Time Out an R Command via Something Like Try()

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



Leave a reply



Submit