¿Cómo esperar una pulsación de tecla en R?


Respuestas:


127

Como alguien ya escribió en un comentario, no tienes que usar el gato antes readline(). Simplemente escribe:

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

Si no desea asignarlo a una variable y no desea que se imprima una declaración en la consola, envuélvala readline()en un invisible():

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

Creo que esta es la mejor respuesta aquí.
Léo Léopold Hertz 준영

1
¿Qué tal si le agregamos una característica más? press esc keep to exit loop?
I_m_LeMarque

44
@nnn esto no funciona si ejecuto un script en rstudio, por ejemplo, print ("hola") readline ("Presione una tecla para continuar") print ("ho") Probablemente sea porque la sesión no es interactiva. ¿Cómo hacer esto en una sesión no interactiva?
PascalIv

79

Método 1

Espera hasta que presiones [enter] en la consola:

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

Envolviendo en una función:

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

Esta función es el mejor equivalente de Console.ReadKey()en C #.

Método 2

Haga una pausa hasta que escriba la pulsación de tecla [enter] en el teclado. La desventaja de este método es que si escribe algo que no es un número, mostrará un error.

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

Envolviendo en una función:

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

Método 3

Imagine que desea esperar una pulsación de tecla antes de trazar otro punto en un gráfico. En este caso, podemos usar getGraphicsEvent () para esperar una pulsación de tecla dentro de un gráfico.

Este programa de muestra ilustra el concepto:

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

Aquí puede ver el gráfico, con la mitad de sus puntos coloreados, esperando la próxima pulsación del teclado.

Compatibilidad: probado en entornos con win.graph o X11 . Funciona con Windows 7 x64 con Revolution R v6.1. No funciona bajo RStudio (ya que no usa win.graph).

ingrese la descripción de la imagen aquí


66
El método 1 podría acortarse usando el promptargumento to readline. El método 2 funcionaría con cualquier entrada (no solo números) si what=""se agregaran a la llamada a scan. getGraphicsEventsolo funciona en dispositivos gráficos específicos en ciertas plataformas (pero si está utilizando uno de esos dispositivos, funciona bien).
Greg Snow

2
Si está utilizando esta función (Método 1) en un bucle y desea detener el bucle, incluya, por ejemplo:if(line == "Q") stop()
Dorian Grv

18

Aquí hay una pequeña función (usando el paquete tcltk) que abrirá una pequeña ventana y esperará hasta que haga clic en el botón Continuar o presione cualquier tecla (mientras la pequeña ventana todavía tiene el foco), luego permitirá que su script continúe.

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

Simplemente coloque mywait()su script en cualquier lugar donde desee que el script se detenga.

Esto funciona en cualquier plataforma que admita tcltk (que creo que son todas las comunes), responderá a cualquier pulsación de tecla (no solo enter), e incluso funciona cuando el script se ejecuta en modo por lotes (pero aún se detiene en modo por lotes , así que si no estás allí para continuar, esperará para siempre). Se podría agregar un temporizador para que continúe después de un período de tiempo establecido si no se hace clic o se presiona una tecla.

No devuelve qué tecla se presionó (pero podría modificarse para hacerlo).


Es impresionante. Pero solo una advertencia, no se ejecutará en el cliente web RStudio-Server, por alguna razón ( Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel". )
milia

2
@milia, eso es correcto. El código basado en tcltk debe ejecutarse en la máquina local y no se ejecutará en RStudio-Server.
Greg Snow

14

R y Rscript se envían ''a readline y se escanean en modo no interactivo (ver ? readline). La solución es forzar el stdinuso del escaneo.

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

Ejemplo:

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

2
¡Increíble! Esto casi resuelve mi problema . Aún así, sería bueno que la consola no estuviera esperando texto + Retorno, sino que reaccionara a la primera pulsación de tecla (como en "Presione cualquier tecla para continuar").
Vorac

3

Esta respuesta es similar a la de Simon , pero no requiere una entrada adicional que no sea una nueva línea.

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

Utilizando en nlines=1lugar de n=1, el usuario puede simplemente presionar enter para continuar el Rscript.


+1 esta es la única respuesta que realmente funciona según lo deseado para mí. Interior Rscript: hace una pausa y solo requiere golpear Enterpara continuar.
arielf

2
esto rompió R y tuve que terminar la sesión
blobbymatt

1
en modo interactivo, esto rompe R y requiere terminar la sesión. Agregue advertencia en su entrada, en cuyo caso, eliminaré el voto negativo.
HoneyBuddha

¡Funcionó para mí como se esperaba en Windows !. La solución aceptada (arriba) se omitió y no se detuvo. Este en realidad se detuvo y esperó a que presionase enter.
Matt D

0

Una forma de hacerlo (un poco, debes presionar un botón en lugar de una tecla, pero lo suficientemente cerca) es usar el brillo:

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

Según mi experiencia, esto tiene una característica única: incluso si ejecutó un script que tenía un código escrito después de la runAppfunción, no se ejecutará hasta que haya presionado el botón en la aplicación (botón que detiene el uso interno de las aplicaciones stopApp).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.