Reputation: 3512
Let's say I have species-habitat abundance matrices sampled in time. I am trying to find a neat way to to aggregate over temporal replicates, creating a single species abundances matrix.
# 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)
My first thought was to use apply(margin=2)
(but then again, the matices are within a list, lapply
?) and colSums
but I have not find a way not to sum over rows (habitat) within each matrix, but rather between, as seen below. Also when a new species occur, it should appear in the aggregated matrix
# Desired output
# Aggregated matrix
sp1 sp2 sp3 sp4 sp5 sp6
h1 5 0 7 10 25 6
h2 16 2 2 3 2 3
Any pointers would be very much appreciated, thanks!
Upvotes: 0
Views: 105
Reputation: 193637
This is pretty direct to do if you use the "reshape2" package:
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
Or, now that I think of it (since there's a melt
method for list
s, you can just do:
dcast(melt(l.mat), X1 ~ X2, value.var="value", fun.aggregate=sum)
If you want to stick with base R, I haven't found anything quite as direct. Here are two ways I came up with that's along the same lines as above:
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
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
Upvotes: 3
Reputation: 3184
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)
would produce
Var1 sp1 sp2 sp3 sp4 sp5 sp6
1 h1 5 0 7 10 25 6
2 h2 16 2 2 3 2 3
Upvotes: 0