汇总矩阵之间的某些行

时间:2014-03-08 10:56:30

标签: r list matrix aggregate

假设我有物种 - 栖息地丰度矩阵及时采样。我试图找到一种简洁的方法来聚合时间重复,创建一个物种丰度矩阵。

# Construct dummy data

mat1<-matrix(c(1,3,0,2,0,0,6,0,10,1), ncol=5, nrow=2)
mat2<-matrix(c(0,11,0,0,1,0,2,3,7,1), ncol=5, nrow=2)
mat3<-matrix(c(2,1,0,0,3,1,1,0,4,0), ncol=5, nrow=2)
colnames(mat1) <-c('sp1','sp2','sp3','sp4','sp5')
rownames(mat1) <- c('h1','h2')
colnames(mat2) <-c('sp1','sp2','sp3','sp4','sp5')
rownames(mat2) <- c('h1','h2')
colnames(mat3) <-c('sp1','sp2','sp3','sp4','sp5')
rownames(mat3) <- c('h1','h2')
# Special case when new species occur
mat4 <- matrix(c(2,1,0,0,3,1,1,0,4,0,6,3), ncol=6, nrow=2)
colnames(mat4) <-c('sp1','sp2','sp3','sp4','sp5','sp6')
rownames(mat4) <- c('h1','h2')

# Replicate matrices are within a list
l.mat<-list(mat1,mat2,mat3,mat4)

我的第一个想法是使用apply(margin=2)(但是又一次,问题在列表中,lapply?)和colSums但是我找不到总结的方法每个矩阵中的行(栖息地),而不是如下所示。此外,当一个新物种出现时,它应该出现在聚合矩阵中

# Desired output

# Aggregated matrix
   sp1 sp2 sp3 sp4 sp5 sp6
h1   5   0   7  10  25  6
h2  16   2   2   3   2  3

非常感谢任何指示,谢谢!

2 个答案:

答案 0 :(得分:3)

如果您使用“reshape2”软件包,这是非常直接的做法:

library(reshape2)
allMat <- do.call(rbind, lapply(l.mat, melt))
dcast(allMat, X1 ~ X2, fun.aggregate=sum)
#   X1 sp1 sp2 sp3 sp4 sp5 sp6
# 1 h1   5   0   7  10  25   6
# 2 h2  16   2   2   3   2   3

或者,现在我想到了它(因为melt的方法是list,你可以这样做:

dcast(melt(l.mat), X1 ~ X2, value.var="value", fun.aggregate=sum)

如果你想坚持使用基础R,我没有发现任何直接的东西。以下是我提出的两种方法,与上述方法相同:

基本选项1

allMat <- do.call(rbind, lapply(l.mat, function(x) 
  cbind(id = rownames(x), stack(data.frame(x)))))
xtabs(values ~ id + ind, data = allMat)
#     ind
# id   sp1 sp2 sp3 sp4 sp5 sp6
#   h1   5   0   7  10  25   6
#   h2  16   2   2   3   2   3

基本选项2

allMat <- do.call(rbind, lapply(l.mat, function(x) {
  cbind(expand.grid(dimnames(x)), value = as.vector(x))
}))
allMat
xtabs(value ~ Var1 + Var2, allMat)
#     Var2
# Var1 sp1 sp2 sp3 sp4 sp5 sp6
#   h1   5   0   7  10  25   6
#   h2  16   2   2   3   2   3

答案 1 :(得分:0)

library(reshape2)
library(dplyr)
df = rbind(melt(mat1),melt(mat2),melt(mat3),melt(mat4))
sdf = df %.% group_by(Var1,Var2)%.%summarize(value=sum(value))
dcast(sdf, Var1~Var2)

会产生

  Var1 sp1 sp2 sp3 sp4 sp5 sp6
1   h1   5   0   7  10  25   6
2   h2  16   2   2   3   2   3