r语言 - 在包含多个元素的数据表中执行逐行操作



我有以下数据表:

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

最新更新