Làm thế nào để chờ nhấn phím trong R?


139

Tôi muốn tạm dừng tập lệnh R của mình cho đến khi người dùng nhấn phím.

Làm thế nào để tôi làm điều này?


Bạn đã tìm thấy bất kỳ câu trả lời mà bạn có thể chấp nhận?
Léo Léopold Hertz

Câu trả lời:


126

Như ai đó đã viết trong một bình luận, bạn không cần phải sử dụng con mèo trước đó readline(). Đơn giản chỉ cần viết:

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

Nếu bạn không muốn gán nó cho một biến và không muốn trả về được in trong bảng điều khiển, hãy bọc nó readline()trong invisible():

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

Tôi nghĩ rằng đây là câu trả lời tốt nhất ở đây.
Léo Léopold Hertz

1
làm thế nào về việc thêm một tính năng cho nó? press esc keep to exit loop?
I_m_LeMarque

4
@nnn điều này không hoạt động nếu tôi chạy tập lệnh trong rstudio, ví dụ như đường đọc ("hi") ("Nhấn phím để tiếp tục") in ("ho") Có lẽ vì phiên không tương tác. Làm thế nào để làm điều này trong một phiên không tương tác?
PascalIv

78

Phương pháp 1

Chờ cho đến khi bạn nhấn [enter] trong bảng điều khiển:

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

Gói thành một chức năng:

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

Hàm này tương đương tốt nhất Console.ReadKey()trong C #.

Cách 2

Tạm dừng cho đến khi bạn gõ phím [enter] trên bàn phím. Nhược điểm của phương pháp này là nếu bạn gõ một cái gì đó không phải là số, nó sẽ hiển thị một lỗi.

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

Gói thành một chức năng:

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

Phương pháp 3

Hãy tưởng tượng bạn muốn chờ nhấn phím trước khi vẽ một điểm khác trên biểu đồ. Trong trường hợp này, chúng ta có thể sử dụng getGraphicsEvent () để chờ nhấn phím trong biểu đồ.

Chương trình mẫu này minh họa khái niệm:

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

Tại đây bạn có thể thấy biểu đồ, với một nửa số điểm của nó được tô màu, chờ nhấn phím tiếp theo trên bàn phím.

Khả năng tương thích: Được kiểm tra trong các môi trường sử dụng win.graph hoặc X11 . Hoạt động với Windows 7 x64 với Revolution R v6.1. Không hoạt động theo RStudio (vì nó không sử dụng win.graph).

nhập mô tả hình ảnh ở đây


6
Phương pháp 1 có thể được rút ngắn bằng cách sử dụng promptđối số để readline. Phương pháp 2 sẽ hoạt động với mọi đầu vào (không chỉ số) nếu what=""được thêm vào lệnh gọi đến scan. getGraphicsEventchỉ hoạt động trên các thiết bị đồ họa cụ thể trên các nền tảng nhất định (nhưng nếu bạn đang sử dụng một trong những thiết bị đó thì nó hoạt động tốt).
Greg Snow

2
Nếu bạn đang sử dụng chức năng này (Phương pháp 1) trong một vòng lặp và muốn dừng vòng lặp, hãy bao gồm ví dụ:if(line == "Q") stop()
Dorian Grv

18

Đây là một chức năng nhỏ (sử dụng gói tcltk) sẽ mở một cửa sổ nhỏ và đợi cho đến khi bạn nhấp vào nút tiếp tục hoặc nhấn bất kỳ phím nào (trong khi cửa sổ nhỏ vẫn có tiêu điểm), sau đó nó sẽ để tập lệnh của bạn tiếp tục.

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

Chỉ cần đặt mywait()tập lệnh của bạn bất cứ nơi nào bạn muốn tập lệnh tạm dừng.

Điều này hoạt động trên bất kỳ nền tảng nào hỗ trợ tcltk (mà tôi nghĩ là tất cả những nền tảng phổ biến), sẽ phản hồi với bất kỳ phím bấm nào (không chỉ nhập) và thậm chí hoạt động khi tập lệnh được chạy ở chế độ hàng loạt (nhưng nó vẫn tạm dừng ở chế độ hàng loạt , vì vậy nếu bạn không ở đó để tiếp tục, nó sẽ đợi mãi). Có thể thêm đồng hồ bấm giờ để tiếp tục sau một khoảng thời gian đã đặt nếu không nhấp hoặc nhấn phím.

Nó không trả về phím nào được nhấn (nhưng có thể được sửa đổi để làm như vậy).


Thật tuyệt vời. Nhưng chỉ là một cảnh báo, nó sẽ không chạy trên webclient RStudio-Server, vì một số lý do ( Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") : [tcl] invalid command name "toplevel". )
milia

2
@milia, đúng rồi. Mã dựa trên tcltk cần chạy trên máy cục bộ và sẽ không chạy trên RStudio-Server.
Greg Snow

14

Cả R và Rupcript đều gửi ''đến đường đọc và quét ở chế độ không tương tác (xem ? readline). Giải pháp là bắt buộc stdinsử dụng quét.

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

Thí dụ:

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

2
Tuyệt vời! Điều này gần như giải quyết vấn đề của tôi . Tuy nhiên, sẽ rất tuyệt nếu bảng điều khiển không chờ văn bản + Trả về mà thay vào đó là phản ứng với phím bấm đầu tiên (như trong "Nhấn phím bất kỳ để tiếp tục").
Vorac

3

Câu trả lời này tương tự như của Simon , nhưng không yêu cầu thêm đầu vào ngoài dòng mới.

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

Sử dụng nlines=1thay vì n=1, người dùng chỉ cần nhấn enter để tiếp tục Rupcript.


+1 đây là câu trả lời duy nhất thực sự hoạt động như mong muốn đối với tôi. Bên trong Rscript: nó tạm dừng và chỉ yêu cầu nhấn Enterđể tiếp tục.
thân

2
điều này đã phá vỡ R và tôi đã phải chấm dứt phiên
blobbymatt

1
trong chế độ tương tác, điều này phá vỡ R và yêu cầu kết thúc phiên. Vui lòng thêm cảnh báo vào mục nhập của bạn, trong trường hợp này, tôi sẽ xóa downvote.
HoneyBuddha

Làm việc cho tôi như mong đợi trên Windows!. Giải pháp được chấp nhận (ở trên) đã bị bỏ qua và không tạm dừng. Điều này thực sự dừng lại và chờ đợi tôi nhấn enter.
Matt D

0

Một cách để làm điều đó (loại, bạn phải nhấn một nút chứ không phải là một phím, nhưng đủ gần) là sử dụng sáng bóng:

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

Theo kinh nghiệm của tôi, điều này có một đặc điểm độc đáo: ngay cả khi bạn chạy tập lệnh có mã được viết theo runAppchức năng, nó sẽ không chạy cho đến khi bạn nhấn nút trong ứng dụng (nút dừng ứng dụng từ bên trong sử dụng stopApp).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.