如何在R中按条件筛选数据并获取最早可行日期对应值?
R语言按ID-name组合筛选值并标记缺失情况的简便实现
原始数据集
df <- data.frame(ID = c(1,1,1,1,1,2,2,2,2,3,4), name = c('a','a','a','b','c','a','a','b','b','c','a'), date = c('01/01/2023','01/02/2023', '01/03/2023','01/01/2023','01/03/2023', '01/01/2023', '01/03/2023', '01/03/2023','01/02/2023', '01/03/2023','01/01/2023'), value = c(1:11), days = c(-2, -1, 0, -2, 0, -2, 0, 0,-1, 0, -2)) df$date <- as.Date(df$date, format = "%m/%d/%Y")
数据集预览:
ID name date value days 1 1 a 2023-01-01 1 -2 2 1 a 2023-01-02 2 -1 3 1 a 2023-01-03 3 0 4 1 b 2023-01-01 4 -2 5 1 c 2023-01-03 5 0 6 2 a 2023-01-01 6 -2 7 2 a 2023-01-03 7 0 8 2 b 2023-01-03 8 0 9 2 b 2023-01-02 9 -1 10 3 c 2023-01-03 10 0 11 4 a 2023-01-01 11 -2
需求说明
- 按
ID+name的唯一组合保留一行数据,选取value的优先级规则:- 优先选择该组合下
days < 0的记录中日期最早的对应value - 若没有
days < 0的记录,则选取days = 0的对应value
- 优先选择该组合下
- 新增
flag列:若该组合无days = 0的记录,标记为"no day 0",否则标记为NA
解决方案(dplyr实现)
用dplyr的分组、排序、切片操作可以高效完成需求,无需拆分合并数据集:
# 安装并加载dplyr(若未安装) # install.packages("dplyr") library(dplyr) result <- df %>% group_by(ID, name) %>% # 标记当前组是否存在days=0的记录 mutate(has_day0 = any(days == 0)) %>% # 排序:先保留days<0的记录(优先级高),同优先级下日期早的在前;再排days=0的记录 arrange(desc(days < 0), date) %>% # 取每组第一条,即符合优先级的记录 slice_head(n = 1) %>% # 生成flag列 mutate(flag = ifelse(!has_day0, "no day 0", NA)) %>% # 移除辅助列 select(-has_day0) %>% ungroup() print(result)
输出结果
# A tibble: 7 × 6 ID name date value days flag <dbl> <chr> <date> <int> <dbl> <chr> 1 1 a 2023-01-01 1 -2 NA 2 1 b 2023-01-01 4 -2 no day 0 3 1 c 2023-01-03 5 0 NA 4 2 a 2023-01-01 6 -2 NA 5 2 b 2023-01-02 9 -1 NA 6 3 c 2023-01-03 10 0 NA 7 4 a 2023-01-01 11 -2 no day 0
大数据集优化方案(data.table实现)
如果数据集规模较大,用data.table处理效率更高:
# 安装并加载data.table(若未安装) # install.packages("data.table") library(data.table) setDT(df) result_dt <- df[, { has_day0 = any(days == 0) # 排序后取第一条记录 top_row = .SD[order(-(days < 0), date)][1] # 添加flag列 top_row[, flag := ifelse(!has_day0, "no day 0", NA)] }, by = .(ID, name)] print(result_dt)
内容的提问来源于stack exchange,提问作者blue_da_ba_dee
相关产品推荐
相关产品推荐

