How to stop a function in R that is taking too long and give it an alternative?
The R package R.utils
has a function evalWithTimeout
that's pretty much exactly what you're describing. If you don't want to install a package, evalWithTimeout
relies on the less user friendly R base function setTimeLimit
Your code would look something like this:
library(R.utils)
slow.func <- function(x){
Sys.sleep(10)
return(x^2)
}
fast.func <- function(x){
Sys.sleep(2)
return(x*x)
}
interruptor = function(FUN,args, time.limit, ALTFUN){
results <- NULL
results <- evalWithTimeout({FUN(args)},timeout=time.limit,onTimeout="warning")
if(results==NULL){
results <- ALTFUN(args)
}
return(results)
}
interruptor(slow.func,args=2,time.limit=3,fast.func)
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.
How to retry for loop when timeout error occurs: Where to add trycatch or withTimeout
Perhaps I'm missing something, but in the third example, using try()
, you evaluate if(!is(df, 'try-error'))
but a
is the object that stores the results of try()
. So shouldn't it be if(!is(a, 'try-error'))
files <- NULL
#sample.id <- NULL
for(i in 1:length(sample.id.path2[[1]])){
while(TRUE){
a <- try(as.data.frame(system(paste0("mcli ls s3/path/to/bucket/", sample.id.path2[['V2']][i], sep = ""), intern=TRUE)), silent=TRUE)
if(!is(a, 'try-error')) break
colnames(a)[1] <- "V1"
a$V1 <- gsub("^.{0,34}", "", a$V1)
a <- a %>% filter(str_detect(V1, 'fastq'))
}
#print(a)
b <- as.data.frame(paste0("", sample.id.path2[['V2']][i], sep = ""))
colnames(b)[1] <- "V1"
c <- as.data.frame(paste0(b$V1, a$V1, sep = ""))
colnames(c)[1] <- "V2"
d <- cbind(a,c)
print(d)
files <- rbind(files, d)
}
run a function for specified time in R
If you want to run some code for a specified number of seconds, you can try the following :
start <- as.numeric(Sys.time())
duration <- 5
results <- NULL
while(as.numeric(Sys.time())-start < duration) {
results <- c(results, replicate(...))
}
Of course, you have to change the value of duration
(in seconds), and replace replicate(...)
with your code.
Interrupting readline() after a time interval in R
i think you can use fucntion "setTimeLimit" from library base. so...
record.events <- function(duration = 30, first.event = "a"){
# Initial settings
time.start <- proc.time()[3]
events<-first.event
stroke.time<-c(0)
# Timed data collection
while(proc.time()[3] - time.start < duration){
temp <- tryCatch({setTimeLimit(elapsed=(time.start + duration - proc.time()[3]),
transient = TRUE);readline("record events...")},
error = function(e) { return("NULL")})
#you need to set up back this function... (but why i dont know????)
setTimeLimit(elapsed = Inf, transient = TRUE)
events[length(events)+1] <- temp
stroke.time[length(stroke.time)+1]<-round(proc.time()[3],3)
}
# Format recorded data for post-processing
events<-data.frame(events, stroke.time)
return(events)
}
But setTimeLimit inst great for use in user functions.. My results is:
events stroke.time
1 a 0.00
2 s 1539.12
3 s 1539.52
4 ass 1539.96
5 s 1540.49
6 asd 1540.94
7 fed 1541.27
8 NULL 1541.55
For more info see:
https://stackoverflow.com/a/7891479
https://stat.ethz.ch/R-manual/R-devel/library/base/html/setTimeLimit.html
How does setTimeLimit work in R?
setTimeLimit fails to terminate idle call in R
How to refresh or retry a specific web page using httr GET command?
Look at purrr::safely()
. You can wrap GET
as such:
safe_GET <- purrr::safely(GET)
This removes the ugliness of tryCatch()
by letting you do:
resp <- safe_GET("http://example.com") # you can use all legal `GET` params
And you can test resp$result
for NULL
. Put that into your retry loop and you're good to go.
You can see this in action by doing:
str(safe_GET("https://httpbin.org/delay/3", timeout(1)))
which will ask the httpbin service to wait 3s before responding but set an explicit timeout on the GET
request to 1s. I wrapped it in str()
to show the result:
List of 2
$ result: NULL
$ error :List of 2
..$ message: chr "Timeout was reached"
..$ call : language curl::curl_fetch_memory(url, handle = handle)
..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
So, you can even check the message if you need to.
Related Topics
Conditional Coloring of Cells in Table
Variable Name Restrictions in R
Shiny Slider on Logarithmic Scale
Stacked Barplot with Colour Gradients for Each Bar
What Methods How to Use to Reshape Very Large Data Sets
Different Legends and Fill Colours for Facetted Ggplot
Put a Break in the Y-Axis of a Histogram
Cumulative Count of Each Value
Ggplot - Multiple Legends Arrangement
How to Access the Help/Documentation .Rd Source Files in R
Merge Rows in a Dataframe Where the Rows Are Disjoint and Contain Nas
How to Force Specific Order of the Variables on the X Axis
What Is the Meaning of the Dollar Sign "$" in R Function()
Using Stargazer with Rstudio and Knitr
Equivalent to Unix "Less" Command Within R Console