我想构建一个矩阵,其中该行的第一列是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并用随机数填充前几列?
答案 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)
这是一种使用lapply
和do.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