2016-03-18 35 views
7

Voglio eseguire una funzione che richiede meno di un secondo per l'esecuzione. Voglio eseguirlo in un ciclo ogni secondo. Non voglio aspettare un secondo tra l'esecuzione della funzione come farebbe Sys.sleep.Come si esegue una funzione ogni secondo

while(TRUE){ 
    # my function that takes less than a second to run 
    Sys.sleep(runif(1, min=0, max=.8)) 

    # wait for the remaining time until the next execution... 
    # something here 
} 

ho potuto registrare un starttime <- Sys.time() e fare un confronto ogni iterazione del ciclo, qualcosa di simile ...

starttime <- Sys.time() 
while(TRUE){ 
    if(abs(as.numeric(Sys.time() - starttime) %% 1) < .001){ 
    # my function that takes less than a second to run 
    Sys.sleep(runif(1, min=0, max=.8)) 
    print(paste("it ran", Sys.time())) 
    } 
} 

Ma la mia funzione non sembra mai essere eseguito.

So che Python ha un pacchetto per fare questo genere di cose. R ha anche uno che non conosco? Grazie.

+0

Immagino che il problema sia che c'è una possibilità di 1/1000 di essere al momento giusto in ogni iterazione. Dovrebbe comunque essere eseguito alla fine, anche se non riesco a farlo ... – Frank

+4

Sembra che tu voglia un processo cron in R. A seconda delle specifiche, potrebbe essere meglio farlo con i soliti strumenti da riga di comando. – Roland

+2

Per @ il commento di Roland, assicuriamoci di non avere un [problema XY] (http://meta.stackexchange.com/q/66377). – JasonAizkalns

risposta

9

È possibile tenere traccia del tempo con system.time

while(TRUE) 
{ 
    s = system.time(Sys.sleep(runif(1, min = 0, max = 0.8))) 
    Sys.sleep(1 - s[3]) #basically sleep for whatever is left of the second 
} 

È inoltre possibile utilizzare direttamente proc.time (che system.time chiamate), che per qualche motivo ha ottenuto risultati migliori per me:

> system.time(
    for(i in 1:10) 
    { 
    p1 = proc.time() 
    Sys.sleep(runif(1, min = 0, max = 0.8)) 
    p2 = proc.time() - p1 
    Sys.sleep(1 - p2[3]) #basically sleep for whatever is left of the second 
    }) 
    user system elapsed 
    0.00 0.00 10.02 
+0

Qualsiasi tipo di sovraccarico fatto da ' system.time' o il ciclo 'while' lo eliminerà, quindi sarà leggermente più di un secondo. Potresti fare il lavoro per compensare ciò, se vuoi. –

7

Ecco alcune alternative:

1) tcltk Prova after nel pacchetto tcltk:

library(tcltk) 

run <- function() { 
    .id <<- tcl("after", 1000, run) # after 1000 ms execute run() again 
    cat(as.character(.id), "\n") # replace with your code 
} 

run() 

L'esecuzione di questo su una sessione di R fresca dà:

after#0 
after#1 
after#2 
after#3 
after#4 
after#5 
after#6 
after#7 
...etc... 

Per fermarlo tcl("after", "cancel", .id).

2) tcltk2 Un'altra possibilità è tclTaskSchedule nel pacchetto tcltk2:

library(tcltk2) 

test <- function() cat("Hello\n") # replace with your function 
tclTaskSchedule(1000, test(), id = "test", redo = TRUE) 

fermarlo con:

tclTaskDelete("test") 

o redo= possibile specificare il numero di volte che deve essere eseguito.

Problemi correlati