Як чекати натискання клавіші в R?


Відповіді:


127

Як уже хтось писав у коментарі, раніше не потрібно використовувати кішку readline(). Просто напишіть:

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

Якщо ви не хочете , щоб привласнити його змінної і не хочуть повернення надрукований в консолі, оберніть readline()в invisible():

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

Я думаю, що це найкраща відповідь тут.
Лео Леопольд Герц 준영

1
як щодо додавання до нього ще однієї функції? press esc keep to exit loop?
I_m_LeMarque

4
@nnn це не працює, якщо я запускаю скрипт у rstudio, наприклад, print ("привіт") readline ("Натисніть клавішу для продовження") print ("ho") Це, ймовірно, тому, що сеанс не є інтерактивним. Як це зробити в неінтерактивній сесії?
PascalIv

79

Спосіб 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 . Працює з Windows 7 x64 з Revolution R v6.1. Не працює під RStudio (оскільки він не використовує win.graph).

введіть тут опис зображення


6
Спосіб 1 можна скоротити за допомогою promptаргументу до readline. Спосіб 2 працював би з будь-яким входом (а не лише цифрами), якби вони what=""були додані до виклику scan. getGraphicsEventпрацює лише на певних графічних пристроях на певних платформах (але якщо ви використовуєте один із цих пристроїв, він працює чудово).
Грег Сніг

2
Якщо ви використовуєте цю функцію (метод 1) у циклі і хочете зупинити цикл, включіть, наприклад:if(line == "Q") stop()
Доріан Грв

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 (що, на мою думку, є загальним), реагуватиме на будь-яке натискання клавіші (не просто вводити) і навіть працює, коли сценарій запускається в пакетному режимі (але він все ще призупиняється в пакетному режимі , тож якщо ви не там, щоб продовжити це, це буде чекати вічно). Можна додати таймер, щоб продовжувати його після встановленого часу, якщо його не натискали або натиснуто клавішу.

Він не повертає, яку клавішу натискали (але її можна змінити для цього).


Це приголомшливо. Але лише попередження, він не запуститься на веб-кліенті RStudio-Server (чомусь ( Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel". )
milia

2
@milia, це правильно. Код, заснований на tcltk, повинен працювати на локальній машині і не працюватиме на RStudio-сервері.
Грег Сніг

14

R і Rscript обидва надсилають ''для перегляду чи сканування у неінтерактивному режимі (див. ? 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

Ця відповідь схожа на відповідь Саймона , але не потребує додаткового введення, окрім нового рядка.

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

Використовуючи nlines=1замість n=1, користувач може просто натиснути клавішу Enter, щоб продовжити Rscript.


+1 це єдина відповідь, яка насправді працює для мене. Всередині Rscript: він призупиняється і вимагає лише натискання, Enterщоб продовжити.
аріельф

2
це зламало R, і мені довелося припинити сеанс
blobbymatt

1
в інтерактивному режимі це розбиває R і вимагає припинити сеанс. Будь ласка, додайте попередження щодо вашого вступу, і в такому випадку я зніму зворотний запис.
HoneyBuddha

Працював для мене, як очікувалося, у Windows !. Прийняте рішення (вище) було пропущено і не призупинялося. Цей насправді зробив паузу і чекав, коли я вдару ввійти.
Matt 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).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.