【问题标题】:Randomize and compare matrices in R在 R 中随机化和比较矩阵
【发布时间】:2020-11-22 11:59:18
【问题描述】:

我有两个矩阵(1 和 2)相乘,得到一致性矩阵 (c)。

我需要将这些矩阵中的一个随机化 1000 次,然后他们比较这些一致性矩阵的值高于第一次比较的次数。

# Exemple:
 mat1 <- matrix(rbinom(222, 1, 0.5),nrow=74,ncol=3) # habitat

 mat2 <- matrix(rbinom(592, 1, 0.5),nrow=74,ncol=8) # modular

 tmat1 <- t(mat1)

 # Multipying the tranposed matrix 1 by matrix 2:

 c <- tmat1%*%mat2 # concordance matrix c

 resu <- matrix(NA,nrow=3,ncol=8) # creating the matrix to fill with the results of values higher than c

  for(r in 1:1000) {

mat3 <- apply(mat1,1,sample) # randomizing matrix 1, maintaining the number of intercations by nodes

cc <- mat3%*%mat2 # multiplying these matrices 

for (i in 1:dim(c)[1]){ # rows

 for(j in 1:dim(c)[2]){ # columns

   if(cc[i]>=c[j]){ #  

   resu[i,j] <- sum(cc[i]>=c[j]) # filling the matrix with the number of times cc was higher then c

   } 

 }

}

}

但结果是错误的:它生成的矩阵具有正确的行数 (3) 和列数 (8),但全部填充为 1。

每个元素的一致性在 cc[i] 中高于 c[j] 的次数必须不同。

有什么想法吗?

【问题讨论】:

    标签: r loops matrix random


    【解决方案1】:

    让我们从较小的版本开始,逐步完成您想要做的事情。我正在设置一个随机种子,所以你会得到相同的结果:

    set.seed(42)
    mat1 <- matrix(rbinom(75, 1, 0.5), nrow=25, ncol=3)
    mat2 <- matrix(rbinom(200, 1, 0.5), nrow=25, ncol=8)
    tmat1 <- t(mat1)
    c <- tmat1 %*% mat2
    c
    #      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    # [1,]   10   11   10    7   10    9    5    6
    # [2,]    9   11   11    7    8    7    4    8
    # [3,]    5    7    8    6    7    4    4    7
    

    现在你想要一个mat1 的版本,每行中的值都被打乱了。然后你想知道第二个矩阵中有多少值更大:

    mat3 <- apply(mat1, 1, sample)
    cc <- mat3 %*% mat2
    cc
    #      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    # [1,]    7   10   12    7   10    8    5    8
    # [2,]    9    8    7    5    6    5    3    5
    # [3,]    8   11   10    8    9    7    5    8
    cc > c
    #       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]
    # [1,] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE
    # [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
    # [3,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
    sum(cc > c)
    # [1] 10
    

    现在创建一个处理这一步的函数:

    matrand <- function(mat1, mat2, prod) {
        mat3 <- apply(mat1, 1, sample)
         cc <- mat3 %*% mat2
         cc > prod
    }
    

    最后根据需要多次运行该函数:

    results <- replicate(10, matrand(mat1=mat1, mat2=mat2, prod=c))
    apply(results, 1:2, sum)
    #      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    # [1,]    1    1    4    2    0    1    3    4
    # [2,]    4    3    1    1    6    4    6    2
    # [3,]    8    8    9    5    6    9    3    5
    

    对象results 是一个 3x8x10 数组。上面的矩阵是该单元格在 10 次复制中cc 较高的次数。

    【讨论】:

    • 谢谢!我仍在学习如何在这里和 R 使用。对于结果,我需要查看 cc 的值高于 c 的次数:对于元素 [1,1],随机化 cc 的值比一致性矩阵高多少次c,并在 cc 随机化之后继续我的相关一致性矩阵的每个元素组合。我会尝试使用您建议的功能,看看我是否可以适应这样做。
    • 为此,您可能希望保存整个矩阵 (cc > pro) 而不仅仅是总和。我修改了答案,将所有逻辑矩阵保存在一个数组中。
    • 是的,它起作用了@dcarlson!但是有一件事......在我的情况下,在随机化中保持相同的行总和值并且只随机化标签列是很重要的。我不知道为什么,但是当使用 apply 和转置 mat1 并在 mat3 工作后转置时。行保持总数,但列上的分布不同。非常感谢!!
    【解决方案2】:

    我会使用包 purrr 并使用 map 和 reduce 概念

    library(purrr)
    mat1 <- matrix(rbinom(222, 1, 0.5),nrow=74,ncol=3) # habitat
    
    mat2 <- matrix(rbinom(592, 1, 0.5),nrow=74,ncol=8) # modular
    
    tmat1 <- t(mat1)
    
    # Multipying the tranposed matrix 1 by matrix 2:
    
    c <- tmat1%*%mat2
    mat3 <- apply(mat1,1,sample)
    cc<-mat3 %*% mat2
    map(1:1000, ~apply(mat1,1,sample)) %>% #sample 1000 matrices
      map(~`%*%`(.,mat2)) %>% # multiply them with mat2
      map(~`>`(., c)) %>% #check for each result which element is greather the first result c
      reduce(`+`) # use the fact that TRUE -> 1 and just sum all the comparison matrices
    

    R 在后台处理所有元素操作,所以这应该就是您所需要的。

    【讨论】:

    • 谢谢您,Bertil Baron 和@Dharman!这也有效,但是作为使用其他建议,在我的情况下,随机化保持行总和的相同值并且仅随机化标签列是很重要的。我不知道为什么,但是当使用 apply 和转置的 mat1 并在此之后转置 mat3 以我需要的方式工作这里。行保持总数,但列上的分布不同。非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    相关资源
    最近更新 更多