我正在计算每个组的矩阵列的总和,其中相应的组值也包含在矩阵列中。目前我正在使用循环如下:
index <- matrix(c("A","A","B","B","B","B","A","A"),4,2)
x <- matrix(1:8,4,2)
for (i in 1:2) {
tapply(x[,i], index[,i], sum)
}
在一天结束时,我需要以下结果:
1 2
A 3 15
B 7 11
有没有办法在没有循环的情况下使用矩阵运算?最重要的是,实际数据很大(例如500 x 10000),因此它必须很快。
提前致谢。
答案 0 :(得分:5)
以下是几个解决方案:
# 1
ag <- aggregate(c(x), data.frame(index = c(index), col = c(col(x))), sum)
xt <- xtabs(x ~., ag)
# 2
m <- mapply(rowsum, as.data.frame(x), as.data.frame(index))
dimnames(m) <- list(levels(factor(index)), 1:ncol(index))
仅当index
的每一列至少有一个级别并且还要求至少有两个级别时,第二个才有效;然而,它更快。
答案 1 :(得分:1)
这很丑陋而且有效,但有更好的方法可以做到更具普遍性。只是让球滚动。
data.frame("col1"=as.numeric(table(rep(index[,1], x[,1]))),
"col2"=as.numeric(table(rep(index[,2], x[,2]))),
row.names=names(table(index)))
答案 2 :(得分:1)
我仍然怀疑有更好的选择,但实际上这似乎相当快:
index <- matrix(sample(LETTERS[1:4],size = 500*1000,replace = TRUE),500,10000)
x <- matrix(sample(1:10,500*10000,replace = TRUE),500,10000)
rs <- matrix(NA,4,10000)
rownames(rs) <- LETTERS[1:4]
for (i in LETTERS[1:4]){
tmp <- x
tmp[index != i] <- 0
rs[i,] <- colSums(tmp)
}
它在我的机器上运行~0.8秒。我将类别数量增加到四个,并将其扩展到您拥有的大小数据。但我不必每次都复制x
。
你可以通过矩阵乘法变得聪明,但我认为你仍然必须一次做一行或一列。