getGraphicsEvent for reading the key board for a noninteractive session
In older versions of R, version 2.9 anyway, I was able to run an R program from batch using rterm.exe and create a graphics window that a user could scroll back and forth and view the graphs. I was able to do that by using some R code like:
kbd <- function(key) {
if (key == "q") { "Quit" } else NULL }
getGraphicsEvent(" ", onKeybd = kbd)
This held the graphics viewer open until the user pressed the "q" key. In newer versions of R, it seems that since this is started from batch (non-interactive using Rterm.exe), the key value is always NULL and the graphics window simply flashes and closes. My question is if there is any way I can somehow convince the R sys开发者_运维知识库tem that I'm running a quasi-interactive session and get the behavior of getGraphicsEvent to not return NULL immediately?
You can fake an interactive session in one that would be detected as non-interactive by starting Rterm with the option
--ess
on Windows, or
--interactive
on Unix-alikes.
This may cause other problems, because all functions will see the session as interactive. You can't change that flag in the middle of a session, since it affects lots of things related to I/O.
Here is the source code 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) }
You can see why it returns NULL, since that's made explicit with if (!interactive()) return(NULL)
. Try this inserted into your original code:
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)
It seems to lose functionality (i.e. I couldn't manipulate the plot on OSX with X11 as graphics device), but at least the plot stays up. The call to internal code for this function changed recently (to confirm, look at source code for R in two versions - the code for this function in R 2.6.2, for example is at R-2.6.2/src/library/grDevices/R/gevents.R).
精彩评论