在R中创建矩阵的更有效代码

时间:2018-07-31 18:54:39

标签: r matrix

我想构建一个矩阵,其中该行的第一列是1到3的随机值,第二列是1到4的随机值,依此类推,直到列号tm-3。我创建了以下代码,以随机数填充矩阵

tm <- 10
A <- matrix(0, 5, 23)
for(i in 1:5){
  for(j in 1:c(tm-3)){
    A[i,j] <- sample(1:c(j+2), 1, replace = T)
  }
}
A[ ,-c(1:c(tm-3))] <- sample(1:tm, 16, replace = T)

该代码当然可以正常工作,但是当出现大型矩阵时,双循环会降低整个程序的速度。

是否可以根据上面的公式去掉double并用随机数填充前几列?

5 个答案:

答案 0 :(得分:2)

这是替换双循环的一种方法:

sapply(1:(tm-3), function(x) {sample(1:(x+2), 5, replace = TRUE)})

# example output
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,]    1    1    5    3    3    5    5
# [2,]    2    1    1    1    4    5    2
# [3,]    1    1    3    5    1    1    6
# [4,]    2    1    3    1    7    6    9
# [5,]    2    4    1    1    7    3    8

答案 1 :(得分:1)

这是一种使用单个for循环的方法-您可以通过将sample的大小设置为行数来一次完成每一列:

for(j in 1:(tm-3)){
    A[,j] <- sample(1:c(j+2), size = nrow(A), replace = T)
  }

这是没有for循环的一种方法,用最大允许值填充每一列,乘以runif值,然后取上限:

A[, 1:(tm - 3)] = ceiling(rep(1:(tm - 3) + 2, each = nrow(A)) * runif(nrow(A) * (tm - 3)))

您当然可以在矩阵的其余部分中遵循以下任一行:

    A[ ,-(1:c(tm-3))] <- sample(1:tm, 16, replace = T)

答案 2 :(得分:1)

这是仅使用单个循环的解决方案:

tm <- 10
B <- matrix(ncol=23,nrow=5)
for (i in seq_len(ncol(B))) B[,i] <- sample(min(i+2,tm),nrow(B),replace=TRUE)

生成的矩阵与其他已发布的解决方案不同之处在于,列号大于tm-3的元素:

#> B
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16]
#[1,]    1    3    4    6    3    7    5    8    6     6     1     6     9     8     2     6
#[2,]    2    1    3    2    3    5    3    3    7     7     4     5     1     4     9     4
#[3,]    2    1    2    2    2    8    3    3    4     5     8     8     4     6     1     1
#[4,]    2    3    5    2    1    7    5   10    7     3     6     2     1     1     8     4
#[5,]    3    3    2    2    2    1    2    9    4     8     2     9     3     6     1     7
#     [,17] [,18] [,19] [,20] [,21] [,22] [,23]
#[1,]    10     9     2     6     1     4     8
#[2,]     5     4    10     4     6     2     2
#[3,]     2     4     2     1     3     2    10
#[4,]     6     2     2     4     3     5     2
#[5,]     2     9     2     8     2     1     3

答案 3 :(得分:1)

这是一种使用lapplydo.call(cbind)来映射要替换的矩阵的方法。仅保留tm和矩阵作为参数,并避免使用sapply的奇数简化规则。将代码包装在函数中也使它具有更高的可重用性。

make_matrix <- function(tm, A){
  A[, 1:(tm - 3)] <- do.call(
    what = cbind,
    args = lapply(
      X = 1:(tm - 3),
      FUN = function(n) sample(1:(n + 2), nrow(A), replace = TRUE)
      )
    )
  return(A)
}
A <- matrix(0, 5, 23)
make_matrix(10, A)
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
#> [1,]    2    2    2    3    2    8    1    0    0     0     0     0     0
#> [2,]    1    4    4    5    3    3    4    0    0     0     0     0     0
#> [3,]    2    1    5    2    6    2    2    0    0     0     0     0     0
#> [4,]    1    2    2    1    7    7    7    0    0     0     0     0     0
#> [5,]    2    1    4    5    3    4    1    0    0     0     0     0     0
#>      [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23]
#> [1,]     0     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     0     0     0     0
#> [4,]     0     0     0     0     0     0     0     0     0     0
#> [5,]     0     0     0     0     0     0     0     0     0     0

was removed(v0.2.0)于2018-07-31创建。

答案 4 :(得分:0)

您可以编写一个函数,该函数用随机样本sapply()的第一tm-3列填充1:<column number + 2>。剩下的> 7列将通过replicate()中的1:tm进行填充并替换。在函数中,您可以定义结果矩阵的tm, nrow, ncol

mFun <- function(tm, nrow, ncol) {
  A <- matrix(NA, nrow, ncol)
  A[, 1:(tm-3)] <- sapply(1:(tm-3), 
                          function(x) sample(1:(x + 2), nrow, replace=TRUE))
  A[, - (1:(tm-3))] <- replicate(ncol - tm + 3, sample(1:tm, nrow, replace=TRUE))
  return(A)
  }

屈服

> set.seed(42)  # for sake of reproducibility
> mFun(tm=10, nrow=5, ncol=12)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    3    3    3    6    7    5    7    9    4    10     4     8
[2,]    3    3    4    6    1    4    8    1    5     9     4     7
[3,]    1    1    5    1    7    8    4    3    1     7     4     2
[4,]    3    3    2    3    7    4    7   10   10    10     8     3
[5,]    2    3    3    4    1    7    1    7    5     7     1     6

测试

以1.000 x 100.000矩阵运行非常快:

> system.time(A <- mFun(10, 1e3, 1e5))
   user  system elapsed 
   4.88    0.92    7.96