【问题标题】:R - Simple loop not working: no loop for break/next, jumping to top levelR - 简单循环不起作用:没有循环中断/下一个,跳转到顶层
【发布时间】:2021-10-20 05:25:57
【问题描述】:

我知道这可能是一个简单的问题,但我正在努力学习和改进。当我尝试这段代码时,它给了我错误:“没有循环中断/下一个,跳转到顶层”。有人可以建议为什么并帮助我吗?非常感谢。

x_1 <- rnorm(100)
x_2 <- rnorm(10000)
x_3 <- rnorm(1000000)

to_evaluate <- list(x_1, x_2, x_3)

speed_test <- for (i in to_evaluate) {
  microbenchmark(mean_loop(i), mean_mat(i), mean(i))
} 
print(speed_test)

mean_loop 和 mean_mat 的代码:

x <- c(1:11)

mean_loop <- function(x) {
  
  sum_of_x <- 0
  
  for(i in x){
    sum_of_x <- sum_of_x + x[i]
  }
  
  mean_of_x <- sum_of_x/length(x)
  return(mean_of_x)
}

mean_mat <- function(x) {
sum(diag(length(x))%*%x)/length(x)
}

函数microbenchmark(来自包microbenchmark)可让您测量代码运行的速度。如果你给它代码来评估,它会评估它 100 次,并返回关于代码运行多长时间的摘要统计信息。如果你给它多个表达式,它会对每个表达式都这样做。

【问题讨论】:

  • 也许可以尝试使用for (i in length(to_evaluate)。另外,您是否考虑过使用lapply?即lapply(to_evaluate, function(x) microbenchmark(mean_loop(x), mean_mat(x), mean(x)))?您能否添加用于microbenchmark()mean_loop()mean_mat() 函数的包?
  • 谢谢!我添加了代码。不幸的是,您的解决方案都不适合我,但感谢您的帮助!

标签: r loops break next microbenchmark


【解决方案1】:

这适用于我使用问题中的函数定义 -

x_1 <- rnorm(10)
x_2 <- rnorm(100)
x_3 <- rnorm(1000)
library(microbenchmark)
to_evaluate <- list(x_1, x_2, x_3)

result <- vector('list', length(to_evaluate))

for (i in seq_along(to_evaluate)) {
  val <- to_evaluate[[i]]
  result[[i]] <- microbenchmark(mean_loop(val), mean_mat(val), mean(val))
} 

result

#[[1]]
#Unit: microseconds
#           expr   min     lq    mean median    uq     max neval cld
# mean_loop(val) 2.818 3.2495 7.62632  4.204 5.847  41.214   100   a
#  mean_mat(val) 2.547 2.9765 7.90376  3.571 4.940  93.155   100   a
#      mean(val) 1.896 2.1700 6.59605  2.818 4.204 116.467   100   a

#[[2]]
#Unit: microseconds
#           expr    min      lq     mean median      uq     max neval cld
 #mean_loop(val) 49.368 89.8705 92.81099 92.820 99.6505 179.400   100   c
 # mean_mat(val) 18.968 50.7335 55.61163 52.987 55.5770 141.363   100  b 
 #     mean(val)  2.090  2.2815  3.87982  2.803  3.3115  33.779   100 a  

#[[3]]
#Unit: microseconds
#           expr      min        lq       mean   median        uq       max neval cld
# mean_loop(val) 1359.527 1511.9295 3312.36578 1835.326 2970.1350 16455.048   100   b
#  mean_mat(val) 1713.178 2155.3815 4032.53143 2352.858 2739.6650 19783.264   100   b
#      mean(val)    3.708    4.6695   16.39451   14.881   21.8355   162.184   100  a 

【讨论】:

    【解决方案2】:

    使用 lapply() 你可以这样做:

    speed_test <- lapply(to_evaluate, function(x) microbenchmark(mean_loop(x), mean_mat(x), mean(x)))
    print(speed_test)
    

    例子:

    # had to remove x_3 to overcome a crash not linked with the use of a loop or lapply, see the Note at the end of the post
    x_1 <- rnorm(100)
    x_2 <- rnorm(10000)
    to_evaluate <- list(x_1, x_2)
    
    library(microbenchmark)
    
    speed_test <- lapply(to_evaluate, function(x) microbenchmark(mean_loop(x), mean_mat(x), mean(x)))
    

    输出:

    > print(speed_test)
    
    [[1]]
    Unit: microseconds
             expr  min    lq   mean median   uq    max neval cld
     mean_loop(x) 35.3 36.05 67.174  36.85 37.3 3000.9   100   a
      mean_mat(x) 19.7 20.25 38.090  20.60 20.9 1761.0   100   a
          mean(x)  2.0  2.30  2.793   2.70  2.9   13.8   100   a
    
    [[2]]
    Unit: microseconds
             expr      min        lq       mean    median        uq      max neval cld
     mean_loop(x) 126214.8 139520.40 211537.906 182460.50 245618.95 463139.9   100  b 
      mean_mat(x) 275451.1 314082.60 337446.084 340836.75 358470.35 411152.0   100   c
          mean(x)     16.7     20.15     31.192     33.35     35.35     82.0   100 a  
    

    注意:

    无论我是否使用 lapply 循环,在我的计算机上,我都会遇到与您的问题无关的性能问题。 即使这对我不起作用microbenchmark(mean_loop(to_evaluate[[3]]), mean_mat(to_evaluate[[3]]), mean(to_evaluate[[3]])),而其他运行良好(to_evaluate[[1]]to_evaluate[[2]])。

    【讨论】:

    • 嗨,保罗!谢谢!我试过了,但错误“没有循环中断/下一个,跳转到顶层”不断弹出。我认为错误实际上是在 microbenchmark() 内部。
    • @CeciliaBonucchi 此答案中提供的代码确实对我有用并产生显示的输出:/ 但是,由于某些原因,如果我包含自定义函数 mean_mat()mean_loop() 它会崩溃,但对于另一个原因,而不是您指出的原因
    • 我刚刚测试并得到了相同的推理。我认为微基准不能一次执行多个功能。您认为我需要嵌套 lapply 还是嵌套循环?你能帮我建造它吗?非常感谢
    • @CeciliaBonucchi,Ronak 解决了您的循环问题,我认为因此我将答案集中在 lapply 的一个想法上,但是由于另一个与您的问题无关的问题,我无法对其进行测试。我好像microbenchmark()实际上可以一次处理多个函数。
    • 非常感谢您为帮助我所做的所有努力!我会尝试让您的代码(这真的很有趣)也适用于 x_3!再次感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 2014-04-10
    相关资源
    最近更新 更多