Rでキーを押すのを待つ方法は?


回答:


126

誰かがすでにコメントに書いているので、以前に猫を使う必要はありませんreadline()。単に書く:

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

それを変数に割り当てたくない場合、およびコンソールに戻り値を出力したくない場合は、をでラップreadline()しますinvisible()

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

これがここでの最良の答えだと思います。
レオ・レオポルド・ヘルツ준 영

1
それにもう1つの機能を追加するのはどうですか?press esc keep to exit loop
I_m_LeMarque 2018年

4
@nnnこれは、rstudioでスクリプトを実行した場合は機能しません。非インタラクティブセッションでこれを行う方法
PascalIv 2018

78

方法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を使用する環境でテストされています。Revolution R v6.1を搭載したWindows 7 x64で動作します。RStudioでは機能しません(win.graphを使用しないため)。

ここに画像の説明を入力してください


6
方法1は、へのprompt引数を使用して短縮できますreadline。メソッド2はwhat=""、への呼び出しに追加された場合、任意の入力(数値だけでなく)で機能しscanます。 getGraphicsEvent特定のプラットフォームの特定のグラフィックスデバイスでのみ機能します(ただし、これらのデバイスのいずれかを使用している場合は正常に機能します)。
グレッグスノー

2
あなたがループ内で、この関数(方法1)を使用して、ループを停止したい場合は、例えば、次のとおりですif(line == "Q") stop()
ドリアン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をサポートするすべてのプラットフォームで動作し(これはすべて一般的なものだと思います)、任意のキー入力(Enterキーだけでなく)に応答し、スクリプトがバッチモードで実行されている場合でも動作します(ただし、バッチモードでは一時停止します) 、そのため、続行する必要がない場合は、永久に待機します)。タイマーを追加して、クリックされなかったり、キーが押されなかったりした場合に、一定時間後にタイマーを継続させることができます。

どのキーが押されたかは返しません(変更することもできます)。


それは素晴らしいです。しかし、単なる警告です。何らかの理由でRStudio-Server webclientで実行されません(Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel".
milia

2
@milia、そうです。tcltkに基づくコードはローカルマシンで実行する必要があり、RStudio-Serverでは実行されません。
グレッグスノー

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
驚くばかり!これで問題はほぼ解決します。それでも、コンソールがテキスト+ Returnを待たずに、最初のキーを押した場合は反応するのがよいでしょう(「続行するには任意のキーを押してください」など)。
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 2018年

2
これはRを壊し、私はセッションを終了しなければなり
ませんでした

1
対話モードでは、これによりRが壊れ、セッションを終了する必要があります。エントリに警告を追加してください。その場合、反対票を削除します。
HoneyBuddha

Windowsで期待どおりに動作しました!。承認されたソリューション(上記)はスキップされ、一時停止しませんでした。これは実際に一時停止し、Enterキーを押すのを待っていました。
マット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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.