如何用R语言if/else if/else及data.table创建多条件汇总列
基于多条件为data.table创建汇总列的解决方案
需求规则
- 4个Condition全为1时,赋值5
- 3个Condition为1时,赋值4
- Condition3和Condition4均为1时,赋值3
- 仅Condition1为1时,赋值2
- 仅Condition3为1时,赋值1
- 无符合条件时,赋值0
测试数据集
dt <- data.table(ID=c(1,2,3,4,5,6), Condition1=c(1,0,1,1,0,0), Condition2=c(0,0,0,1,0,0), Condition3=c(0,1,1,1,0,1), Condition4=c(0,1,1,1,0,0)) str(dt) # 输出: # $ ID : num 1 2 3 4 5 6 # $ Condition1: num 1 0 1 1 0 0 # $ Condition2: num 0 0 0 1 0 0 # $ Condition3: num 0 1 1 1 0 1 # $ Condition4: num 0 1 1 1 0 0
期望结果
str(dt) # 输出: # $ ID : num 1 2 3 4 5 6 # $ Condition1: num 1 0 1 1 0 0 # $ Condition2: num 0 0 0 1 0 0 # $ Condition3: num 0 1 1 1 0 1 # $ Condition4: num 0 1 1 1 0 0 # $ Summary : num 2 3 4 5 0 1
错误代码分析
你尝试的if/else if/else代码存在两个核心问题:
- 普通
if/else是标量判断,无法处理data.table的向量列,会导致只返回一个值而非每行对应的值; - 代码中存在拼写错误:
Condition32应为Condition2。
dt$Summary <- if(c(dt$Condition1 == 1 & dt$Condition2 == 1 & dt$Condition3 == 1 & dt$Condition4 == 1)){ print("5") } else if (c(dt$Condition1 == 1 & dt$Condition32 == 1 & dt$Condition4 == 1)){ print("4") } else if (c(dt$Condition3 == 1 & dt$Condition4 == 1)){ print("3") } else if (dt$Condition1==1){ print("2") } else if (dt$Condition3==1){ print("1") } else { "0" }
正确的data.table解决方案
方法1:使用data.table原生:=结合嵌套fifelse
fifelse是data.table提供的向量版ifelse,支持逐行判断:
dt[, Summary := fifelse(Condition1 == 1 & Condition2 == 1 & Condition3 == 1 & Condition4 == 1, 5, fifelse(rowSums(.SD) == 3, 4, fifelse(Condition3 == 1 & Condition4 == 1, 3, fifelse(Condition1 == 1 & Condition2 == 0 & Condition3 == 0 & Condition4 == 0, 2, fifelse(Condition3 == 1 & Condition1 == 0 & Condition2 == 0 & Condition4 == 0, 1, 0))))), .SDcols = Condition1:Condition4]
方法2:结合dplyr::case_when(兼容data.table)
如果熟悉case_when的语法,可用于简化多条件逻辑,直接嵌入data.table的赋值操作:
library(dplyr) dt[, Summary := case_when( Condition1 == 1 & Condition2 == 1 & Condition3 == 1 & Condition4 == 1 ~ 5, rowSums(.SD) == 3 ~ 4, Condition3 == 1 & Condition4 == 1 ~ 3, Condition1 == 1 & Condition2 == 0 & Condition3 == 0 & Condition4 == 0 ~ 2, Condition3 == 1 & Condition1 == 0 & Condition2 == 0 & Condition4 == 0 ~ 1, TRUE ~ 0 ), .SDcols = Condition1:Condition4]
关键注意点
- 规则判断有优先级:比如"3个Condition为1"的逻辑要放在"Condition3和Condition4均为1"之前,避免被后者覆盖;
- 对于"仅某一个Condition为1"的情况,必须明确其他条件为0,防止和多条件场景冲突;
.SDcols = Condition1:Condition4用于指定计算行和的列范围,适合列数较多的复杂数据集。
内容的提问来源于stack exchange,提问作者Svenja
相关产品推荐
相关产品推荐

