R - Set execution time limit in loop
The function evalWithTimeout
of package R.utils
does this.
evalWithTimeout(Sys.sleep(10), timeout = 1)
(times are in seconds).
Note: I have not used this function a lot, I liked your question so I did some googling around and found this.
Limiting the time that a function processes in an R for loop
withTimeout()
from package R.utils
, in concert with tryCatch()
, might provide a cleaner solution.
For example:
require(R.utils)
for(i in 1:5) {
tryCatch(
expr = {
withTimeout({Sys.sleep(i); cat(i, "\n")},
timeout = 3.1)
},
TimeoutException = function(ex) cat("Timeout. Skipping.\n")
)
}
# 1
# 2
# 3
# Timeout. Skipping.
# Timeout. Skipping.
In the artificial example above:
The first argument to
withTimeout()
contains the code to be evaluated within each loop.The
timeout
argument towithTimeout()
sets the time limit in seconds.The
TimeoutException
argument totryCatch()
takes a function that is to be executed when an iteration of the loop is timed out.
How to re-run a piece of code if it hangs for more than x seconds?
One possible implementation:
run <- function(x,timeout) {
res <- tryCatch(R.utils::withTimeout(square_slowly(x),timeout=timeout),error=function(cond) NULL)
if (is.null(res)) res <- Recall(x,timeout)
return(res)
}
run(3,timeout = 5)
it took 4 seconds
[1] 9
Or in functional form:
run <- function(.f,...,timeout,trial=1) {
cat('run',trial,'\n')
res <- tryCatch(R.utils::withTimeout(do.call(.f,list(...)),timeout=timeout),error=function(cond) NULL)
if (is.null(res)) res <- Recall(.f=.f,unlist(list(...)),timeout=timeout,trial = trial + 1)
return(res)
}
run(square_slowly,3,timeout = 5)
run 1
run 2
run 3
run 4
run 5
run 6
it took 4 seconds
[1] 9
Skipping slow tasks in a loop in R
Using https://www.rdocumentation.org/packages/R.utils/versions/2.5.0/topics/withTimeout as a source. Here's a test unit that works as expected.
foo = function() {
print("Tic");
x <- ceiling(runif(1) * 100)+1;
for (kk in 1:x) {
print(kk);
Sys.sleep(runif(1));
}
print("Tac");
}
bar = function() {
for (i in 1:100) {
tryCatch({
res <- withTimeout({
foo();
}, timeout=1.08);
}, TimeoutException=function(ex) {
cat("Timeout. Skipping.\n");
});
print(i);
}
}
So the question is, is there an error that is thrown by interrupting by sim.rateshift.taxa that is not being caught, use error
as thc mentions in order to catch that but use the TimeoutException to skip over proper timeouts
There is also a problem with setting too low a time limit:
https://github.com/mhahsler/arules/issues/22
You may want to simply use setTimeLimit
yourself and ensure that transient
is set to TRUE that way you have finer control.
Here's an example taken from http://blog.revolutionanalytics.com/2014/10/r-in-production-controlling-runtime.html
system.time(Sys.sleep(5))
##user system elapsed
## 0.000 0.000 5.005
system.time(local({
setTimeLimit(elapsed = 1, transient = TRUE)
Sys.sleep(5)
}))
## Error in Sys.sleep(5): reached elapsed time limit
## Timing stopped at: 0 0 5.006
Related Topics
How to Make Shinyapp to Use Environmental Variables When Deployed on the Web
How to Put a Complicated Equation into a R Formula
From [Package] Import [Function] in R
R: Ggplot2: Adding Count Labels to Histogram with Density Overlay
Predict.Svm Does Not Predict New Data
Specify Function Parameters in Do.Call
Caret: There Were Missing Values in Resampled Performance Measures
How to Search for a String in One Column in Other Columns of a Data Frame
How to Set the Latex Path for Sweave in R
Calculating Standard Deviation Across Rows
Use of .By and .Eachi in the Data.Table Package
Running an R Script Using a Windows Shortcut
How to Get the First 10 Words in a String in R
Adding All Elements of Two Lists
Aggregating Values on a Data Tree with R
Mutating Dummy Variables in Dplyr