在 case_when() 中使用 (.) 作为分组 tibble 上 mutate() 的一部分

Using (.) in case_when() as part of mutate() on grouped tibble

我有以下类型的数据:

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) 在最近的一年之前没有包含 strt 的行,并且 fnsh 等于或晚于 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))

我使用的 case_when() 中的第一个 if 似乎有效,但第二个无效。我怀疑我对 . 的使用是错误的。如何获得所需的输出?

. 是 magrittr 包提供的工具,它指的是 %>% 运算符的左侧。 %>% 对 dplyr 动词一无所知,因此当您在 mutate 中使用 . 时,它只是扩展为通过管道输入的对象。在分组 df 的情况下,这意味着整个 df,不是分组的子集。

到目前为止我找到的最佳解决方案是将 mutate 替换为 group_modify:

data %>%
    group_by(a, b, c) %>%
    group_modify(function(.x, .y)
    {
        .x %>% mutate(startLatestYear=case_when(...))
    })

这是可行的,因为现在 group_modify 中的管道针对每个组单独执行。