使用dplyr实现R分组内skipped列按位置赋值(1前0、1后2)
基于dplyr的分组规则赋值实现方案
注意:示例构造的
test_df中,分组列的实际列名为plant_sp,非描述中提到的plant_id,代码已适配实际列名。
核心赋值逻辑
每个分组完全以首个skipped取值为1的行为分界匹配规则:
- 分界行本身保留原值1
- 分界行之前的所有行,skipped值保持原有状态(示例中为0)
- 分界行之后的所有行,skipped值统一设置为2
- 若某分组内从未出现skipped=1的取值,全组skipped值保留原状,不会被误修改
完整可运行代码
library(dplyr) test_df <- structure(list(plant_id = c("plant_1", "plant_1", "plant_1", "plant_1", "plant_1", "plant_2", "plant_2", "plant_2", "plant_2", "plant_2", "plant_3", "plant_3", "plant_3", "plant_3", "plant_3", "plant_4", "plant_4", "plant_4", "plant_4", "plant_4"), skipped = c(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0,0)), row.names = c(NA, -20L), class = "data.frame", .Names = c("plant_sp", "skipped")) result_df <- test_df %>% # 按实际分组列拆分数据块 group_by(plant_sp) %>% mutate( # 定位组内第一个skipped=1的行序号,无匹配则返回NA first_1_pos = which(skipped == 1)[1], skipped = case_when( # 组内无1的场景:保留原skipped值 is.na(first_1_pos) ~ skipped, # 行在首个1之前:保留原skipped值 row_number() < first_1_pos ~ skipped, # 行恰好是首个1的位置:保留原skipped值 row_number() == first_1_pos ~ skipped, # 行在首个1之后:统一赋值为2 row_number() > first_1_pos ~ 2 ) ) %>% # 撤销分组状态 ungroup() %>% # 移除临时生成的定位辅助列 select(-first_1_pos) # 查看转换后的数据 result_df
转换结果校验
代码运行后输出的各组skipped序列完全匹配要求:
- plant_1组序列:
0,0,0,1,2 - plant_2组序列:
0,0,1,2,2 - plant_3组序列:
0,0,1,2,2 - plant_4组序列:
0,0,1,2,2
内容的提问来源于stack exchange,提问作者Ido
相关产品推荐
相关产品推荐

