我有一个与R.有关的问题。
我有一些顺序编号的矩阵(所有相同的维度),我想要搜索它们并生成一个最终矩阵,其中包含(对于每个矩阵元素)超出定义阈值的次数。
作为一个例子,我可以选择0.7的阈值,我可以有以下三个矩阵。
matrix1 [,1] [,2] [,3] [1,] 0.38 0.72 0.15 [2,] 0.58 0.37 0.09 [3,] 0.27 0.55 0.22 matrix2 [,1] [,2] [,3] [1,] 0.19 0.78 0.72 [2,] 0.98 0.65 0.46 [3,] 0.72 0.57 0.76 matrix3 [,1] [,2] [,3] [1,] 0.39 0.68 0.31 [2,] 0.40 0.05 0.92 [3,] 1.00 0.43 0.21
我想要的输出是
[,1] [,2] [,3] [1,] 0 2 1 [2,] 1 0 1 [3,] 2 0 1
如果我这样做:
test <- matrix1 >= 0.7
test[test==TRUE] = 1
然后我得到一个矩阵,其中1超出阈值,0而不是。所以这是我想要做的关键一步:
test= [,1] [,2] [,3] [1,] 0 1 0 [2,] 0 0 0 [3,] 0 0 0
我的想法是做一个循环,所以我在每个矩阵上执行这个计算并添加“test”的每个结果,这样我得到了我想要的最终矩阵。但我不确定两件事:如何在变量名“矩阵”中使用计数器,第二,如果有一种比使用循环更有效的方法。
所以我想的是这样的事情:
output = matrix(0,3,3)
for i in 1:3 {
test <- matrixi >= 0.7
test[test==TRUE] = 1
output = output + test }
当然,这不起作用,因为matrixi不会转换为matrix1,matrix2等。
我真的很感谢你的帮助!
答案 0 :(得分:2)
如果您将矩阵存储在列表中,您会发现操作更容易:
lst <- list(matrix(c(0.38, 0.58, 0.27, 0.72, 0.37, 0.55, 0.15, 0.09, 0.22), nrow=3),
matrix(c(0.19, 0.98, 0.72, 0.78, 0.65, 0.57, 0.72, 0.46, 0.76), nrow=3),
matrix(c(0.39, 0.40, 1.00, 0.68, 0.05, 0.43, 0.31, 0.92, 0.21), nrow=3))
Reduce("+", lapply(lst, ">=", 0.7))
# [,1] [,2] [,3]
# [1,] 0 2 1
# [2,] 1 0 1
# [3,] 2 0 1
此处,lapply(lst, ">=", 0.7)
会返回一个x >= 0.7
列表,其中列出x
中存储的每个矩阵lst
。然后使用Reduce
调用+
将它们全部加起来。
如果您只有三个矩阵,则可以执行lst <- list(matrix1, matrix2, matrix3)
之类的操作。但是,如果你有更多(比方说100,编号为1到100),那么lst <- lapply(1:100, function(x) get(paste0("matrix", x)))
或lst <- mget(paste0("matrix", 1:100))
可能更容易。
对于100个矩阵,每个100 x 100(基于您的评论大致与您的用例大小相同),带有列表的Reduce
方法似乎比{{1}快一点使用数组进行处理,尽管两者都很快:
rowSums
答案 1 :(得分:0)
如果将矩阵放在数组中,这很容易做到没有循环。这是一个例子:
## dummy data
set.seed(1)
m1 <- matrix(runif(9), ncol = 3)
m2 <- matrix(runif(9), ncol = 3)
m3 <- matrix(runif(9), ncol = 3)
将这些粘贴到数组中
arr <- array(c(m1, m2, m3), dim = c(3,3,3))
现在每个矩阵都像一个盘子,阵列就是这些盘子的堆叠。
按照您的方式执行并将数组转换为指标数组(您无需保存此步骤,可以在下次调用中内联完成)
ind <- arr > 0.7
这给出了:
> ind
, , 1
[,1] [,2] [,3]
[1,] FALSE TRUE TRUE
[2,] FALSE FALSE FALSE
[3,] FALSE TRUE FALSE
, , 2
[,1] [,2] [,3]
[1,] FALSE FALSE FALSE
[2,] FALSE FALSE TRUE
[3,] FALSE TRUE TRUE
, , 3
[,1] [,2] [,3]
[1,] FALSE FALSE FALSE
[2,] TRUE FALSE FALSE
[3,] TRUE FALSE FALSE
现在使用rowSums()
函数计算您想要的值
> rowSums(ind, dims = 2)
[,1] [,2] [,3]
[1,] 0 1 1
[2,] 1 0 1
[3,] 1 2 1
请注意,rowSums()
中总结的内容(有点令人困惑!)维度dims + 1
。在这种情况下,我们将每个3 * 3单元的板堆(数组)的值相加,即输出中的9个值。
如果您需要将对象放入数组表单,可以通过
执行此操作arr2 <- do.call("cbind", mget(c("m1","m2","m3")))
dim(arr2) <- c(3,3,3) # c(nrow(m1), ncol(m1), nmat)
> all.equal(arr, arr2)
[1] TRUE
对于较大的问题(更多矩阵),请使用类似
的内容nmat <- 200 ## number matrices
matrices <- paste0("m", seq_len(nmat))
arr <- do.call("cbind", mget(matrices))
dim(arr) <- c(dim(m1), nmat)