我有以下数据表:
library(data.table)
set.seed(1)
DT <- data.table(ind=1:100,x=sample(100),y=sample(100),group=c(rep("A",50),rep("B",50)))
现在的问题是,我需要取列"x"中的每个值(即每个给定的ID),并将所有现有值添加到列&;y&;到它。我还需要单独做每列"组"。假设我们从ID = 1开始。这个元素的值是:x_1 = 68, y_1 = 76。我们还看到y_2 = 39 y_3 = 24,等等。我要计算的是x_1 + y_1, x_1 + y2, x_1 + y_3,等等的和。不仅是x_1,还有x_2, x_3,等等。对于x_2,它是这样的:x_2 + y_1, x_2 + y_2, x_2 + y_3,等等。这也应该在每一栏"组"(在这方面,数据集应该简单地按组划分)。
编辑:仅对X_1和组A执行此操作的示例代码:current_X <- DT[1,x] # not needed, just to illustrate
vector_current_X <- rep(DT[1,x],nrow(DT[group == "A"]))
DT[group == "A",copy_current_X := vector_current_X]
DT[,sum_current_X_Y := copy_current_X + y]
DT
这种方法的一个明显问题是,如果它应用于所有的x,那么很多列将被添加到最终的DT中。所以我不确定这是否是最好的方法。最后,我只是在寻找(每个元素x)与每个元素y和每个组的最小和。
我知道如何对每组进行操作,我也知道lapply函数。问题是,从我的理解,我需要包括一个逐行循环。接下来,结果的结构将与原始数据表不同,因为我们有许多额外的观测值。我以前看到过可以在数据中保存列表。但我不确定这是否是最好的办法。我的数据集更大,所以效率很重要。
谢谢你给我的提示。
你可以这样做:
DT[, .(.BY$x+DT[group==.BY$group,y]), by=.(x,group)]
每个x返回N行,其中N是x所在组的大小。我们利用特殊的(.BY
),当利用by
时,j
中可用。基本上,.BY
是一个命名列表,包含分组变量的值。在这里,我将x的值(.BY$x
)添加到DT
子集的y
值向量中,其中group
等于当前组值(.BY$group
)
输出:
x group V1
<int> <char> <int>
1: 68 A 144
2: 68 A 107
3: 68 A 92
4: 68 A 121
5: 68 A 160
---
4996: 4 B 25
4997: 4 B 66
4998: 4 B 83
4999: 4 B 27
5000: 4 B 68
也可以通过join来实现:
DT[,!c("y")][DT[, .(y,group)], on=.(group), allow.cartesian=T][, total:=x+y][order(ind)]
输出:
ind x group y total
<int> <int> <char> <int> <int>
1: 1 68 A 76 144
2: 1 68 A 39 107
3: 1 68 A 24 92
4: 1 68 A 53 121
5: 1 68 A 92 160
---
4996: 100 4 B 21 25
4997: 100 4 B 62 66
4998: 100 4 B 79 83
4999: 100 4 B 23 27
5000: 100 4 B 64 68
如果我理解正确的话,请求的结果需要一个交叉连接,其中x
的每个元素与y
的每个元素相结合(在每个group
中)。
这可以使用CJ()
函数轻松完成:
DT[, CJ(x, y, sorted = FALSE), by = group][, sum_x_y := x + y][]
group x y sum_x_y 1: A 68 76 144 2: A 68 39 107 3: A 68 24 92 4: A 68 53 121 5: A 68 92 160 --- 4996: B 4 21 25 4997: B 4 62 66 4998: B 4 79 83 4999: B 4 23 27 5000: B 4 64 68