Как дождаться нажатия клавиши в R?

Я хочу приостановить свой R script, пока пользователь не нажмет клавишу.

Как это сделать?

Ответ 1

Как уже писал кто-то в комментарии, вам не нужно использовать cat до readline(). Просто напишите:

readline(prompt="Press [enter] to continue")

Если вы не хотите назначать его переменной и не хотите, чтобы в консоли печаталось сообщение, оберните readline() в invisible():

invisible(readline(prompt="Press [enter] to continue"))

Ответ 2

Метод 1

Ожидает, пока вы не нажмете [enter] в консоли:

cat ("Press [enter] to continue")
line <- readline()

Включение в функцию:

readkey <- function()
{
    cat ("Press [enter] to continue")
    line <- readline()
}

Эта функция является лучшим эквивалентом Console.ReadKey() в С#.

Метод 2

Пауза, пока вы не нажмете клавишу [enter] на клавиатуре. Недостатком этого метода является то, что если вы набираете то, что не является числом, оно будет отображать ошибку.

print ("Press [enter] to continue")
number <- scan(n=1)

Включение в функцию:

readkey <- function()
{
    cat("[press [enter] to continue]")
    number <- scan(n=1)
}

Метод 3

Представьте, что вы хотите дождаться нажатия клавиши перед построением другой точки на графике. В этом случае мы можем использовать getGraphicsEvent() для ожидания нажатия клавиши внутри графика.

Эта примерная программа иллюстрирует концепцию:

readkeygraph <- function(prompt)
{
    getGraphicsEvent(prompt = prompt, 
                 onMouseDown = NULL, onMouseMove = NULL,
                 onMouseUp = NULL, onKeybd = onKeybd,
                 consolePrompt = "[click on graph then follow top prompt to continue]")
    Sys.sleep(0.01)
    return(keyPressed)
}

onKeybd <- function(key)
{
    keyPressed <<- key
}

xaxis=c(1:10) # Set up the x-axis.
yaxis=runif(10,min=0,max=1) # Set up the y-axis.
plot(xaxis,yaxis)

for (i in xaxis)
{
    # On each keypress, color the points on the graph in red, one by one.
    points(i,yaxis[i],col="red", pch=19)
    keyPressed = readkeygraph("[press any key to continue]")
}

Здесь вы можете увидеть график, причем половина его точек окрашена, ожидая следующего нажатия клавиши на клавиатуре.

Совместимость. Протестированные в среде используют либо win.graph, либо X11. Работает с Windows 7 x64 с Revolution R v6.1. Не работает в RStudio (поскольку он не использует win.graph).

enter image description here

Ответ 3

Вот небольшая функция (с помощью пакета tcltk), которая откроет небольшое окно и подождет, пока вы не нажмете на кнопку продолжения или не нажмете любую клавишу (в то время как небольшое окно все еще имеет фокус), тогда это позволит script продолжить.

library(tcltk)

mywait <- function() {
    tt <- tktoplevel()
    tkpack( tkbutton(tt, text='Continue', command=function()tkdestroy(tt)),
        side='bottom')
    tkbind(tt,'<Key>', function()tkdestroy(tt) )

    tkwait.window(tt)
}

Просто поместите mywait() в script в любом месте, где вы хотите приостановить script.

Это работает на любой платформе, поддерживающей tcltk (которая, как мне кажется, является общей), будет реагировать на любое нажатие клавиши (а не просто на ввод) и даже работает, когда script запускается в пакетном режиме (но это все еще останавливается в пакетном режиме, поэтому, если вы не хотите его продолжить, он будет ждать всегда). Можно добавить таймер, чтобы он продолжался по истечении заданного промежутка времени, если не был нажат или нажата клавиша.

Он не возвращает какую клавишу нажата (но может быть изменена для этого).

Ответ 4

R и Rscript отправляют '' для чтения и сканирования в неинтерактивном режиме (см. ? readline). Решение состоит в том, чтобы заставить stdin использовать сканирование.

cat('Solution to everything? > ')
b <- scan("stdin", character(), n=1)

Пример:

$ Rscript t.R 
Solution to everything? > 42
Read 1 item