R-基于分组的矩阵行和列求和
我有一个对称矩阵和一个适用于行和列的特定分组。我试图根据这个特定的分组只对这些行和列求和 例如,我有一个4x4矩阵。我还有一个特定的分组,比如1,1,2,2。也就是说,行和列1和2属于组1,而行和列3和列4属于组2。我想将函数rowSums或rowSums应用于组约束: 我的矩阵:R-基于分组的矩阵行和列求和,r,matrix,sum,row,grouping,R,Matrix,Sum,Row,Grouping,我有一个对称矩阵和一个适用于行和列的特定分组。我试图根据这个特定的分组只对这些行和列求和 例如,我有一个4x4矩阵。我还有一个特定的分组,比如1,1,2,2。也就是说,行和列1和2属于组1,而行和列3和列4属于组2。我想将函数rowSums或rowSums应用于组约束: 我的矩阵: [,1] [,2] [,3] [,4] [1,] 0 1 0 0 [2,] 1 0 1 0 [3,] 0 1 0 3
[,1] [,2] [,3] [,4]
[1,] 0 1 0 0
[2,] 1 0 1 0
[3,] 0 1 0 3
[4,] 3 0 0 0
直观地说,为了帮助回答我的问题,分组1,1,2,2基本上意味着:
[,1] [,2] [,3] [,4]
[1,] 0 1 NA NA
[2,] 1 0 NA NA
[3,] NA NA 0 3
[4,] NA NA 0 0
将行和应用于原始矩阵将产生:
[1] 1 2 4 3
此外,应用rowsum(允许传递组)仅将分组应用于行,并且仍然对不属于组的列求和:
[,1] [,2] [,3] [,4]
1 1 1 1 0
2 3 1 0 3
这是一个问题的原因,因为我试图在每个组中找到最小值。由于上述列不属于该组,因此结果将不正确。我可以无聊地循环分组并应用行和来获得每组的和,然后找到最小值:
rowSums(mat[c(1,2),c(1,2)])
[1] 1 1 <- minimum is 1
rowSums(mat[c(3,4),c(3,4)])
[1] 3 0 <- minimum is 0
如有任何建议,将不胜感激
谢谢
编辑:
我将我的问题调整为以下内容。鉴于我的原始矩阵:
[,1] [,2] [,3] [,4]
[1,] 0 1 0 0
[2,] 1 0 1 0
[3,] 0 1 0 3
[4,] 3 0 0 0
以及一个特定的分组:
groups<-c(1,1,2,2)
组也许这有帮助
sapply(split(mat, kronecker(matrix(1:4, nrow=2, byrow=TRUE),
matrix(1, 2, 2))), function(x) rowSums(matrix(x, ncol=2)))
# 1 2 3 4
#[1,] 1 0 1 3
#[2,] 1 1 3 0
解释
两个数组的kronecker
乘积返回如上所示的分组索引。用它来分割矩阵
split(mat, kronecker(matrix(1:4, nrow=2, byrow=TRUE),
matrix(1, 2, 2)))
#$`1`
#[1] 0 1 1 0
#$`2`
#[1] 0 1 0 0
#$`3`
#[1] 0 3 1 0
#$`4`
#[1] 0 0 3 0
它返回向量的列表
将向量
转换为矩阵
,通过sapply
在列表
上循环,得到行和
,1 13 0
中的3
如果你取的是最小值,我相信他想要mat[1:2,1:2]和mat[3:4]的最大行数。分组c(1,1,2,2)同时适用于行和列。在该步骤中,我只想显示每个组的行和(在搜索每个组的最小值之前)。根据ouptut,这并不清楚。正如您提到的行和
,我发布了一个解决方案below@akrun你可以把它想象成:[1,]1[2,]1[3,]3[4,]0谢谢。你的回答让我开始考虑在我的矩阵上使用sapply。我已经编辑了上面的问题以重定向所需的输出。请看一看。谢谢
groups<-c(1,1,2,2)
for(i in 1:length(groups))
{
mat[i,which(groups[i]!=groups)]<-NA
}
mat
[,1] [,2] [,3] [,4]
[1,] 0 1 NA NA
[2,] 1 0 NA NA
[3,] NA NA 0 3
[4,] NA NA 0 0
sapply(split(mat, kronecker(matrix(1:4, nrow=2, byrow=TRUE),
matrix(1, 2, 2))), function(x) rowSums(matrix(x, ncol=2)))
# 1 2 3 4
#[1,] 1 0 1 3
#[2,] 1 1 3 0
kronecker(matrix(1:4, nrow=2, byrow=TRUE), matrix(1, 2, 2))
# [,1] [,2] [,3] [,4]
#[1,] 1 1 2 2
#[2,] 1 1 2 2
#[3,] 3 3 4 4
#[4,] 3 3 4 4
split(mat, kronecker(matrix(1:4, nrow=2, byrow=TRUE),
matrix(1, 2, 2)))
#$`1`
#[1] 0 1 1 0
#$`2`
#[1] 0 1 0 0
#$`3`
#[1] 0 3 1 0
#$`4`
#[1] 0 0 3 0