getGraphicsEvent для чтения клавиатуры для неинтерактивного сеанса - PullRequest
12 голосов
/ 14 августа 2011

В более старых версиях R, версии 2.9, в любом случае, я смог запустить R-программу из пакета, используя rterm.exe, и создать графическое окно, которое пользователь мог бы прокручивать назад и вперед и просматривать графики.Я смог сделать это с помощью некоторого кода R, например:

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

Это удерживало графический просмотрщик открытым, пока пользователь не нажал клавишу «q».В более новых версиях R кажется, что поскольку он запускается из пакета (не интерактивно с использованием Rterm.exe), значение ключа всегда равно NULL, а графическое окно просто мигает и закрывается.У меня вопрос: есть ли способ как-то убедить систему R, что я запускаю квазиинтерактивный сеанс, и заставить поведение getGraphicsEvent не возвращать NULL немедленно?

Ответы [ 2 ]

1 голос
/ 13 января 2015

Вы можете подделать интерактивный сеанс, который будет определен как неинтерактивный, запустив Rterm с параметром

--ess

в Windows или

--interactive

в Unix-alikes.

Это может вызвать другие проблемы, потому что все функции будут видеть сеанс как интерактивный.Вы не можете изменить этот флаг в середине сеанса, так как он влияет на множество вещей, связанных с вводом / выводом.

0 голосов
/ 20 декабря 2013

Вот исходный код 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)
}

Вы можете понять, почему он возвращает NULL, поскольку это явно указано в if (!interactive()) return(NULL). Попробуйте это вставить в свой оригинальный код:


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) 

Кажется, что он теряет функциональность (т.е. я не мог манипулировать сюжетом на OSX с X11 в качестве графического устройства), но, по крайней мере, сюжет остается неизменным. Вызов внутреннего кода для этой функции недавно изменился (для подтверждения посмотрите исходный код для R в двух версиях - код для этой функции в R 2.6.2, например, находится в R-2.6.2 / src / library / grDevices /R/gevents.R).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...