在R中生成具有固定特征的随机0/1矩阵

时间:2019-05-06 17:54:48

标签: r matrix random

我想生成一个随机的M x N矩阵,该矩阵包含零和一个具有以下特殊属性:

1)仅位于m行的M中。

2)仅位于n列的N中。

假设仅给出M=10N=10m=6n=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

与上面的mn完全匹配。一个的数量可以是随机的。在一个极端上,我可能有6个分布在6行和4列上(2列将有2个,而其余的有1个),或者在另一个极端,我可以有24个(6行中的每个都有一个在同一4列中为1)。

问题 我可以用蛮力的方式生成它,对行和列进行采样,但是我需要对成千上万个这样的矩阵进行处理(因为mn每次都不同),并且这些矩阵很大(通常是M=5000N=8000)。有没有办法在R中有效地做到这一点?

2 个答案:

答案 0 :(得分:1)

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)

答案 1 :(得分:0)

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)