如何在 R 中等待按键?

我想暂停我的 R 脚本,直到用户按下一个键。

我该怎么做?

107732 次浏览

方法1

直到您在控制台中按下[回车] :

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

函数的包装:

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

这个函数是 C # 中 Console.ReadKey()的最佳等价物。

方法2

在键盘上键入[输入]按键之前暂停。这种方法的缺点是,如果您键入的内容不是数字,它将显示一个错误。

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

下面是一个小函数(使用 tcltk 包) ,它会打开一个小窗口,然后等到您单击“继续”按钮或按下任何键(当小窗口仍然有焦点时) ,然后它会让您的脚本继续。

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()放在脚本中任何您希望脚本暂停的位置。

这适用于任何支持 tcltk 的平台(我认为这是所有常见的平台) ,可以响应任何按键(不仅仅是输入) ,甚至在脚本以批处理模式运行时也可以工作(但它仍然以批处理模式暂停,所以如果你不在那里继续它将永远等待)。可以添加一个计时器,使其在设定的时间后继续,如果没有单击或按下一个键。

它不会返回按了哪个键(但是可以为此进行修改)。

正如有人已经在评论中写道,你不必在 readline()之前使用猫。只需写:

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

如果你不想把它赋值给一个变量,也不想在控制台中打印一个返回值,那么把 readline()包装成一个 invisible():

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

R 和 Rscript 都将 ''发送到 readline,并在非交互模式下进行扫描(参见 ? readline)。解决方案是使用扫描强制 stdin

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

例如:

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

这个答案类似于 西蒙,但是除了换行符之外不需要额外的输入。

cat("Press Enter to continue...")
invisible(scan("stdin", character(), nlines = 1, quiet = TRUE))

使用 nlines=1而不是 n=1,用户可以简单地按回车键继续执行 Rscript。

这样做的一个方法(有点,你必须按一个按钮而不是一个键,但是足够近)是使用闪亮:

library(shiny)


ui     <- fluidPage(actionButton("button", "Press the button"))
server <- function(input, output) {observeEvent(input$button, {stopApp()})}


runApp(shinyApp(ui = ui, server = server))


print("He waited for you to press the button in order to print this")


根据我的经验,这有一个独特的特点: 即使你运行的脚本有代码写在 runApp函数之后,它也不会运行,直到你按下应用程序中的按钮(按钮使用 stopApp阻止应用程序从内部)。

keypress中的函数 keypress()立即读取一个按键,即 不用按回车键

但是,它只能在 Unix/OSX 终端或 Windows 命令行中工作。它不能在 Rstudio、 Windows r GUI、 emacs shell 缓冲区等工作。