Рандомизировать и сравнивать матрицы в R - PullRequest
0 голосов
/ 02 августа 2020

У меня есть две матрицы (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].

Есть какие-нибудь мысли, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 03 августа 2020

Я бы использовал пакет 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 обрабатывает все поэлементные операции под капотом, так что это должно быть все, что вам нужно.

0 голосов
/ 02 августа 2020

Давайте начнем с уменьшенной версии и проработаем то, что вы пытаетесь сделать. Я устанавливаю случайное начальное число, поэтому вы получите те же результаты:

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. Приведенная выше матрица показывает, сколько раз cc было больше для этой ячейки за 10 повторений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...