【问题标题】:How to wait for a keypress in R?如何等待R中的按键?
【发布时间】:2013-02-22 18:04:39
【问题描述】:

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

我该怎么做?

【问题讨论】:

  • 你有没有找到可以接受的答案?

标签: r keypress wait readline readkey


【解决方案1】:

方法一

等到您在控制台中按 [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)。

【讨论】:

  • 方法 1 可以通过使用 prompt 参数来缩短 readline。如果将what="" 添加到对scan 的调用中,则方法2 将适用于任何输入(不仅仅是数字)。 getGraphicsEvent 仅适用于某些平台上的特定图形设备(但如果您使用其中一种设备,它可以正常工作)。
  • 如果你在循环中使用这个函数(方法一)并想停止循环,包括例如:if(line == "Q") stop()
【解决方案2】:

这是一个小功能(使用 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-Server 网络客户端上运行(Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel". )
  • @milia,这是正确的。基于tcltk的代码需要在本地机器上运行,不会在RStudio-Server上运行。
【解决方案3】:

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

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

如果您不想将其分配给变量并且不想在控制台中打印返回值,请将 readline() 包装在 invisible() 中:

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

【讨论】:

  • 我认为这是最好的答案。
  • 再增加一项功能怎么样? press esc keep to exit loop ?
  • @nnn 如果我在 rstudio 中运行脚本,这将不起作用,例如print("hi") readline("Press a key to continue") print("ho") 这可能是因为会话不是交互式的。如何在非交互式会话中执行此操作?
【解决方案4】:

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

【讨论】:

  • 太棒了!这几乎解决了my problem。如果控制台不等待文本+返回,而是对第一次按键做出反应(如“按任意键继续”),那还是很好的。
【解决方案5】:

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

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

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

【讨论】:

  • +1 这是唯一真正符合我要求的答案。在Rscript 内部:它会暂停,只需点击Enter 即可继续。
  • 这破坏了 R,我不得不终止会话
  • 在交互模式下,这会破坏 R 并需要终止会话。请在您的条目中添加警告,在这种情况下,我将删除反对票。
  • 在 Windows 上按预期为我工作!。已接受的解决方案(上图)被跳过并且没有暂停。这个居然停了下来等我回车。
【解决方案6】:

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

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

【讨论】:

    【解决方案7】:

    keypress 包中的函数 keypress() 可立即读取单个按键,无需按 Enter 键

    但是,它仅适用于 Unix/OSX 终端或 Windows 命令行。它不适用于 Rstudio、Windows R GUI、emacs shell 缓冲区等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 2020-01-21
      • 2018-10-30
      • 2010-11-02
      • 1970-01-01
      相关资源
      最近更新 更多