2015-12-18 6 views
11

Sto provando a fare una cosa "nel modo giusto". A volte "la strada giusta" richiede troppo tempo, a seconda degli input. Non posso davvero sapere a priori quando sarà questo. Quando "la strada giusta" sta impiegando troppo tempo, voglio andare su "la via hackish". Come posso fare in modo che R monitorizzi per quanto tempo un particolare compito è stato eseguito, e dargli qualcos'altro da fare se è passata una soglia? Immagino che questo farà parte della famiglia try, ma non sono abbastanza sicuro di come chiamarlo o google.Come fermare una funzione in R che impiega troppo tempo e dargli un'alternativa?

Esempio fittizio di seguito. Quando lo slow.func impiega troppo tempo, voglio interuptor per fermarlo e chiamare invece fast.func.

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) 
+0

come aggiungerei un controllo orario? –

+0

sì, sto solo eseguendo R. Non ho imparato alcun C. Sarebbe banale scrivere e compilare un semplice programma in questo caso e chiamarlo con '.C'? –

risposta

7

Il pacchetto R R.utils ha una funzione evalWithTimeout che è più o meno esattamente quello che stai descrivendo. Se non si desidera installare un pacchetto, evalWithTimeout si basa sulla funzione meno user friendly di base R setTimeLimit

il codice sarà simile a questo:

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) 
1

La risposta di "nwknoblauch" non funziona per me a meno che non cambi "avviso" di "silenzioso" all'interno della funzione di interruzione.

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="silent") 
    if(is.null(results)){ 
    results <- ALTFUN(args) 
    } 
    return(results) 
} 
interruptor(FUN = slow.func,args=2,time.limit=3,ALTFUN = fast.func)