Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop a function in R that is taking too long and give it an alternative?

Tags:

I'm trying to do a thing "the right way". Sometimes "the right way" takes too long, depending on the inputs. I can't really know a priori when this will be. When "the right way" is taking too long, I want to go to "the hackish way". How do I make R monitor how long a particular task as taken, and give it something else to do if a threshold has passed? I'd imagine that this will be part of the try family, but I'm not quite sure what to call it or google for.

Dummy example below. When slow.func takes too long, I want interuptor to stop it and call fast.func instead.

slow.func <- function(x){     Sys.sleep(x)         print('good morning') }  fast.func <- function(x){     Sys.sleep(x/10)      print('hit snooze') }  interuptor = function(FUN,args, time.limit, ALTFUN){ #   START MONITORING TIME HERE     do.call(FUN,args) #   IF FUN TAKES TOO LONG, STOP IT, CALL A     do.call(ALTFUN,args) }  interuptor(slow.func, list(x = 2), time.limit = 1, fast.func) 
like image 694
generic_user Avatar asked Dec 18 '15 00:12

generic_user


People also ask

How do I stop a function running in R?

The shortcut to interrupt a running process in R depends on the R software and the operating system you are using. However, if you are using RStudio on a Windows computer, you can usually use Esc to stop a currently executing R script. Then, we can press Esc to interrupt the loop.

How do you make a function faster?

24.4 Doing as little as possible. The easiest way to make a function faster is to let it do less work. One way to do that is use a function tailored to a more specific type of input or output, or to a more specific problem.


1 Answers

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) 
like image 83
nwknoblauch Avatar answered Sep 22 '22 03:09

nwknoblauch