我如何每秒运行一个函数

cor*_*ory 10 r

我想运行一个执行时间不到一秒的函数.我想每秒循环运行它.我不想像运行那样在运行函数之间等待一秒钟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
}
Run Code Online (Sandbox Code Playgroud)

我可以记录一个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()))
  }
}
Run Code Online (Sandbox Code Playgroud)

但我的功能似乎永远不会被执行.

我知道python有一个包来做这种事情.R还有一个我不知道的吗?谢谢.

Señ*_*r O 11

你可以跟踪时间 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
}
Run Code Online (Sandbox Code Playgroud)

你也可以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
Run Code Online (Sandbox Code Playgroud)


G. *_*eck 10

以下是一些替代方案:

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()
Run Code Online (Sandbox Code Playgroud)

在新的R会话上运行它会给出:

after#0 
after#1 
after#2 
after#3 
after#4 
after#5 
after#6 
after#7 
...etc...
Run Code Online (Sandbox Code Playgroud)

阻止它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)
Run Code Online (Sandbox Code Playgroud)

停止它:

tclTaskDelete("test")
Run Code Online (Sandbox Code Playgroud)

或者redo=可以指定它应该运行的次数.