1

In R, I am looping over a vector of objects and apply the same commands at each iteration. How to (i) stop an iteration that takes too long, (ii) print a error/warning message and (iii) go ahead with the next iteration?

For instance, let's say that I have a vector containing 3 time periods and I make R sleeps for these periods, applying a time limit of 5 seconds. If a for loop iteration takes more than 5 seconds (second one of the vector here), it should stop at (around) 5 seconds and keeps going.

My problem with the below codes is that, if an iteration takes too long, R does not stop, but only prints the error message once the iteration is finished and not straight at the time limit.

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")}
    )
}

EDIT

As mentionned in the comments, this solution does not work neither with my example.

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")
+     )
+ }

It outputs:

. 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

EDIT 2

My example involving the Sys.sleep function does not work with withTimeout.

From R.Utils manual:

(*) Note that on Unix and macOS, Sys.sleep(time) will signal a timeout error only after time seconds passed, regardless of timeout limit (< time).

Taking another example, the SO post mentioned in the comments below actually works.

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...
user31888
  • 421
  • 6
  • 13
  • 1
    Possible duplicate of [Limiting the time that a function processes in an R for loop](https://stackoverflow.com/questions/8652681/limiting-the-time-that-a-function-processes-in-an-r-for-loop) – krads Mar 27 '19 at 10:13
  • @ krads: tried that solution. Same problem. – user31888 Mar 27 '19 at 11:25
  • I see you have updated your question to say that the solution in the suggested duplicate question does not work either. That's good but just to better help diagnose your problem please can you detail the exact result or error you encounter when you run the code suggested in [the solution to the other SO question](https://stackoverflow.com/a/8653049/10312356)? Asking because that solution runs for me to give output matching their sample output. If you can tell us what you see when your run the code in that solution it may help us narrow down what's happening for you. Thanks! – krads Mar 27 '19 at 13:29
  • Apologies. Post edited. – user31888 Mar 27 '19 at 19:00
  • @krads: the post you mentioned works. See my edit. Thanks ! – user31888 Mar 28 '19 at 17:53

0 Answers0