如何按ID分组比较DataFrame日期,跨行取值生成结果列
解决按ID分组判断是否存在date_2早于date_1的问题
你的核心问题在于原代码是逐行比较日期,但每行的date_1或date_2总有一个是NA,导致比较结果全为NA;而需求是跨行检查整个ID组内的所有有效日期组合——只要存在任意一个date_2早于任意一个date_1,就给该组所有行标记"yes",否则标记"no"。
解决步骤与代码
- 先将字符型的日期列转换为
Date类型,确保日期比较的正确性; - 按
id分组后,提取组内所有非NA的date_1和date_2; - 用
any()函数判断是否存在符合条件的日期组合,将结果赋值给组内每一行。
完整代码如下:
library(dplyr) # 原始数据 id <- c("N03", "N03", "N03", "N07", "N07", "N16", "N16", "N17", "N17") date_1 <- c("2008-05-13", "2010-12-14", NA, NA, "2009-06-09", NA, "2011-05-03", "2018-05-03", NA) date_2 <- c(NA, NA, "2011-12-19", "2008-06-13", NA, "2010-10-18", NA, NA, "2018-07-08") df1 <- data.frame(id, date_1, date_2) # 处理日期类型并生成结果列 df2 <- df1 %>% # 将字符型日期转为Date类型 mutate(across(c(date_1, date_2), as.Date)) %>% group_by(id) %>% mutate( # 提取组内所有非NA的date_1和date_2 valid_d1 = na.omit(date_1), valid_d2 = na.omit(date_2), # 判断是否存在任意date_2 < date_1 date_2_before_date_1 = ifelse(any(valid_d2 < valid_d1), "yes", "no") ) %>% # 删除临时生成的有效日期列 select(-valid_d1, -valid_d2) %>% ungroup() # 查看结果 print(df2)
结果验证
运行后会得到你期望的输出:
# A tibble: 9 × 4 id date_1 date_2 date_2_before_date_1 <chr> <date> <date> <chr> 1 N03 2008-05-13 NA no 2 N03 2010-12-14 NA no 3 N03 NA 2011-12-19 no 4 N07 NA 2008-06-13 yes 5 N07 2009-06-09 NA yes 6 N16 NA 2010-10-18 yes 7 N16 2011-05-03 NA yes 8 N17 2018-05-03 NA no 9 N17 NA 2018-07-08 no
关键逻辑说明
across(c(date_1, date_2), as.Date):统一日期格式,避免字符比较的逻辑错误;na.omit():过滤组内的NA值,确保只拿有效日期做跨组合比较;any(valid_d2 < valid_d1):检查所有有效date_2与date_1的组合,只要有一对满足date_2 < date_1就返回TRUE;- 分组内的
mutate会将结果应用到该组的每一行,实现整组统一标记。
内容的提问来源于stack exchange,提问作者CharlesLDN
相关产品推荐
相关产品推荐

