我有以下类型的数据:
library(tidyverse)
library(lubridate)
data <- tibble(a = c(1, 1, 2, 3, 3),
b = c('x', 'y', 'z', 'z', 'z'),
c = c('ps', 'ps', 'qs', 'rs', 'rs'),
d = c(100, 200, 300, 400, 500),
strt = ymd(c('2019-03-20', '2020-01-01', '2018-01-02', '2020-05-01', '2016-01-01')),
fnsh = ymd(c(NA, NA, NA, '2020-06-01', '2016-05-01')))
该操作必须应用于按a,b,c(即data %>% group_by(a, b, c)
)分组的数据。我想添加一列,以显示某个组在最近一年内是否开始。要在最近一年内开始,一个小组必须:
1)在最近一年内有strt行
2)在最近的一年之前没有strt的行,并且fnsh作为NA(没有取消资格的重叠)
3)在最近的年份和fnsh之前没有strt的行等于或晚于strt中所有条目的最新(没有取消资格的重叠)
因此,我试图获得:
tibble(a = c(1, 1, 2, 3, 3),
b = c('x', 'y', 'z', 'z', 'z'),
c = c('ps', 'ps', 'qs', 'rs', 'rs'),
d = c(100, 200, 300, 400, 500),
strt = ymd(c('2019-03-20', '2020-01-01', '2018-01-02', '2020-05-01', '2016-01-01')),
fnsh = ymd(c(NA, NA, NA, '2020-06-01', '2016-05-01')),
startLatestYear = c(0, 1, 0, 1, 1))
我当前的方法是:
test <- data %>%
group_by(a, b, c) %>%
mutate(startLatestYear = case_when(all(is.na(fnsh)) &
min(strt) > today(tzone = 'CET') - years(1) &
min(strt) <= today(tzone = 'CET') ~ 1,
strt > today(tzone = 'CET') - years(1) &
strt <= today(tzone = 'CET') &
nrow(filter(., strt < today(tzone = 'CET') - years(1) &
fnsh %in% NA)) == 0 &
nrow(filter(., strt < today(tzone = 'CET') - years(1))) > 0 &
strt > max(pull(filter(., strt < today(tzone = 'CET') - years(1)), fnsh)) ~ 1,
TRUE ~ 0))
我在使用if
时使用的第一个case_when()
似乎有效,但是第二个无效。我怀疑我对.
的使用是错误的。如何获得所需的输出?
.
是magrittr软件包提供的工具,它表示%>%
运算符的左侧。 %>%
对dplyr动词一无所知,因此,当您在.
中使用mutate
时,它只会扩展到通过管道传递的对象。对于成组的df,这意味着entire df ,而不是分组的子集。
到目前为止,我发现的最佳解决方案是将mutate
替换为group_modify
:
data %>%
group_by(a, b, c) %>%
group_modify(function(.x, .y)
{
.x %>% mutate(startLatestYear=case_when(...))
})
这是有效的,因为现在group_modify
内部的管道针对每个组分别执行。