2013-03-07 76 views
93

我想暂停我的R脚本,直到用户按下一个键。如何等待R中的按键?

我该怎么做?

+0

你有没有发现,你可以接受任何答案? – 2017-01-21 13:47:24

回答

65

正如有人在评论中写道的,您不必在readline()之前使用猫。简单地写:

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

如果你不想把它分配给一个变量,不希望打印到控制台上一回,包裹在readline()一个invisible()

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

我认为这是这里最好的答案。 – 2017-01-21 13:46:39

68

方法1

等待,直到你按[Enter]在控制台:

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

包装成一个函数:

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

此功能的Console.ReadKey()最好相当于在C#中。

方法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

+5

通过对'readline'使用'prompt'参数可以缩短方法1。方法2可以处理任何输入(不只是数字),如果'what =“”'被添加到'scan'的调用中。 'getGraphicsEvent'只能在某些平台上的特定图形设备上工作(但如果您使用其中一种设备,则工作正常)。 – 2013-03-07 22:36:16

+2

'readline'和'scan'在Linux下的命令行中不起作用 – 2014-02-21 06:08:27

+2

如果您在循环中使用此函数(方法1)并想要停止循环,请包括例如: 'if(line ==“Q “)stop()' – 2017-02-17 13:04:41

17

这里是一个小功能(使用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(我认为都是常见的)的平台,它可以响应任何按键(不仅仅是输入),甚至可以在脚本以批处理模式运行时工作(但它仍然在批处理模式下暂停,所以如果你不在那里继续它将永远等待)。如果未点击或按下按键,则可以添加定时器以在设定的时间量之后继续。

它没有返回哪个键被按下(但可以修改为这样做)。

+0

太棒了。但出于某种原因('结构错误(.External(.C_dotTclObjv,objv),class =“tclObj”)): [tcl]无效的命令名称“toplevel “#) – milia 2016-06-18 10:09:05

+1

@ milia,这是正确的。基于tcltk的代码需要在本地机器上运行,并且不会在RStudio-Server上运行。 – 2016-06-20 17:35:48

11

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 
+0

太棒了!这几乎解决了[我的问题](https://stackoverflow.com/questions/47294283/how-to-run-an-r-script-and-show-a-plot)。如果控制台没有等待文本+返回,而是对第一个按键作出反应(如“按任意键继续”),这仍然会很好。 – Vorac 2017-11-15 14:59:49