如何在R中搜索顺序编号的矩阵变量

时间:2014-06-12 23:08:01

标签: r search matrix threshold sequential-number

我有一个与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等。

我真的很感谢你的帮助!

2 个答案:

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