根据其他列获取data.table行之间的差异

Cro*_*ops 1 aggregate r data.table

我有一个数据框data如下。如何根据该类获取类c1c2列的值之间的差异v1v3v4有效地使用data.table它们index

data <- data.frame(index = c("A", "B", "C", "D", "C", "A", "D", "B"),
                   class = c(rep("c1", 4), rep("c2", 4)),
                   v1 = c(21,85,74,96,55,77,21,34),
                   v3 = c(77,41,91,85,22,74,36,41),
                   v4 = c(41,58,24,36,84,24,74,11))

setDT(data)
data[, index := as.factor(index)]
data[, class := as.factor(class)]

   index class v1 v3 v4
1:     A    c1 21 77 41
2:     B    c1 85 41 58
3:     C    c1 74 91 24
4:     D    c1 96 85 36
5:     C    c2 55 22 84
6:     A    c2 77 74 24
7:     D    c2 21 36 74
8:     B    c2 34 41 11
Run Code Online (Sandbox Code Playgroud)

所需的输出是

out <- data.frame(index = data[1:4]$index,
           v1 = data[1:4]$v1 - data[5:8]$v1,
           v3 = data[1:4]$v3 - data[5:8]$v3,
           v4= data[1:4]$v4 - data[5:8]$v4)
out
  index  v1 v3  v4
1     A -56  3  17
2     B  51  0  47
3     C  19 69 -60
4     D  75 49 -38
Run Code Online (Sandbox Code Playgroud)

mto*_*oto 5

您可以将diff()每个索引的功能应用于数字列:

data[,lapply(.SD,diff),by=index,.SDcols = v1:v4]
#   index  v1  v3  v4
#1:     A  56  -3 -17
#2:     B -51   0 -47
#3:     C -19 -69  60
#4:     D -75 -49  38
Run Code Online (Sandbox Code Playgroud)

要翻转符号(如预期的输出一样),您可以简单地使用-.SD代替.SD