在 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
中的管道针对每个组单独执行。
我有以下类型的数据:
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
中的管道针对每个组单独执行。