基于分组计数与条件判断为data.table添加新列
解决方法:用data.table实现New_Var列的计算
我来帮你搞定这个data.table的问题!你的思路方向是对的,只是在分组求和的环节没选对筛选逻辑,咱们一步步来搞定:
第一步:确保数据是data.table格式
先把你的数据转换成data.table类型(如果还没转的话):
library(data.table) DT <- setDT(DT)
第二步:分组计算并赋值New_Var
我们可以在一次分组操作里完成所有逻辑,不需要额外冗余的中间列(如果想保留中间计算结果也可以调整):
DT[, New_Var := { # 先在当前家庭组内计算两个关键总和 total_main0 <- sum(Variable[Main == 0]) total_main1 <- sum(Variable[Main == 1]) # 根据家庭人数和当前行的Main值返回对应结果 if (.N == 1) { 0 } else { ifelse(Main == 1, total_main0, total_main1) } }, by = Household]
代码细节解释:
.N是data.table的特殊内置变量,代表当前分组(这里是Household)的行数,也就是该家庭的成员数量sum(Variable[Main == 0])会在每个家庭组内,仅对Main==0的行的Variable值求和,精准筛选了你需要的子集- 逻辑判断部分:如果家庭只有1个成员,直接返回0;否则根据当前行的
Main标记,返回对应的另一组总和
可选:保留中间计算过程的写法
如果你想直观看到每个家庭的Main==0和Main==1的总和,可以先计算这些中间列,再赋值New_Var,最后按需删除中间列:
# 先分组计算总和和家庭人数 DT[, `:=`( sum_main0 = sum(Variable[Main == 0]), sum_main1 = sum(Variable[Main == 1]), household_size = .N ), by = Household] # 赋值New_Var DT[, New_Var := ifelse(household_size == 1, 0, ifelse(Main == 1, sum_main0, sum_main1))] # 移除不需要的中间列 DT[, c("sum_main0", "sum_main1", "household_size") := NULL]
验证结果正确性
运行完代码后,你可以用下面的代码验证结果是否和你给出的DTnew一致(考虑浮点数精度差异,添加tolerance参数):
all.equal(DT, DTnew, tolerance = 1e-6) # 返回TRUE即说明结果完全匹配
你之前代码的问题说明
你尝试的sum(Variable, by=Household)写法是错误的:sum()函数本身不支持by参数,且你没有针对Main的取值做筛选。正确的做法是在分组内,对符合Main条件的Variable子集求和,也就是sum(Variable[Main == 0])这类精准筛选的写法。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

