我正在尝试使用apply-esque做一些看似相对简单的事情,但我只能使用for循环来使用它。
一般的想法是我有两个向量,一个向量对应于矩阵中的一行,另一个向量对应于列,两个长度相同。我从0矩阵开始,并根据两个向量中的值对递增[row,column]。例如:
vectorCols <- c(1,2,3,1,3)
vectorRows <- c(2,1,2,3,2)
countMat <- matrix(rep(0,9),ncol=3)
最后,countMat
是:
[,1] [,2] [,3]
[1,] 0 1 0
[2,] 1 0 2
[3,] 1 0 0
使用for
循环非常容易管理:
for (i in 1:length(vectorCols)){
countMat[vectorRows[i],vectorCols[i]] <- countMat[vectorRows[i],vectorCols[i]] + 1
}
但我不禁想到在R中有更好的方法。我尝试使用apply
系列函数,但是当你想要分配一些东西时这些不合作。我知道我可以使用mapply
并一次构建countMat
一个值的每个元素,但这似乎效率低下 - vectorRows
和vectorCols
非常长,似乎在countMat
中为每个单元格完全遍历它们是浪费的。但除了循环和mapply
之外,我无法想到如何做到这一点。我已考虑将assign
与apply
系列中的一个一起使用,但有一点需要注意 - 我的矩阵实际上有列和行的名称,名称存储在vectorCols
和{ {1}},似乎vectorRows
不想播放像assign
apply这样的东西仍然希望为迭代中的每一步返回一个值。)
有什么建议吗?如果我没有矢量列和行的名称,如果有理想的方法,我也很好奇。如果是这种情况,那么我可以将countMat["rowName"]["columnName"] (not to mention that
和vectorCols
转换为数字,然后构建矩阵,然后重命名所有内容。
谢谢大家。
答案 0 :(得分:4)
以下是一些解决方案。不需要包裹。
1)表
table(vectorRows, vectorCols)
,并提供:
vectorCols
vectorRows 1 2 3
1 0 1 0
2 1 0 2
3 1 0 0
请注意,如果有任何行或列没有条目,则不会显示。
2)汇总
ag <- aggregate( Freq ~ ., data.frame(Freq = 1, vectorRows, vectorCols), sum)
countMat[as.matrix(ag[-3])] <- ag[[3]]
,并提供:
> countMat
[,1] [,2] [,3]
[1,] 0 1 0
[2,] 1 0 2
[3,] 1 0 0
3)xtabs
xtabs(~ vectorRows + vectorCols)
,并提供:
vectorCols
vectorRows 1 2 3
1 0 1 0
2 1 0 2
3 1 0 0