windows - getGraphicsEvent for at læse tastaturet for en ikke-interaktiv session

Indlæg af Hanne Mølgaard Plasc

Problem



I ældre versioner af R, version 2.9 kunne jeg alligevel køre et R-program fra batch ved hjælp af rterm.exe og oprette et grafikvindue, som en bruger kunne rulle frem og tilbage og se graferne. Jeg kunne gøre det ved at bruge nogle R-kode som:


 kbd <- function(key) { 
 if (key == "q") { "Quit" } else NULL } 
 getGraphicsEvent(" ",  onKeybd = kbd) 


Dette holdt grafikfremviseren åben, indtil brugeren trykte på 'q' -tasten. I nyere versioner af R ser det ud til, at da dette er startet fra batch (ikke-interaktivt ved hjælp af Rterm.exe), er nøgleværdien altid NULL, og grafikvinduet blinker og lukker blot. Mit spørgsmål er, om der er nogen måde, jeg på en eller anden måde kan overbevise R-systemet om, at jeg kører en quasi-interaktiv session og får adfærd fra getGraphicsEvent til ikke at returnere NULL med det samme?

Bedste reference


Du kan falske en interaktiv session i en, der ville blive opdaget som ikke-interaktiv ved at starte Rterm med optionen


--ess


på Windows eller


--interactive


på Unix-alikes.


Dette kan forårsage andre problemer, fordi alle funktioner vil se sessionen som interaktiv. Du kan ikke ændre dette flag midt i en session, da det påvirker mange ting relateret til I/O.

Andre referencer 1


Her er kildekoden for getGraphicsEvent:


function (prompt = "Waiting for input", onMouseDown = NULL, onMouseMove = NULL, 
    onMouseUp = NULL, onKeybd = NULL, consolePrompt = prompt) 
{

    if (!interactive()) 
        return(NULL)
    if (!missing(prompt) || !missing(onMouseDown) || !missing(onMouseMove) || 
        !missing(onMouseUp) || !missing(onKeybd)) {
        setGraphicsEventHandlers(prompt = prompt, onMouseDown = onMouseDown, 
            onMouseMove = onMouseMove, onMouseUp = onMouseUp, 
            onKeybd = onKeybd)
    }
    .External2(C\_getGraphicsEvent, consolePrompt)
}


Du kan se, hvorfor det returnerer NULL, da det er udtrykt med if (!interactive()) return(NULL). Prøv dette indsat i din originale kode:



getGraphicsEvent2 = function (prompt = "Waiting for input", onMouseDown = NULL, onMouseMove = NULL, 
    onMouseUp = NULL, onKeybd = NULL, consolePrompt = prompt) 
{

  #  if (!interactive()) 
  #      return(NULL)
    if (!missing(prompt) || !missing(onMouseDown) || !missing(onMouseMove) || 
        !missing(onMouseUp) || !missing(onKeybd)) {
        setGraphicsEventHandlers(prompt = prompt, onMouseDown = onMouseDown, 
            onMouseMove = onMouseMove, onMouseUp = onMouseUp, 
            onKeybd = onKeybd)
    }
    .External2(C\_getGraphicsEvent, consolePrompt)
}
environment(getGraphicsEvent2) = environment(grDevices::getGraphicsEvent)

dragplot(rnorm(1000), rnorm(1000))


kbd = function(key) { 
 if (key == "q") { "Quit" } else NULL } 
 getGraphicsEvent2("Waiting for input",  onKeybd = kbd) 


Det ser ud til at tabe funktionalitet (dvs. jeg kunne ikke manipulere plottet på OSX med X11 som grafik enhed), men i det mindste går plottet op. Opkaldet til intern kode for denne funktion ændret sig for nylig (for at bekræfte, se kildekoden for R i to versioner - koden for denne funktion i R 2.6.2, for eksempel er ved R-2.6.2/src/library/grDevices/R/gevents.R).