Генерация случайной матрицы 0/1 с фиксированными элементами в R - PullRequest
0 голосов
/ 06 мая 2019

Я хочу сгенерировать случайную матрицу M x N с нулями и со следующими специальными свойствами:

1) Они есть только в m из M строк.

2) Они есть только в n столбцов N.

Предположим, мне даны ТОЛЬКО M=10, N=10, m=6 и n=4. Одна возможная случайная матрица определяется как

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    0    1    0    0    0    1    0    1     0
 [2,]    0    0    1    0    0    0    1    0    1     0
 [3,]    0    0    0    0    0    0    0    0    0     0
 [4,]    0    0    0    0    0    0    0    0    0     0
 [5,]    0    0    1    0    0    0    1    0    0     0
 [6,]    0    1    0    0    0    0    0    0    0     0
 [7,]    0    0    0    0    0    0    0    0    0     0
 [8,]    0    0    1    0    0    0    0    0    0     0
 [9,]    0    0    1    0    0    0    0    0    1     0
[10,]    0    0    0    0    0    0    0    0    0     0

Для воспроизводимости я искусственно сгенерировал вышеупомянутую "случайную" матрицу, используя

ex <- matrix(0,10,10)
ex[1,3] <- ex[1,7] <- ex[1,9] <- ex[2,3] <- ex[2,7] <- 
  ex[2,9] <- ex[5,3] <- ex[5,7] <- ex[6,2] <- ex[8,3] <- ex[9,3] <- ex[9,9] <- 1

Обратите внимание, что

sum(rowSums(ex)>0)
[1] 6
sum(colSums(ex)>0)
[1] 4

, которые точно соответствуют m и n выше. Количество из них может быть случайным. В одном крайнем случае у меня может быть 6 столбцов, распределенных по 6 строкам и 4 столбцам (2 столбца будут иметь 2 столбца, в то время как у остальных - 1), а в другом крайнем случае у меня может быть 24 (каждый из 6 рядов будет иметь 1 в тех же 4 колонках).

Вопрос Я могу сгенерировать это методом грубой силы, используя выборки по строкам и столбцам, но мне нужно сделать это по тысячам таких матриц (потому что m и n будут отличаться каждый раз), и эти матрицы большие ( M=5000 и N=8000, как правило). Есть ли способ сделать это эффективно в R?

Ответы [ 2 ]

1 голос
/ 06 мая 2019
M=10 #total number rows
N=10 #total number columns
m=6 #number valid rows
n=4 #number valid columns

#number of cells to simulate
k=12

ex <- matrix(0,M,N)

#sample m valid rows and n valid columns from uniform
mi <- sample(1:M, m) 
ni <- sample(1:N, n)

#get all valid cells (valid rows and columns)
mn_i <- expand.grid(mi, ni)

#sample k cells from valid cells
x <- mn_i[sample(1:nrow(mn_i), k), ]

#update sampled cells using matrix subet on ex
ex[as.matrix(x)] <- 1

# > ex
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,]    1    0    0    0    0    0    0    0    0     0
# [2,]    0    0    0    0    0    0    0    0    0     0
# [3,]    0    0    0    0    0    0    1    1    0     1
# [4,]    0    0    0    0    0    0    0    0    0     0
# [5,]    1    0    0    0    0    0    1    1    0     1
# [6,]    1    0    0    0    0    0    1    0    0     0
# [7,]    0    0    0    0    0    0    0    0    0     0
# [8,]    0    0    0    0    0    0    0    1    0     1
# [9,]    0    0    0    0    0    0    0    0    0     0
# [10,]    0    0    0    0    0    0    0    0    0     0

Возможно, вы захотите заключить в функцию, чтобы вызвать что-то вроде

 ex <- constrained_matrix_sample(M, N, m, n, k)
0 голосов
/ 06 мая 2019

A dplyr вариант

M = 10 # rows
N = 10 # columns
m = 6
n = 4

ni = sample(1:N, n)
mi = sample(1:M, m)

expand.grid(N = 1:N, M = 1:M) %>% 
  mutate(value = ifelse(N %in% ni & M %in% mi, 1, 0)) %>% 
  .$value %>% 
  matrix(., nrow = M, byrow = TRUE)
...