Wie warte ich auf einen Tastendruck in R?


Antworten:


126

Wie jemand bereits in einem Kommentar geschrieben hat, müssen Sie die Katze vorher nicht benutzen readline(). Schreiben Sie einfach:

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

Wenn Sie es keiner Variablen zuweisen möchten und keine Rückgabe in der Konsole gedruckt werden soll, schließen Sie das readline()in ein invisible():

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

Ich denke, das ist die beste Antwort hier.
Léo Léopold Hertz 21

1
Wie wäre es mit einem weiteren Feature? press esc keep to exit loop?
I_m_LeMarque

4
@nnn Dies funktioniert nicht, wenn ich ein Skript in rstudio ausführe, z. B. print ("hi") readline ("Drücken Sie eine Taste, um fortzufahren") print ("ho") Dies liegt wahrscheinlich daran, dass die Sitzung nicht interaktiv ist. Wie geht das in einer nicht interaktiven Sitzung?
PascalIv

78

Methode 1

Wartet, bis Sie in der Konsole die Eingabetaste drücken:

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

In eine Funktion einwickeln:

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

Diese Funktion ist das beste Äquivalent zu Console.ReadKey()in C #.

Methode 2

Halten Sie an, bis Sie den Tastendruck [Enter] auf der Tastatur eingeben. Der Nachteil dieser Methode ist, dass ein Fehler angezeigt wird, wenn Sie etwas eingeben, das keine Zahl ist.

print ("Press [enter] to continue")
number <- scan(n=1)

In eine Funktion einwickeln:

readkey <- function()
{
    cat("[press [enter] to continue]")
    number <- scan(n=1)
}

Methode 3

Stellen Sie sich vor, Sie möchten auf einen Tastendruck warten, bevor Sie einen anderen Punkt in einem Diagramm zeichnen. In diesem Fall können wir getGraphicsEvent () verwenden, um auf einen Tastendruck in einem Diagramm zu warten.

Dieses Beispielprogramm veranschaulicht das Konzept:

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]")
}

Hier sehen Sie die Grafik, deren Hälfte farbig ist und auf den nächsten Tastendruck auf der Tastatur wartet.

Kompatibilität: In Umgebungen getestet, verwenden Sie entweder win.graph oder X11 . Funktioniert mit Windows 7 x64 mit Revolution R v6.1. Funktioniert nicht unter RStudio (da win.graph nicht verwendet wird).

Geben Sie hier die Bildbeschreibung ein


6
Methode 1 könnte mit dem promptArgument to verkürzt werden readline. Methode 2 würde mit jeder Eingabe (nicht nur mit Zahlen) funktionieren, wenn what=""sie dem Aufruf von hinzugefügt würde scan. getGraphicsEventFunktioniert nur auf bestimmten Grafikgeräten auf bestimmten Plattformen (aber wenn Sie eines dieser Geräte verwenden, funktioniert es einwandfrei).
Greg Snow

2
Wenn Sie diese Funktion (Methode 1) in einer Schleife verwenden und die Schleife stoppen möchten, schließen Sie zum Beispiel ein:if(line == "Q") stop()
Dorian Grv

18

Hier ist eine kleine Funktion (unter Verwendung des tcltk-Pakets), die ein kleines Fenster öffnet und wartet, bis Sie entweder auf die Schaltfläche "Weiter" klicken oder eine beliebige Taste drücken (während das kleine Fenster noch den Fokus hat). Dann wird Ihr Skript fortgesetzt.

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()Fügen Sie Ihr Skript einfach an einer beliebigen Stelle ein, an der das Skript angehalten werden soll.

Dies funktioniert auf jeder Plattform, die tcltk unterstützt (was meiner Meinung nach alle gängigen sind), auf jeden Tastendruck reagiert (nicht nur die Eingabe) und sogar funktioniert, wenn das Skript im Batch-Modus ausgeführt wird (aber im Batch-Modus immer noch angehalten wird) Wenn Sie also nicht da sind, um fortzufahren, wird es ewig warten. Ein Timer kann hinzugefügt werden, damit er nach einer festgelegten Zeit fortgesetzt wird, wenn nicht geklickt oder eine Taste gedrückt wird.

Es wird nicht zurückgegeben, welche Taste gedrückt wurde (dies kann jedoch geändert werden).


Es ist toll. Aber nur eine Warnung, es wird aus irgendeinem Grund nicht auf RStudio-Server-Webclient ausgeführt ( Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel". )
Milia

2
@milia, das ist richtig. Code, der auf tcltk basiert, muss auf dem lokalen Computer ausgeführt werden und wird nicht auf RStudio-Server ausgeführt.
Greg Snow

14

R und Rscript senden beide ''an readline und scannen im nicht interaktiven Modus (siehe ? readline). Die Lösung besteht darin, die stdinVerwendung des Scans zu erzwingen .

cat('Solution to everything? > ')
b <- scan("stdin", character(), n=1)

Beispiel:

$ Rscript t.R 
Solution to everything? > 42
Read 1 item

2
Genial! Dies löst fast mein Problem . Trotzdem wäre es schön, wenn die Konsole nicht auf Text + Return warten würde, sondern auf den ersten Tastendruck reagieren würde (wie unter "Drücken Sie eine beliebige Taste, um fortzufahren").
Vorac

3

Diese Antwort ähnelt der von Simon , erfordert jedoch keine zusätzliche Eingabe außer einer neuen Zeile.

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

Mit nlines=1anstelle von n=1kann der Benutzer einfach die Eingabetaste drücken, um das Rscript fortzusetzen.


+1 Dies ist die einzige Antwort, die für mich tatsächlich wie gewünscht funktioniert. Innen Rscript: Es pausiert und muss nur gedrückt werden, Enterum fortzufahren.
Arielf

2
Dies brach R und ich musste die Sitzung beenden
blobbymatt

1
Im interaktiven Modus wird R unterbrochen und die Sitzung muss beendet werden. Bitte fügen Sie Ihrem Eintrag eine Warnung hinzu. In diesem Fall werde ich die Ablehnung entfernen.
HoneyBuddha

Arbeitete für mich wie erwartet unter Windows!. Die akzeptierte Lösung (oben) wurde übersprungen und pausierte nicht. Dieser hielt tatsächlich inne und wartete darauf, dass ich die Eingabetaste drückte.
Matt D

0

Eine Möglichkeit, dies zu tun (irgendwie muss man eher einen Knopf als eine Taste drücken, aber nah genug), ist die Verwendung von glänzendem:

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

Meiner Erfahrung nach hat dies eine einzigartige Eigenschaft: Selbst wenn Sie ein Skript ausgeführt haben, dessen Code nach der runAppFunktion geschrieben wurde, wird es erst ausgeführt, wenn Sie die Schaltfläche in der App gedrückt haben (Schaltfläche, mit der die Apps von innen nicht mehr verwendet werden stopApp).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.