我一次添加一行数据帧的总和,条件是另一列具有二进制变量。
因此,对于每一行,我计算相应行中二进制变量具有相同值的所有行的上面整列的总和。
我想颠倒这一点,以便每一行都有"错误" group,这是不正确的虚拟值的值(作为健壮性测试的一部分):
以下是一个例子:
dummy var1 var2
1 x1 y1
0 x2 y2
0 x3 y3
1 x4 y4
目前我获得了这个:
dummy var1 var2
1 x1 y1
0 x2 y2
0 x3+x2 y3+y2
1 x4+x1 y4+y1
我想得到错误的值,即(第一行为N / A,因为该行或更高版本中的dummy = 0没有值):
dummy var1 var2
1 N/A N/A
0 x1 y1
0 x1 y1
1 x3+x2 y3+y2
到目前为止,我是如何做到这一点的(我在这个论坛Adding columns sums in dataframe row wise conditional on a dummy中问了这个问题),以及"正确的"版本:
setDT(df1)
cols = c("var1", "var2", "var3", ...)
df1[, (cols) := lapply(.SD, cummean) , by = dummy, .SD = cols]
我在考虑使用:-dummy而不是dummy,但这只会改变每个组的标签。有没有一种简单的方法来改变它?
答案 0 :(得分:1)
您可以获取变量的累积总和(忽略虚拟ID)与目前为止的结果之间的差异。
setDT(df1)
cols <- paste0("var", 1:3)
#cumulative sum of each column
df1[, (paste0("cumsum_", cols)) := lapply(.SD, cumsum), .SD=cols]
#your cumulative sum by ID
df1[, (paste0("sumById_", cols)) := lapply(.SD, cumsum), by=dummy, .SD=cols]
#the reverse version, the solution is to think of using subtracting the original cumulative sum by id from the cumulative sum of everything.
rcsCols <- paste0("reverseCumSum_", cols)
df1[, (rcsCols) := lapply(cols,
function(x) get(paste0("cumsum_", x)) - get(paste0("sumById_", x)))]
#then set NA before the first change in dummy
df1[, (rcsCols) := lapply(.SD, function(x) {
x[seq_along(rle(dummy)$lengths[1])] <- NA
x
}), .SDcols=rcsCols]
df1
# dummy var1 var2 var3 cumsum_var1 cumsum_var2 cumsum_var3 sumById_var1 sumById_var2 sumById_var3 reverseCumSum_var1 reverseCumSum_var2 reverseCumSum_var3
#1: 1 1 5 10 1 5 10 1 5 10 NA NA NA
#2: 0 2 6 11 3 11 21 2 6 11 1 5 10
#3: 0 3 7 12 6 18 33 5 13 23 1 5 10
#4: 1 4 8 13 10 26 46 5 13 23 5 13 23
数据:
df1 <- data.table(dummy=c(1,0,0,1),
var1=1:4,
var2=5:8,
var3=10:13)