R下标超出绑定错误 - 用于自定义函数的循环

时间:2018-03-20 20:04:36

标签: r loops for-loop

我已经编写了一个函数来模拟遗传漂移,并且我希望将其循环到各种t值(代数)上,但是每当我这样做时,我都会收到以下错误:

locifreq<-runif(49, .4, 0.8)

gen<-1:100
for (i in 1:length(gen)){
  pop[i]<-lapply(locifreq,wright.fisher,3000,200,gen[i])
}
Error in `[<-`(`*tmp*`, i, j, value = rbinom(1, 2 * N, prob = k[i - 1,  : 
  subscript out of bounds

我认为这是因为我的功能无法生成适当的矩阵,或者它无法访问列表中的矩阵(尽管我可能完全错了!) ,但是我不确定如何解决这个问题,因为每次尝试都会导致下标数量不正确。

我的功能代码在

之下
wright.fisher<-function(p,Ne,nsim,t){
  N <-Ne/2
  NA1 <- 2*N*p 
  NA2 <- 2*N*(1-p)
  k <- matrix(0, nrow = t, ncol = nsim)
  k[1,] <- rep(NA1, nsim) 
  for (j in 1:nsim) {
    for (i in 2:t) {
      k[i, j] <- rbinom(1, 2*N, prob = k[i-1, j] / (2*N))  
    }
  }
  k <- as.matrix(k/(2*N)) 
  t(k)
}

有谁知道如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

使用此部分代码复制您的问题:

wright.fisher(locifreq[1], 3000, 200, 1)

导致下标越界错误的特定步骤是在循环的第一步中在第9行中分配k[i,j]。此时,i为2,j为1.您通常可以通过将对象分配给超出其范围的索引来扩展对象,但是您无法通过在需要改变尺寸数量的方式。 (这是k[2,1]当时所做的事情,因为它是1行和200列的矩阵。

k <- matrix(1:200, 1)
k[2,1] <- 5
# Error in `[<-`(`*tmp*`, 2, 1, value = 5) : subscript out of bounds

您可以通过让函数初始化矩阵以获得正确的维数来解决此问题。对功能的第5行进行更改

k <- matrix(0, nrow = max(2, t), ncol = nsim)

我之所以选择max(2, t),是因为这就是嵌套for循环的要求所强加的:for (i in 2:t)。它完成,解决你的帖子中的问题,但请确认它产生你想要的行为。

此外,您的代码中有许多不是特别有效的习惯用语,但这是另一个问题。

如何在R

中进行调试

如果你想知道如何调试这样的东西......我正在考虑编写一个关于如何使用浏览器的教程(这里经常出现)。在函数体顶部添加一行browser()。然后,当您尝试运行浏览器时,它会在浏览器中将其拉出来,这样您就可以一次单步执行一个语句。输入help以查看如何导航。在RStudio中,请继续关注“环境”选项卡以查看该变量的值。请注意,您可以在浏览器中评估任何R表达式。这将帮助您检查您认为导致问题的原因。

答案 1 :(得分:0)

你的Wright-Fisher模拟看起来有点复杂,但我不知道你在模拟什么,所以也许这是正确的。我会使用一个更简单的版本,只需在下一代中对基因频率进行采样,给出频率和有效种群大小。

target = [[1],[1]]
add = [2,4]
count = 0

idx = 0
while idx < len(target):
    target[idx].append(add[idx])
    idx += 1

print(target)

# >>> 
[[1, 2], [1, 4]]

真正的问题是表以及如何索引它。如果wf <- function(f, Ne) { rbinom(1, 2*Ne, prob = f) / (2*Ne) } 计算给定wff的一个频率,并且您希望在Ne代之间进行no_sims次模拟,则可以构建no_gen表格,填充它,使得行对应于世代,列对应于独立的模拟。它看起来像这样:

no_gens x no_sims

这些(小)参数的结果如下所示:

no_sims <- 5
no_gens <- 4
Ne <- 10000

locifreq <- runif(5, .4, 0.8)
sims <- matrix(NA, ncol = no_sims, nrow = no_gens)
sims[1,] <- runif(5, .4, 0.8) # first generation
for (gen in 2:no_gens) {
    sims[gen,] <- sapply(sims[gen-1,], FUN = wf, Ne = Ne)
}