Bagaimana cara menunggu tombol ditekan di R?

142

Saya ingin menghentikan sementara skrip R saya sampai pengguna menekan tombol.

Bagaimana saya melakukan ini?

Contango
sumber
Sudahkah Anda menemukan jawaban yang dapat Anda terima?
Léo Léopold Hertz 준영

Jawaban:

132

Karena seseorang sudah menulis di komentar, Anda tidak harus menggunakan kucing sebelumnya readline(). Cukup tulis:

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

Jika Anda tidak ingin menetapkannya ke variabel dan tidak ingin pengembalian dicetak di konsol, bungkus readline()dalam invisible():

invisible(readline(prompt="Press [enter] to continue"))
nnn
sumber
Saya pikir ini adalah jawaban terbaik di sini.
Léo Léopold Hertz 준영
1
bagaimana jika menambahkan satu fitur lagi padanya? press esc keep to exit loop?
I_m_LeMarque
4
@nnn ini tidak berfungsi jika saya menjalankan skrip di rstudio misalnya print ("hi") readline ("Press a key to continue") print ("ho") Mungkin karena sesi tidak interaktif. Bagaimana melakukan ini dalam sesi non-interaktif?
PascalIv
79

Metode 1

Menunggu sampai Anda menekan [enter] di konsol:

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

Membungkus menjadi sebuah fungsi:

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

Fungsi ini adalah padanan terbaik Console.ReadKey()di C #.

Metode 2

Jeda hingga Anda mengetik tombol [enter] pada keyboard. Kerugian dari metode ini adalah jika Anda mengetik sesuatu yang bukan angka, maka akan muncul kesalahan.

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

Membungkus menjadi sebuah fungsi:

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

Metode 3

Bayangkan Anda ingin menunggu tombol ditekan sebelum memplot titik lain pada grafik. Dalam kasus ini, kita bisa menggunakan getGraphicsEvent () untuk menunggu penekanan tombol dalam grafik.

Contoh program ini menggambarkan konsep:

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

Di sini Anda dapat melihat grafik, dengan setengah dari titiknya diwarnai, menunggu penekanan tombol berikutnya pada keyboard.

Kompatibilitas: Diuji di bawah lingkungan, gunakan win.graph atau X11 . Bekerja dengan Windows 7 x64 dengan Revolution R v6.1. Tidak bekerja di bawah RStudio (karena tidak menggunakan win.graph).

masukkan deskripsi gambar di sini

Gravitas
sumber
6
Metode 1 dapat dipersingkat dengan menggunakan promptargumen ke readline. Metode 2 akan bekerja dengan input apa pun (bukan hanya angka) jika what=""ditambahkan ke panggilan ke scan. getGraphicsEventhanya berfungsi pada perangkat grafik tertentu pada platform tertentu (tetapi jika Anda menggunakan salah satu perangkat itu, itu berfungsi dengan baik).
Greg Snow
2
Jika Anda menggunakan fungsi ini (Metode 1) dalam satu loop dan ingin menghentikan loop, sertakan misalnya:if(line == "Q") stop()
Dorian Grv
18

Berikut adalah fungsi kecil (menggunakan paket tcltk) yang akan membuka jendela kecil dan menunggu sampai Anda mengklik tombol lanjutkan atau menekan tombol apa saja (sementara jendela kecil masih fokus), maka skrip Anda akan dilanjutkan.

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

Letakkan saja mywait()di skrip Anda di mana saja yang Anda inginkan untuk menjeda skrip.

Ini berfungsi pada platform apa pun yang mendukung tcltk (yang menurut saya adalah semua yang umum), akan merespons penekanan tombol apa pun (tidak hanya masuk), dan bahkan berfungsi ketika skrip dijalankan dalam mode batch (tetapi masih berhenti dalam mode batch , jadi jika Anda tidak ada di sana untuk melanjutkan itu akan menunggu selamanya). Pengatur waktu dapat ditambahkan untuk membuatnya melanjutkan setelah jumlah waktu yang ditentukan jika tidak diklik atau tombol ditekan.

Itu tidak mengembalikan tombol mana yang ditekan (tetapi dapat dimodifikasi untuk melakukannya).

Greg Snow
sumber
Itu mengagumkan. Tapi hanya peringatan, itu tidak akan berjalan di RStudio-Server webclient, untuk beberapa alasan ( Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel". )
milia
2
@milia, itu benar. Kode berdasarkan tcltk perlu dijalankan di mesin lokal dan tidak akan dijalankan di RStudio-Server.
Greg Snow
14

R dan Rscript keduanya mengirim ''ke readline dan memindai dalam mode non-interaktif (lihat ? readline). Solusinya adalah dengan memaksa stdinmenggunakan scan.

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

Contoh:

$ Rscript t.R 
Solution to everything? > 42
Read 1 item
Simon A. Eugster
sumber
2
Hebat! Ini hampir menyelesaikan masalah saya . Akan lebih baik jika konsol tidak menunggu teks + Kembali, melainkan bereaksi terhadap penekanan tombol pertama (seperti dalam "Tekan sembarang tombol untuk melanjutkan").
Vorac
2

Jawaban ini mirip dengan jawaban Simon , tetapi tidak memerlukan masukan tambahan selain baris baru.

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

Menggunakan nlines=1alih-alih n=1, pengguna cukup menekan enter untuk melanjutkan Rscript.

Dennis YL
sumber
+1 ini adalah satu-satunya jawaban yang benar-benar berfungsi sesuai keinginan saya. Di dalam Rscript: berhenti dan hanya perlu menekan Enteruntuk melanjutkan.
arielf
3
ini mematahkan R dan saya harus mengakhiri sesi
blobbymatt
1
dalam mode interaktif, ini memecah R dan membutuhkan penghentian sesi. Harap tambahkan peringatan pada entri Anda, dalam hal ini, saya akan menghapus suara negatifnya.
HoneyBuddha
Bekerja untuk saya seperti yang diharapkan di Windows !. Solusi yang diterima (di atas) dilewati dan tidak dijeda. Yang ini benar-benar berhenti dan menunggu saya untuk menekan enter.
Matt Dzievit
0

Cara melakukannya (agak, Anda harus menekan tombol daripada tombol, tapi cukup dekat) adalah dengan menggunakan mengkilap:

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

Menurut pengalaman saya, ini memiliki karakteristik unik: bahkan jika Anda menjalankan skrip yang memiliki kode yang ditulis mengikuti runAppfungsinya, itu tidak akan berjalan sampai Anda menekan tombol di aplikasi (tombol yang menghentikan aplikasi dari dalam menggunakan stopApp).

Sébastien Wouters
sumber