Как выполнять функцию каждую секунду
Я хочу запустить функцию, для выполнения которой требуется менее одной секунды. Я хочу запускать его в цикле каждую секунду. Я не хочу ждать одну секунду между запуском функции, как Sys.sleep
.
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
}
Я мог записать a starttime <- Sys.time()
и выполнить сравнение каждой итерации через цикл, что-то вроде этого...
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()))
}
}
Но моя функция никогда не выполняется.
Я знаю, что у python есть пакет для такого рода вещей. У R тоже есть тот, о котором я не знаю? Спасибо.
Ответы
Ответ 1
Вы можете отслеживать время с помощью 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
}
Вы также можете использовать proc.time
напрямую (какие вызовы system.time), которые по некоторым причинам получили лучшие результаты для меня:
> 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
Ответ 2
Вот несколько альтернатив. Эти не блокируют. То есть вы все еще можете использовать консоль для запуска другого кода во время их работы.
1) Попробуйте tcltk after
в пакете 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()
Запуск этого на свежем сеансе R дает:
after#0
after#1
after#2
after#3
after#4
after#5
after#6
after#7
...etc...
Чтобы остановить это tcl("after", "cancel",.id)
.
2) tcltk2 Другая возможность - это tclTaskSchedule
в пакете tcltk2:
library(tcltk2)
test <- function() cat("Hello\n") # replace with your function
tclTaskSchedule(1000, test(), id = "test", redo = TRUE)
Остановите это с помощью:
tclTaskDelete("test")
или redo=
может указать, сколько раз он должен работать.
Ответ 3
Пакет shiny
имеет функцию invalidateLater()
, которая может использоваться для запуска функций. Посмотрите http://shiny.rstudio.com/gallery/timer.html
Ответ 4
Хотя уже очень поздно.
В качестве альтернативы мы можем использовать рекурсию. Я не знаю, если это решение, которое вы ищете. Но он выполняет функцию через регулярные промежутки времени.
ssc <- function(){
x <- rnorm(30,20,2)
print(hist(x))
Sys.sleep(4)
ssc()
}
ssc()
Ответ 5
Еще одна неблокирующая альтернатива, о которой стоит упомянуть, предоставляется библиотекой (позже) с использованием рекурсива later()
:
print_time = function(interval = 10) {
timestamp()
later::later(print_time, interval)
}
print_time()
Пример взят здесь.