使用dplyr按MedID分组添加Flag2列的条件赋值问题
解决方法:用
cumany()标记分组内首次出现99后的所有行 看起来你遇到的问题是在分组内正确标记Flag == 99之后的后续行,对吧?我来帮你修正代码,确保不管99出现在分组的哪个位置都能正确生成Flag2。
核心思路
在每个MedID分组内,我们需要:
- 识别出首次出现
Flag == 99的位置 - 将该位置之后的所有行标记为1,其余行标记为0
dplyr里的cumany()函数正好能帮我们实现这个逻辑——它会返回一个逻辑向量,从第一个TRUE开始,之后的所有元素都会保持TRUE。结合lag()可以精准控制“之后的后续行”(不包含99所在行),如果需要包含99所在行,直接去掉lag()即可。
正确代码
library(dplyr) # 生成df2,添加Flag2列 df2 <- df1 %>% group_by(MedID) %>% mutate( # 方案1:Flag ==99 之后的后续行设为1(不包含99所在行) Flag2 = as.integer(lag(cumany(Flag == 99), default = FALSE)), # 如果你需要把99所在行也设为1,用下面这行代替上面的 # Flag2 = as.integer(cumany(Flag == 99)) ) %>% ungroup()
测试验证
我们用不同的场景测试一下:
场景1:99出现在分组第一行
test_df1 <- tibble( MedID = rep(1, 4), Flag = c(99, 0, 5, 3) ) test_df1 %>% group_by(MedID) %>% mutate(Flag2 = as.integer(lag(cumany(Flag == 99), default = FALSE))) %>% ungroup()
结果:
| MedID | Flag | Flag2 |
|---|---|---|
| 1 | 99 | 0 |
| 1 | 0 | 1 |
| 1 | 5 | 1 |
| 1 | 3 | 1 |
场景2:99出现在分组中间
test_df2 <- tibble( MedID = rep(2, 5), Flag = c(0, 1, 99, 2, 4) ) test_df2 %>% group_by(MedID) %>% mutate(Flag2 = as.integer(lag(cumany(Flag == 99), default = FALSE))) %>% ungroup()
结果:
| MedID | Flag | Flag2 |
|---|---|---|
| 2 | 0 | 0 |
| 2 | 1 | 0 |
| 2 | 99 | 0 |
| 2 | 2 | 1 |
| 2 | 4 | 1 |
场景3:分组内没有99
test_df3 <- tibble( MedID = rep(3, 3), Flag = c(0, 1, 2) ) test_df3 %>% group_by(MedID) %>% mutate(Flag2 = as.integer(lag(cumany(Flag == 99), default = FALSE))) %>% ungroup()
结果:所有Flag2都是0,符合预期。
为什么你的原代码会出错?
如果你的代码在99不在第一行时全生成1,大概率是逻辑判断没有限制在分组内的首次出现,或者误用了cumsum()(比如cumsum(Flag ==99) >0会在出现99后一直返回TRUE,但如果没正确分组就会全局生效)。而cumany()是在分组内逐行判断,能精准控制从首次出现99开始的后续行。
内容的提问来源于stack exchange,提问作者user3885754
相关产品推荐
相关产品推荐

