lapply reverseing' by-variable'

时间:2018-02-18 18:33:07

标签: r dataframe lapply

我一次添加一行数据帧的总和,条件是另一列具有二进制变量。

因此,对于每一行,我计算相应行中二进制变量具有相同值的所有行的上面整列的总和。

我想颠倒这一点,以便每一行都有"错误" 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,但这只会改变每个组的标签。有没有一种简单的方法来改变它?

1 个答案:

答案 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)