จะรอกดปุ่ม R ได้อย่างไร?


142

ฉันต้องการหยุดสคริปต์ R ของฉันชั่วคราวจนกว่าผู้ใช้จะกดปุ่ม

ฉันต้องทำอย่างไร


คุณพบคำตอบที่คุณยอมรับได้หรือไม่?
LéoLéopold Hertz 준영

คำตอบ:


132

readline()เป็นคนแล้วเขียนในความคิดเห็นที่คุณไม่ต้องใช้แมวก่อน เพียงเขียน:

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

หากคุณไม่ต้องการกำหนดให้กับตัวแปรและไม่ต้องการให้พิมพ์ผลตอบแทนในคอนโซลให้ห่อreadline()ในinvisible():

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

ผมว่าตรงนี้ตอบโจทย์ได้ดีที่สุด
LéoLéopold Hertz 준영

1
แล้วจะเพิ่มคุณสมบัติอีกหนึ่งอย่างเข้าไปได้อย่างไร? press esc keep to exit loopเหรอ?
I_m_LeMarque

4
@nnn สิ่งนี้จะใช้ไม่ได้ถ้าฉันเรียกใช้สคริปต์ใน rstudio เช่น print ("hi") readline ("Press a key to continue") 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="" ใช้งานได้กับอุปกรณ์กราฟิกบางอย่างในบางแพลตฟอร์มเท่านั้น (แต่ถ้าคุณใช้อุปกรณ์เหล่านี้ก็ใช้ได้ดี) scangetGraphicsEvent
Greg Snow

2
หากคุณกำลังใช้ฟังก์ชั่นนี้ (วิธีที่ 1) ในการวนซ้ำและต้องการหยุดการวนซ้ำเช่น:if(line == "Q") stop()
Dorian Grv

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-Server
Greg Snow

14

R และ Rscript ส่ง''ไปยัง readline และ scan ในโหมด non-interactive (ดู? 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

2

คำตอบนี้คล้ายกับของSimonแต่ไม่ต้องการการป้อนข้อมูลเพิ่มเติมนอกเหนือจากการขึ้นบรรทัดใหม่

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

การใช้nlines=1แทนn=1ผู้ใช้สามารถกด Enter เพื่อดำเนินการต่อ Rscript


+1 นี่คือคำตอบเดียวที่ใช้งานได้จริงสำหรับฉัน ข้างในRscript: หยุดชั่วคราวและต้องกดEnterเพื่อดำเนินการต่อ
arielf

3
สิ่งนี้ทำลาย R และฉันต้องยุติเซสชัน
blobbymatt

1
ในโหมดโต้ตอบสิ่งนี้จะแบ่ง R และต้องยุติเซสชัน โปรดเพิ่มคำเตือนในรายการของคุณซึ่งในกรณีนี้ฉันจะลบการโหวตลงคะแนน
HoneyBuddha

ทำงานให้ฉันตามที่คาดไว้บน Windows! โซลูชันที่ยอมรับ (ด้านบน) ถูกข้ามไปและไม่ได้หยุดชั่วคราว อันนี้หยุดชั่วคราวและรอให้ฉันกด Enter
Matt Dzievit

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)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.