R语言条件性行操作与按ID汇总生成标记的实现方法
数据处理需求落地实现
输入示例数据
# 简化版测试数据帧 obj <- data.frame ( id = c(1, 1, 2, 2, 3, 3, 4, 4), yr = c(1990, 1991, 1990, 1991, 1990, 1991, 1990, 1991), degree = c(1, 1, 1, 2, 1, 1, 0, 0) )
实际业务使用场景中,真实ID为类似
2.01811e+13格式的长数值取值,处理时需注意避免数值精度丢失问题。
处理规则
最终需要生成每个id仅保留1条记录的新数据帧,为每个id生成取值为1或0的标记值value,判定逻辑如下:
- 同id下的degree观测值从1变化为2,对应
value取值为1 - 同id下的degree观测值始终保持为1,对应
value取值为0 - 同id下的degree观测值为(0,0)、(2,2)这类不满足上述两类规则的情况,该id不纳入最终输出
期望输出效果
- id=1 对应 value=0
- id=2 对应 value=1
- id=3 对应 value=0
- id=4 因degree为(0,0),不纳入输出
可直接运行的实现方案
方案1:dplyr 分组处理(逻辑清晰,适配复杂数据规模)
library(dplyr) final_result <- obj %>% # 按id分组时,自动对每个组内的记录按年份升序排序,避免观测顺序错乱导致判断错误 arrange(yr, .by_group = TRUE) %>% group_by(id) %>% summarise( # 逐组匹配规则生成标记值 value = case_when( identical(degree, c(1, 2)) ~ 1, identical(degree, c(1, 1)) ~ 0, TRUE ~ NA_real_ ), .groups = "drop" ) %>% # 剔除所有不符合规则的无效id filter(!is.na(value))
注意:面对长ID类的数值(如2.01811e+13),可提前将id字段转为字符型存储,避免浮点精度丢失导致分组错乱,上述分组逻辑无需改动即可正常运行。
方案2:Base R 原生实现(无需依赖第三方包)
# 按id拆分原始数据为子数据集列表 split_data <- split(obj, f = obj$id) # 遍历每个id的子数据集,匹配规则生成有效结果 res_list <- lapply(names(split_data), function(single_id) { # 按年份升序整理当前id下的degree取值顺序 cur_degree <- split_data[[single_id]]$degree[order(split_data[[single_id]]$yr)] # 规则判断 if (identical(cur_degree, c(1, 2))) { return(data.frame(id = as.numeric(single_id), value = 1)) } else if (identical(cur_degree, c(1, 1))) { return(data.frame(id = as.numeric(single_id), value = 0)) } else { # 不符合规则的id返回空值,后续直接剔除 return(NULL) } }) # 合并所有有效结果 final_result <- do.call(rbind, res_list)
内容的提问来源于stack exchange,提问作者freddywit
相关产品推荐
相关产品推荐

