关注数据和指数的矩阵

时间:2011-10-26 21:40:28

标签: r

我正在计算每个组的矩阵列的总和,其中相应的组值也包含在矩阵列中。目前我正在使用循环如下:

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),因此它必须很快。

提前致谢。

3 个答案:

答案 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

你可以通过矩阵乘法变得聪明,但我认为你仍然必须一次做一行或一列。