为每次循环迭代设置时间限制

时间:2019-03-27 10:04:36

标签: r timeout

在R中,我遍历对象向量,并在每次迭代时应用相同的命令。如何(i)停止耗时太长的迭代,(ii)打印错误/警告消息,(iii)进行下一个迭代?

例如,假设我有一个包含3个时间段的向量,并且我将这5个时间段限制为R个睡眠时间。 如果for循环迭代花费的时间超过5秒(此处为向量的第二个),则应在5秒左右停止并继续运行。

以下代码的问题是,如果迭代花费的时间太长,R不会停止,而是仅在迭代完成后才打印错误消息,而不是在时限内直接输出。

vec <- c(2, 12, 3)

# using base R 'setTimeLimit' function
for(i in 1:length(vec)){
    cat(". Sleeping", vec[i], "seconds\n")

    tryCatch(
        {
            system.time(
                local(
                    {
                        setTimeLimit(elapsed = 5, transient = TRUE)
                        Sys.sleep(vec[i])
                    }
                )
            )
        },
        error=function(e){cat(conditionMessage(e), "\n")}
    )
}

# using R.utils 'withTimeout' function
library(R.utils)
for(i in 1:length(vec)){
    cat(". Sleeping", vec[i], "seconds\n")

    # first 'tryCatch' if error NOT caused by a timeout
    tryCatch(

        # second 'tryCatch' if error caused by a timeout
        tryCatch(
            withTimeout(
                    Sys.sleep(vec[i]),
                    timeout=5,
                    onTimeout="error"
            ),
            TimeoutException = function(ex) cat("Timeout. Skipping.\n")
        ),
        error=function(e){cat(conditionMessage(e), "\n")}
    )
}

编辑

如评论中所述,此solution不适用于我的示例。

for(i in 1:length(vec)){
+     tryCatch(
+         expr = {
+             withTimeout({Sys.sleep(vec[i]); cat(". Sleeping ", vec[i], " seconds\n")},
+                          timeout = 5)
+             },
+         TimeoutException = function(ex) cat("Timeout. Skipping.\n")
+     )
+ }

它输出:

. Sleeping  2  seconds
Timeout. Skipping.          # this message shows up after 12 seconds anyway (I am trying to stop it after timeout = 5s here)
. Sleeping  3  seconds

编辑2

我的涉及Sys.sleep函数的示例不适用于withTimeout

摘自R.Utils手册:

  

(*)请注意,在Unix和macOS上,Sys.sleep(time)将发出超时通知   无论经过超时限制(<   时间)。

再举一个例子,下面的评论中提到的SO帖子实际上是有效的。

library(R.utils)

vec <- c(1e+02, 1e+06, 1e+04)

# the second element of the vector takes some time to run
foo <- function(i){
            for(j in 1:i){
                invisible(capture.output(print(j)))
            }
    }

# checking that the second element will take a long time (15 seconds)
system.time(foo(vec[1]))
#  user  system elapsed
# 0.002   0.001   0.001

system.time(foo(vec[2]))
#   user  system elapsed
# 11.557   3.157  15.543

system.time(foo(vec[3]))
#  user  system elapsed
# 0.109   0.031   0.148

for(k in vec){
    tryCatch(
        {
            system.time(withTimeout(
                {cat("... Processing ", k, " times...\n\n"); invisible(capture.output(foo(k)))},
                timeout = 5
            ))
        }, 
        TimeoutException = function(ex) cat("Timeout. Skipping.\n\n")
    )
}

#... Processing  100  times...
#
#... Processing  1e+06  times...
#
#Timing stopped at: 4.993 0.029 5.022     # it stops at timeout = 5s
#Timeout. Skipping.
#
#... Processing  10000  times...

0 个答案:

没有答案