【发布时间】:2013-02-22 18:04:39
【问题描述】:
我想暂停我的 R 脚本,直到用户按下一个键。
我该怎么做?
【问题讨论】:
-
你有没有找到可以接受的答案?
标签: r keypress wait readline readkey
我想暂停我的 R 脚本,直到用户按下一个键。
我该怎么做?
【问题讨论】:
标签: r keypress wait readline readkey
方法一
等到您在控制台中按 [enter]:
cat ("Press [enter] to continue")
line <- readline()
包装成一个函数:
readkey <- function()
{
cat ("Press [enter] to continue")
line <- readline()
}
此函数是 C# 中 Console.ReadKey() 的最佳等效函数。
方法二
暂停,直到您在键盘上键入 [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 的环境下测试。适用于带有 Revolution R v6.1 的 Windows 7 x64。在 RStudio 下不起作用(因为它不使用 win.graph)。
【讨论】:
prompt 参数来缩短 readline。如果将what="" 添加到对scan 的调用中,则方法2 将适用于任何输入(不仅仅是数字)。 getGraphicsEvent 仅适用于某些平台上的特定图形设备(但如果您使用其中一种设备,它可以正常工作)。
if(line == "Q") stop()
这是一个小功能(使用 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 的平台(我认为这是所有常见的平台),将响应任何按键(不仅仅是输入),甚至在脚本以批处理模式运行时也有效(但它仍然暂停在批处理模式下,因此如果您不在那里继续,它将永远等待)。如果没有点击或按下键,可以添加一个计时器,使其在设定的时间后继续。
它不会返回按下了哪个键(但可以修改为这样做)。
【讨论】:
Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel". )
正如有人已经在评论中写道,您不必在readline() 之前使用猫。简单写:
readline(prompt="Press [enter] to continue")
如果您不想将其分配给变量并且不想在控制台中打印返回值,请将 readline() 包装在 invisible() 中:
invisible(readline(prompt="Press [enter] to continue"))
【讨论】:
press esc keep to exit loop ?
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
【讨论】:
这个答案类似于Simon 的答案,但除了换行符之外不需要额外的输入。
cat("Press Enter to continue...")
invisible(scan("stdin", character(), nlines = 1, quiet = TRUE))
使用nlines=1而不是n=1,用户可以简单地按回车继续Rscript。
【讨论】:
Rscript 内部:它会暂停,只需点击Enter 即可继续。
一种方法(有点,你必须按下一个按钮而不是一个键,但足够近)是使用闪亮:
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() 可立即读取单个按键,无需按 Enter 键。
但是,它仅适用于 Unix/OSX 终端或 Windows 命令行。它不适用于 Rstudio、Windows R GUI、emacs shell 缓冲区等。
【讨论】: