如何等待R中的按键?


Answers:


127

正如某人已经在评论中写道的那样,您不必在之前使用过这只猫readline()。只需写:

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

如果您不想将其分配给变量并且不希望在控制台中显示返回值,则将换成readline()一个invisible()

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

我认为这是最好的答案。
莱奥波德·赫兹(LéoLéopoldHertz),2017年

1
如何为其添加一个功能?press esc keep to exit loop
I_m_LeMarque

4
@nnn如果我在rstudio中运行脚本,例如print(“ hi”)readline(“ Press a key to continue”“)print(” ho“),则此方法不起作用,可能是因为该会话不是交互式的。如何在非交互式会话中执行此操作?
PascalIv

79

方法一

等待直到您在控制台中按[enter]:

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

包装成一个函数:

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

此功能与Console.ReadKey()C#中的功能等效。

方法二

暂停直到您在键盘上键入[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)。

在此处输入图片说明


6
方法1可以通过使用prompt参数来缩短readline。如果将方法2 what=""添加到对的调用中,则它可以使用任何输入(不仅是数字)scangetGraphicsEvent仅适用于某些平台上的特定图形设备(但是,如果您使用这些设备之一,则可以正常工作)。
格雷格·斯诺

2
如果要在循环中使用此函数(方法1)并要停止循环,请包括例如:if(line == "Q") stop()
Dorian Grv

18

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

它不会返回按下了哪个键(但可以对其进行修改)。


这很棒。但只是警告,由于某种原因,它不能在RStudio服务器Web客户端上运行(Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel".
milia

2
@milia,没错。基于tcltk的代码需要在本地计算机上运行,​​而不能在RStudio服务器上运行。
格雷格·斯诺

14

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

2
太棒了!这几乎解决了我的问题。如果控制台不等待文本+回车,而是对第一次按键做出反应(如“按任意键继续”中所示),那还是不错的。
Vorac

3

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

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

使用nlines=1代替n=1,用户只需按Enter即可继续执行Rscript。


+1这是对我真正有效的唯一答案。内部Rscript:暂停,只需要点击Enter即可继续。
arielf

2
这打破了R,我不得不终止会议
blobbymatt 19'Apr

1
在交互模式下,这会中断R并要求终止会话。请在您的输入内容上添加警告,在这种情况下,我将删除下注。
HoneyBuddha

在Windows上按预期为我工作!接受的解决方案(上述)被跳过并且没有暂停。这个人实际上停了下来,等我按下回车键。
马特D

0

一种方法(有点,您必须按下按钮而不是按键,但要足够接近)是使用闪亮的:

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)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.