我正在构建一个模拟,根据用户定义的参数随机为R中的子数组分配字符标签。
我的代码如下
K <- 2 ### Number of subarrays
K1 <- c(1:3) ### labels in first subarray
K2 <- c(4:5) ### labels in second subarray
N <- 10
Hstar <- 5
perms <- 10 ### rows in each subarray
specs <- 1:N
specs1 <- 1:(N/2) ### specs in subarray 1
specs2 <- ((N/2) + 1):N ### specs in subarray 2
pop <- array(dim = c(c(perms, N/K), K)) ### population subarrays
haps <- as.character(1:Hstar) ### character labels
probs <- rep(1/Hstar, Hstar) ### label probabilities
### 'for' loop to randomly populate 'pop' with 'haps' according to 'probs'
for(j in 1:perms){
for(i in 1:K){
if(i == 1){
pop[j, specs, i] <- sample(haps, size = N, replace = TRUE, prob = probs)
}
else{
pop[j, specs1, 1] <- sample(haps[K1], size = N/2, replace = TRUE, prob = probs[K1])
pop[j, specs2, 2] <- sample(haps[K2], size = N/2, replace = TRUE, prob = probs[K2])
}
}
}
我想要做的是填充(按行,而不是列)&#39; pops&#39;,它由两个子阵列组成,带有字符标签(&#39; haps&#39;)。具体地,子阵列1仅需要包含来自K1的标签,并且子阵列2必须仅包含来自K2的标签。 &#39;弹出&#39;尺寸为10×5×2(子阵列1中的值为50,子阵列2中的值为50)。不幸的是,R抛出了错误
Error in `[<-`(`*tmp*`, j, specs, i, value = c("4", "1", "3", "4", "1", :
subscript out of bounds
当嵌套&#39; for&#39;循环运行,我似乎无法理解为什么。我认为它与specs,specs1,specs2有关。基本上,来自&#39; specs&#39;的值。分为&#39; specs1&#39;和&#39; specs2&#39;。但是,错误表明问题在于pop [j,specs,i],但是由于K = 2,程序的这一部分不应该受到影响......但事实确实如此。
有关如何解决问题的任何想法,以便程序运行任何K值?
如果需要进一步澄清,请与我们联系。
答案 0 :(得分:1)
让我划分零件上的错误。下面的行错误地指定了分配维度。
我注意到有一些不一致,因为你试图逐行循环(10次迭代),每行有5个元素(5列)。我怀疑你要按列循环,所以它应该是perms=5
。
为了描述这个问题,如果你按每个元素调试代码,你会看到pop[j, specs, i]
。您正在尝试引用pop[ 1 , 1:10 , 1]
,并且您的子阵列具有维度10x5
,这意味着您必须切换到pop[,1,1]
(您不需要指定1:10)就整个专栏而言。)
pop[j, specs, i] <- sample(haps, size = N, replace = TRUE, prob = probs)
sample(haps, size = N, replace = TRUE, prob = probs)
# [1] "3" "1" "4" "3" "2" "1" "1" "1" "2" "2"
pop[j, specs, i]
# Error in pop[j, specs, i] : subscript out of bounds
pop[specs, j, i]
# [1] "5" "2" "1" "4" "3" "5" "1" "5" "5" "2"
pop[, j, i] <- sample(haps, size = N, replace = TRUE, prob = probs)
# [,1] [,2] [,3] [,4] [,5]
# [1,] "5" NA NA NA NA
# [2,] "1" NA NA NA NA
# [3,] "4" NA NA NA NA
# [4,] "1" NA NA NA NA
# [5,] "1" NA NA NA NA
# [6,] "2" NA NA NA NA
# [7,] "5" NA NA NA NA
# [8,] "5" NA NA NA NA
# [9,] "3" NA NA NA NA
#[10,] "3" NA NA NA NA
同样的问题出现在else
部分,在那里我可以看到同样的错误。下面正确一个
pop[specs1 , j, 2] <- sample(haps[K1], size = N/2, replace = TRUE, prob = probs[K1])
pop[specs2 , j, 2] <- sample(haps[K2], size = N/2, replace = TRUE, prob = probs[K2])
无论如何,有更好的方法来完成这项任务:
pop[,,1] <-
apply(
pop[,,1], 2,
function(x) sample(haps, size = N, replace = TRUE, prob = probs) )
pop[specs1,,2] <-
apply(
pop[specs1,,2], 2, function(x)
sample(haps[K1], size = N/2, replace = TRUE, prob = probs[K1]) )
pop[specs2,,2] <-
apply(
pop[specs2,,2], 2, function(x)
sample(haps[K2], size = N/2, replace = TRUE, prob = probs[K2]) )
答案 1 :(得分:0)
R语言在矢量化方面非常有效。您可以使用此功能来防止使用for循环。
为了使代码有效,我需要纠正一些错误:
specs
指的是数组的第一维而不是第二维。 specs1
和specs2
是指第二个子阵列(在您的示例中为i=2
)。我修改了以后。要填充数组,我会生成与您要填充的数组对应的大小样本。我使用了length
和dim
。数组由列填充,即第一列,每行,第二列等......
K <- 2 ### Number of subarrays
K1 <- c(1:3) ### labels in first subarray
K2 <- c(4:5) ### labels in second subarray
N <- 10
Hstar <- 5
perms <- 10 ### rows in each subarray
specs <- 1:N
specs1 <- 1:(N/2) ### specs in subarray 1
specs2 <- ((N/2) + 1):N ### specs in subarray 2
pop <- array(dim = c(c(perms, N/K), K)) ### population subarrays
haps <- as.character(1:Hstar) ### character labels
probs <- rep(1/Hstar, Hstar) ### label probabilities
pop[specs, , 1] <- sample(haps, size = length(specs) * dim(pop)[2], replace = TRUE, prob = probs)
pop[specs1, , 2] <- sample(haps[K1], size = length(specs1) * dim(pop)[2], replace = TRUE, prob = probs[K1])
pop[specs2, , 2] <- sample(haps[K2], size = length(specs2) * dim(pop)[2], replace = TRUE, prob = probs[K2])
pop
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "4" "3" "2" "3" "2"
#> [2,] "5" "4" "3" "1" "4"
#> [3,] "1" "3" "4" "3" "5"
#> [4,] "3" "3" "5" "5" "3"
#> [5,] "2" "4" "3" "4" "4"
#> [6,] "3" "3" "2" "4" "1"
#> [7,] "5" "1" "4" "4" "1"
#> [8,] "4" "3" "2" "3" "2"
#> [9,] "3" "2" "3" "3" "1"
#> [10,] "3" "4" "1" "4" "2"
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] "3" "3" "2" "1" "3"
#> [2,] "2" "2" "2" "2" "2"
#> [3,] "2" "2" "2" "2" "1"
#> [4,] "2" "3" "2" "3" "1"
#> [5,] "1" "2" "2" "3" "2"
#> [6,] "5" "5" "5" "4" "5"
#> [7,] "4" "5" "4" "5" "5"
#> [8,] "5" "5" "4" "5" "5"
#> [9,] "4" "5" "5" "4" "4"
#> [10,] "5" "4" "5" "5" "4"
我认为你建立在参数化的基础上允许使用任何K值。