【问题标题】:loop in r until value converges and stores all the outputs在 r 中循环,直到值收敛并存储所有输出
【发布时间】:2014-06-08 22:43:12
【问题描述】:

我想重复该过程,除非在存储结果时满足条件。

这是一个简单的例子,我知道循环中要执行的周期数:

# just example data
smpls <- rnorm(100,50,50)

ncycles <- 1000
outm <- matrix(nrow=ncycles, ncol = 1)

#重复这个过程n个循环

for(i in 1:ncycles){    
outm[i]  <- mean(sample(smpls, 50))
}
# get average of outm
outm <- mean(sample(smpls, 50))

但我的情况不同,因为我不知道 ncyles。我想继续采样,除非样本的方差非常低或收敛(我猜这是“while”循环。例如,除非在以下情况下 vsd 小于 1。

vsd <- NULL
outm <- mean(sample(smpls, 50))
while (vsd > 1){
    outm[i] <- mean(sample(smpls, 50))
    vsd <- sd(outm)
     }

我不知道这里要设置的 i 的值。帮助表示赞赏

编辑:

smpls <- rnorm(100,50,50)
iter <- 0
# maximum iteration 
itermax <- 1000 
outm <- rep(NA, itermax)
vsd <- 2
while((vsd > 1 ) && (iter < itermax)) {
     outm[iter] <- mean(sample(smpls, 50))
     vsd <- sd(outm)
     iter <- iter+1
     }
Error in while ((vsd > 1) && (iter < itermax)) { : 
  missing value where TRUE/FALSE needed

达到收敛时停止的主要思想是节省时间。尽管上面仅使用均值函数的示例很快,但我的原始函数需要大量时间来进行迭代,我想在它收敛时停止它。

【问题讨论】:

  • 只要outm 的标准差大于 1,您就在循环。但是,在您的第一次迭代后,outm 的长度为 1,标准差为 0,导致您的循环终止.
  • 开始 outm 作为一个长向量,比如 10K。如果迭代索引超出范围,请检查将其再扩展 10K 的循环。收敛后修剪 NA。不用说你需要初始化和增加i。这将最大限度地减少 outm 从头开始​​重写的次数。
  • 感谢 @ilir、SHRram 和 josilber - 尝试调整循环仍然出错,请参阅当前编辑
  • 您的代码中仍然存在一些小问题。首先,您应该使用 1 初始化变量 iter(R 中的向量从 1 开始,而不是 0),然后在您的第一个循环运行中,您从单个值计算 sd,这会在 R 中引发 NA。感觉,在while循环外计算第一个outm,然后开始iter,即使值为2,然后,因为你在初始outm中有NA,计算sd通过sd(outm,na.rm=TRUE)和你的while循环应该可以工作。

标签: r loops while-loop


【解决方案1】:

您的代码中有两个问题:

1) 你需要 sd(... , na.rm = TRUE)

2) 您需要确保 outm 中至少有两个数字用于 sd(outm, na.rm = TRUE) != NA

顺便说一句,鉴于您指定给 rnorm 的 sd,我认为您永远不需要超过几十次迭代

sim <- function() {
  smpls <- rnorm(100,50,5)
  itermax <- 1000
  outm <- rep(NA, itermax)
  outm[1] <- mean(sample(smpls, 50))
  iter <- 1
  vsd <- 2
  while((vsd > 1 ) && (iter < itermax)) {
       iter <- iter+1
       outm[iter] <- mean(sample(smpls, 50))
       vsd <- sd(outm, na.rm = TRUE)
       }

  iter
  }

set.seed(666)
iters <- replicate(100000, sim() )
range(iters)  # c(2, 11)

干杯。

【讨论】:

  • 感谢您指出代码中的两个重要限制 - 但是我只是获取所有 100000 次迭代的值 - 尽管这个工作示例小而快 - 我需要做的迭代是花费时间和当值达到收敛时,我想停止进一步计算
  • @jon - 以上第 2 - 12 行是否适合您?如果他们这样做,您可以采取解决方案并保留奖金(我没有 strackoverflow 帐户...)。如果它不起作用,请告诉我你看到了什么,我会再试一次。
  • +1 用于纠正问题(2-12 行),但最初我不明白该函数的含义。
  • 感谢您的反馈。我应该指出该函数只是一个包装器,用于查看实际执行了多少次迭代(实际上与您的原始问题无关)......
【解决方案2】:

这里有一个解决方案:

数据

set.seed(123) # so that you can replicate what I did 
smpls <- rnorm(100,50,50)

我认为您需要一些初始化周期(最小迭代),以便您确实获得错误收敛,因为您的样本数量很少。所以运行几个样本 - 比如说 miniter。你还需要一个最大迭代,这样你的循环就不会变得疯狂——比如 maxiter。

 meanconverge <- function (data, miniter, maxiter, tolerance){ 
      outm <- rep(NA, maxiter) 
     for(i in 1:miniter){    
     outm[i]  <- mean(sample(smpls, 50))
     }
     # sd of initial cycles 
    vsd <- sd(outm, na.rm = TRUE)
     if(vsd > tolerance) {
                   iter <- miniter+1
                   sdout <- rep(NA, maxiter)
                   while((vsd > tolerance ) && (iter < maxiter)) {
                     iter <- iter + 1
                     outm[iter] <- mean(sample(smpls, 50))
                     vsd <- sd(outm, na.rm = TRUE)
                     sdout[iter] <- vsd             
       } 
      out <- list(outm, sdout)
      return(out)
      } else {
      return(outm)
      }
      }

 out <- meanconverge  (data = smpls, miniter = 50, maxiter = 100000, tolerance = 3)
 plot(unlist(out[2]), pch = ".", col = "red") 

 plot(unlist(out[1]), pch = ".", col = "red")

【讨论】:

    【解决方案3】:

    检查收敛是一件棘手的事情。一个很好的入门方法是查看计算时值如何变化。收敛就是任意接近边界。以编程方式,您必须选择“任意”的含义。您还需要决定如何衡量收敛性。

    为了说明,假设我想知道我对满足我的条件的估计是否真的彼此接近。我可能有类似的东西:

    # inside my function or method that performs this convergence feat
    while (while_condition && i < itermax)) {
    
        outcome[i] <- some_complicated_foo(bar)
    
        if ( abs(outcomes[i-1] - outcomes[i]) <= tolerance ) {
           while_condition <- FALSE # i.e. STOP LOOPING
           return outcomes
        } 
    
        else {continue}
    
    }
    

    tolerance 是您对任意接近度的定义。现在,这似乎是你的钉子,对吧?那么,如果你收敛到错误的答案会发生什么?你怎么知道?这东西还能收敛吗?解决这类问题的诀窍是对您的函数或您正在分析的数据生成过程进行准确的猜测。但是,只要合理,拥有最大迭代边界肯定会减少一些计算时间。知道你是否正确的真正方法是使用测试(如统计测试或单元测试)来查看是否有任何“垃圾进垃圾”或得到与你所期望的不同的东西一个众所周知的答案。

    查看优化算法,看看它们是如何做到的。请参阅?optim 或其他一些优化包,了解专业人士是如何做到的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-06
      • 1970-01-01
      相关资源
      最近更新 更多