R语言:为ID分组创建是否出现状态B的0/1指示列
解决方案
方法1:沿用你使用的plyr包
既然你已经在使用ddply,可以直接按ID分组(不需要按Status),判断该分组内是否存在Status == "B",再将逻辑值转为0/1:
library(plyr) # 保留你之前的Count列(如果需要) df <- ddply(df, .(ID, Status), transform, Count = length(ID)) # 添加B_appears列,按ID分组判断是否出现过"B" df <- ddply(df, .(ID), transform, B_appears = as.integer(any(Status == "B")))
逻辑说明:any(Status == "B")检查当前ID分组内是否有至少一行的Status为"B",返回TRUE或FALSE,as.integer()将其转换为1或0。
方法2:用更高效的dplyr包(推荐)
如果可以切换到dplyr,代码更简洁且性能更优:
library(dplyr) df <- df %>% group_by(ID, Status) %>% mutate(Count = n()) %>% # 替代你之前的Count统计逻辑 group_by(ID) %>% mutate(B_appears = as.integer(any(Status == "B"))) %>% ungroup()
方法3:基础R实现(无需额外包)
不想加载第三方包的话,用ave函数就能完成需求:
# 先统计Count列 df$Count <- ave(rep(1, nrow(df)), df$ID, df$Status, FUN = length) # 添加B_appears列 df$B_appears <- as.integer(ave(df$Status == "B", df$ID, FUN = any))
举个示例效果:
假设原始数据为:
| ID | Status |
|---|---|
| 1 | A |
| 1 | B |
| 2 | A |
| 2 | A |
| 3 | B |
运行代码后得到的结果:
| ID | Status | Count | B_appears |
|---|---|---|---|
| 1 | A | 1 | 1 |
| 1 | B | 1 | 1 |
| 2 | A | 2 | 0 |
| 2 | A | 2 | 0 |
| 3 | B | 1 | 1 |
内容的提问来源于stack exchange,提问作者Lda1616
相关产品推荐
相关产品推荐

