在R语言中按列名分组行求和但保留所有列的实现方法
问题:按列名分组行求和并保留原列结构
此前已有类似问题被提出,但本次需求略有不同:常规的按列名分组行求和会合并同名的列,而我们需要保留原始的所有列,每个列位置填充对应列名分组的行求和结果。
示例输入矩阵
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
解决方案
方法1:基于矩阵索引的快速实现
先计算各列名分组的行求和结果,再根据原列名映射填充到对应位置:
# 计算每个列名对应的行求和值 sum_groups <- t(rowsum(t(myMat), group = colnames(myMat), na.rm = TRUE)) # 根据原列名,将求和结果映射到原矩阵的列结构中 result <- sum_groups[, colnames(myMat)] # 查看最终结果 result
方法2:使用dplyr的行操作实现
如果习惯用 tidyverse 工具,可以将矩阵转为数据框后逐行处理:
library(dplyr) myMat %>% as.data.frame() %>% rowwise() %>% mutate(across(everything(), ~ sum(c_across(all_of(cur_column()))))) %>% as.matrix()
原理:c_across(all_of(cur_column()))会提取当前列名对应的所有列的值,求和后替换当前列,从而保留原有的列结构。
内容的提问来源于stack exchange,提问作者Electrino
相关产品推荐
相关产品推荐

