181

How do you pause an R script for a specified number of seconds or miliseconds? In many languages, there is a sleep function, but ?sleep references a data set. And ?pause and ?wait don't exist.

The intended purpose is for self-timed animations. The desired solution works without asking for user input.

Tomas
  • 57,621
  • 49
  • 238
  • 373
Dan Goldstein
  • 24,229
  • 18
  • 37
  • 41
  • 8
    @Ricardo, we had a whole discussion on this with Joshua and others and we finally agreed that both "pause" and "sleep" should be in the title. The final title was result of a compromise. And you just step in and *without any argument why your title is better* rollback to previous revision? Adding "sleep" to the title makes the question much easier to find, because "sleep" is in many languages and there is a high probability that users will search for it. Current title contains a lot of word balast and the important keyword is missing. *What was the purpose of your rollback?* – Tomas Jul 22 '13 at 05:29
  • Google "r sleep" couldn't find it, tried to fix it. – Tomas Jan 17 '14 at 15:03

3 Answers3

189

See help(Sys.sleep).

For example, from ?Sys.sleep

testit <- function(x)
{
    p1 <- proc.time()
    Sys.sleep(x)
    proc.time() - p1 # The cpu usage should be negligible
}
testit(3.7)

Yielding

> testit(3.7)
   user  system elapsed 
  0.000   0.000   3.704 
Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
19

Sys.sleep() will not work if the CPU usage is very high; as in other critical high priority processes are running (in parallel).

This code worked for me. Here I am printing 1 to 1000 at a 2.5 second interval.

for (i in 1:1000)
{
  print(i)
  date_time<-Sys.time()
  while((as.numeric(Sys.time()) - as.numeric(date_time))<2.5){} #dummy while loop
}
rbtj
  • 331
  • 2
  • 6
  • 1
    the Sys.sleep() function did not work in my use case, and this was the only way I was able to manage producing the necessary delay. – Pake Apr 03 '20 at 20:53
  • This is what is called "busy waiting", and will compete with CPU cycles with other threads and processes: https://en.wikipedia.org/wiki/Busy_waiting, which you should avoid. The answer below from Dirk is the far better solution. – akbertram Dec 21 '22 at 11:50
3

TL;DR sys_sleep a new stable and precise sleep function

We already know that Sys.sleep could work not as expected, e.g. when CPU usage is very high.
That is why I decided to prepare a high quality function powered by microbenchmark::get_nanotime() and while/repeat mechanics.

#' Alternative to Sys.sleep function
#' Expected to be more stable
#' @param val `numeric(1)` value to sleep.
#' @param unit `character(1)` the available units are nanoseconds ("ns"), microseconds ("us"), milliseconds ("ms"), seconds ("s").
#' @note dependency on `microbenchmark` package to reuse `microbenchmark::get_nanotime()`.
#' @examples 
#' # sleep 1 second in different units
#' sys_sleep(1, "s")
#' sys_sleep(100, "ms")
#' sys_sleep(10**6, "us")
#' sys_sleep(10**9, "ns")
#' 
#' sys_sleep(4.5)
#'
sys_sleep <- function(val, unit = c("s", "ms", "us", "ns")) {
  start_time <- microbenchmark::get_nanotime()
  stopifnot(is.numeric(val))
  unit <- match.arg(unit, c("s", "ms", "us", "ns"))
  val_ns <- switch (unit,
    "s" = val * 10**9,
    "ms" = val * 10**7,
    "us" = val * 10**3,
    "ns" = val
  )
  repeat {
    current_time <- microbenchmark::get_nanotime()
    diff_time <- current_time - start_time
    if (diff_time > val_ns) break
  }
}

system.time(sys_sleep(1, "s"))
#>    user  system elapsed 
#>   1.015   0.014   1.030
system.time(sys_sleep(100, "ms"))
#>    user  system elapsed 
#>   0.995   0.002   1.000
system.time(sys_sleep(10**6, "us"))
#>    user  system elapsed 
#>   0.994   0.004   1.000
system.time(sys_sleep(10**9, "ns"))
#>    user  system elapsed 
#>   0.992   0.006   1.000

system.time(sys_sleep(4.5))
#>    user  system elapsed 
#>   4.490   0.008   4.500

Created on 2022-11-21 with reprex v2.0.2

polkas
  • 3,797
  • 1
  • 12
  • 25