getGraphicsEvent для чтения клавиатуры для неинтерактивного сеанса
В любом случае, в более старых версиях 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 ответа
Вы можете подделать интерактивный сеанс, который будет определен как неинтерактивный, запустив Rterm с параметром
--ess
в Windows или
--interactive
на Unix-подобных.
Это может вызвать другие проблемы, потому что все функции будут видеть сеанс как интерактивный. Вы не можете изменить этот флаг в середине сеанса, так как он влияет на многие вещи, связанные с вводом / выводом.
Вот исходный код для getGraphicsEvent:
function (prompt = "Ожидание ввода", onMouseDown = NULL, onMouseMove = NULL, onMouseUp = NULL, onKeybd = NULL, consolePrompt = приглашение) { if (!interactive()) вернуть (NULL) if (! отсутствует (приглашение) ||! отсутствует (onMouseDown) ||! отсутствует (onMouseMove) ||! отсутствует (onMouseUp) ||! отсутствует (onKeybd)) { setGraphicsEventHandlers(prompt = prompt, onMouseDown = onMouseDown, onMouseMove = onMouseMove, onMouseUp = onMouseUp, onKeybd = onKeybd) } .External2(C_getGraphicsEvent, consolePrompt) }
Вы можете понять, почему он возвращает NULL, так как это делается с помощью if (!interactive()) return(NULL)
, Попробуйте это вставить в свой оригинальный код:
getGraphicsEvent2 = function (prompt = "Ожидание ввода", onMouseDown = NULL, onMouseMove = NULL, onMouseUp = NULL, onKeybd = NULL, consolePrompt = приглашение) { # if (!interactive()) # возврат (NULL) if (! отсутствует (приглашение) ||! отсутствует (onMouseDown) ||! отсутствует (onMouseMove) ||! отсутствует (onMouseUp) ||! отсутствует (onKeybd)) { setGraphicsEventHandlers(prompt = prompt, onMouseDown = onMouseDown, onMouseMove = onMouseMove, onMouseUp = onMouseUp, onKeybd = onKeybd) } .External2(C_getGraphicsEvent, consolePrompt) } environment(getGraphicsEvent2) = среда (grDevices::getGraphicsEvent) драгплот (рнорм (1000), ннорм (1000)) kbd = функция (ключ) { if (key == "q") { "Quit" } else NULL } getGraphicsEvent2("Ожидание ввода", onKeybd = kbd)
Кажется, он теряет функциональность (то есть, я не мог манипулировать сюжетом на OSX с X11 в качестве графического устройства), но, по крайней мере, сюжет остается неизменным. Вызов внутреннего кода для этой функции недавно изменился (для подтверждения посмотрите исходный код для R в двух версиях - код для этой функции в R 2.6.2, например, находится в R-2.6.2/src/library/grDevices/R/gevents.R).