Come attendere la pressione di un tasto in R?


Risposte:


127

Come qualcuno ha già scritto in un commento, non è necessario utilizzare prima il gatto readline(). Scrivi semplicemente:

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

Se non si desidera assegnarlo a una variabile e non si desidera stampare un ritorno nella console, avvolgere readline()in un invisible():

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

Penso che questa sia la migliore risposta qui.
Léo Léopold Hertz

1
che ne dici di aggiungere un'altra funzionalità ad esso? press esc keep to exit loop?
I_m_LeMarque

4
@nnn questo non funziona se eseguo uno script in rstudio es. print ("hi") readline ("Premi un tasto per continuare") print ("ho") Probabilmente perché la sessione non è interattiva. Come farlo in una sessione non interattiva?
PascalIv,

79

Metodo 1

Attende finché non si preme [invio] nella console:

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

Avvolgimento in una funzione:

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

Questa funzione è il miglior equivalente di Console.ReadKey()in C #.

Metodo 2

Metti in pausa fino a quando non digiti il ​​tasto [invio] sulla tastiera. Lo svantaggio di questo metodo è che se si digita qualcosa che non è un numero, verrà visualizzato un errore.

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

Avvolgimento in una funzione:

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

Metodo 3

Immagina di voler aspettare la pressione di un tasto prima di tracciare un altro punto su un grafico. In questo caso, possiamo usare getGraphicsEvent () per attendere la pressione di un tasto all'interno di un grafico.

Questo programma di esempio illustra il concetto:

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

Qui puoi vedere il grafico, con la metà dei suoi punti colorati, in attesa del prossimo tasto sulla tastiera.

Compatibilità: testato in ambienti utilizzare win.graph o X11 . Funziona con Windows 7 x64 con Revolution R v6.1. Non funziona con RStudio (in quanto non utilizza win.graph).

inserisci qui la descrizione dell'immagine


6
Il metodo 1 può essere abbreviato usando l' promptargomento a readline. Il metodo 2 funzionerebbe con qualsiasi input (non solo numeri) se what=""fosse aggiunto alla chiamata scan. getGraphicsEventFunziona solo su dispositivi grafici specifici su determinate piattaforme (ma se stai usando uno di quei dispositivi funziona benissimo).
Greg Snow

2
Se si utilizza questa funzione (metodo 1) in un ciclo e si desidera interrompere il ciclo, includere ad esempio:if(line == "Q") stop()
Dorian Grv

18

Ecco una piccola funzione (usando il pacchetto tcltk) che aprirà una piccola finestra e aspetterà di fare clic sul pulsante continua o premere un tasto qualsiasi (mentre la piccola finestra ha ancora lo stato attivo), quindi farà continuare lo script.

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

Basta mettere mywait()nel vostro ovunque script che si desidera lo script per mettere in pausa.

Funziona su qualsiasi piattaforma che supporti tcltk (che penso siano tutti quelli comuni), risponderà a qualsiasi pressione dei tasti (non solo invio) e funziona anche quando lo script viene eseguito in modalità batch (ma si ferma ancora in modalità batch , quindi se non sei lì per continuare, aspetterà per sempre). È possibile aggiungere un timer per farlo continuare dopo un determinato periodo di tempo se non si fa clic o si preme un tasto.

Non restituisce quale tasto è stato premuto (ma potrebbe essere modificato per farlo).


È meraviglioso. Ma solo un avvertimento, non funzionerà sul client web RStudio-Server, per qualche motivo ( Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel". )
milia

2
@milia, è corretto. Il codice basato su tcltk deve essere eseguito sul computer locale e non verrà eseguito su RStudio-Server.
Greg Snow,

14

R e Rscript inviano entrambi ''a readline ed eseguono la scansione in modalità non interattiva (vedi ? readline). La soluzione è forzare l' stdinutilizzo della scansione.

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

Esempio:

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

2
Eccezionale! Questo quasi risolve il mio problema . Sarebbe comunque bello se la console non stesse aspettando il testo + Return, ma piuttosto reagisse al primo tasto premuto (come in "Premere un tasto qualsiasi per continuare").
Vorac,

3

Questa risposta è simile a quella di Simon , ma non richiede input extra oltre a una nuova riga.

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

Utilizzando nlines=1invece di n=1, l'utente può semplicemente premere Invio per continuare Rscript.


+1 questa è l'unica risposta che funziona davvero come desiderato per me. All'interno Rscript: fa una pausa e richiede solo di colpire Enterper continuare.
Ari

2
questo ha rotto R e ho dovuto chiudere la sessione
Blobbymatt il

1
in modalità interattiva, questo interrompe R e richiede di terminare la sessione. Si prega di aggiungere un avviso sulla voce, in tal caso, rimuoverò il downvote.
HoneyBuddha,

Ha funzionato per me come previsto su Windows !. La soluzione accettata (sopra) è stata ignorata e non è stata messa in pausa. Questo in realtà si fermò e attese che io premessi Invio.
Matt D,

0

Un modo per farlo (un po ', devi premere un pulsante anziché un tasto, ma abbastanza vicino) è usare lucido:

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

Per la mia esperienza, questo ha una caratteristica unica: anche se hai eseguito uno script con codice scritto seguendo la runAppfunzione, non verrà eseguito fino a quando non avrai premuto il pulsante nell'app (pulsante che interrompe l'utilizzo delle app dall'interno stopApp).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.