对按列名分组但将所有列保留在 R 中的行值求和?

Sum row-wise values that are grouped by column name but keep all columns in R?

提问人:Electrino 提问时间:8/26/2022 最后编辑:ThomasIsCodingElectrino 更新时间:8/26/2022 访问量:146

问:

这里这里都问过类似的问题,但是,我的问题与这些问题略有不同。在其他问题中,在按组求和后,他们将删除“重复”列。我想保留重复的列。例如,如果我有一个矩阵,如下所示:

myMat <- matrix(NA, 3, 4)
colnames(myMat) <- c('x', 'y', 'x', 'y')
myMat[1,] <- c(1,2,0,1)
myMat[2,] <- c(2,4,3,5)
myMat[3,] <- c(3,6,1,7)

> myMat
     x y x y
[1,] 1 2 0 1
[2,] 2 4 3 5
[3,] 3 6 1 7

我想按列名分组的行总和。在上面的链接中,其中一个答案表明了这一点:

> t(rowsum(t(myMat), group = colnames(myMat), na.rm = T))
     x  y
[1,] 1  3
[2,] 5  9
[3,] 4 13

但正如你所看到的,它们将具有相同名称的列组合在一起,从而减少了列的数量。我想对值求和,但仍然具有相同的列。例如,我想要的输出如下所示:

     x  y x  y
[1,] 1  3 1  3
[2,] 5  9 5  9
[3,] 4 13 4 13

在上面,行(按名称分组)相加...但我仍然有每个单独的列。关于我如何做到这一点的任何建议?

R 矩阵 组数据 操作

评论


答:

2赞 Maël 8/26/2022 #1

用途和:aveapply

t(apply(myMat, 1, \(x) ave(x, names(x), FUN = sum)))
     x  y x  y
[1,] 1  3 1  3
[2,] 5  9 5  9
[3,] 4 13 4 13
1赞 Allan Cameron 8/26/2022 #2

一个简单的循环将实现这一点:

for(i in unique(colnames(myMat))) {
  myMat[,colnames(myMat) == i] <- rowSums(myMat[,colnames(myMat) == i])
}

myMat
#>      x  y x  y
#> [1,] 1  3 1  3
#> [2,] 5  9 5  9
#> [3,] 4 13 4 13
2赞 langtang 8/26/2022 #3

您也可以直接获取原始解决方案并将其绑定到自身

sums =  t(rowsum(t(myMat), group = colnames(myMat), na.rm = T))
cbind(sums, sums)

     x  y x  y
[1,] 1  3 1  3
[2,] 5  9 5  9
[3,] 4 13 4 13
1赞 ThomasIsCoding 8/26/2022 #4

您可以尝试如下(借助avecol + row)

> ave(myMat,colnames(myMat)[col(myMat)], row(myMat), FUN = sum)
     x  y x  y
[1,] 1  3 1  3
[2,] 5  9 5  9
[3,] 4 13 4 13

评论

0赞 Maël 8/26/2022
输出应为 4 列