Как установить параметры по умолчанию для графического устройства?

Мне нравится читать белые на черном. Таким образом, в RI будет что-то делать:

par (bg = "black")
par (fg = "ivory1")

Я бы хотел, чтобы эти параметры были установлены по умолчанию. Однако не просто писать эти строки в .Rprofile потому что, насколько я понимаю, в момент его выполнения графическое устройство еще не инициализировано. Скорее, как было предложено в другом ответе, необходимо повторно назначить опцию options()$device чтобы включить необходимую настройку параметра. У меня не было успеха в этом.

Вот что я пробовал:

~/.Rprofile

f_device <- options()$device

blackdevice <- function (...) {

    f_device(...)

    par (bg       = "black")
    par (fg       = "ivory1")
}

options (device = blackdevice)

Идея здесь заключается в том, чтобы сохранить исходную функцию device в другую переменную, а затем вызвать ее из моей новой функции device. Я получаю:

Error in f_device(...) : could not find function "f_device"

- В то время я запускаю plot (something).

Еще одна идея, которую я имел, - это так:

~/.Rprofile

.First <- function () {

    options(f_device = options()$device)

    blackdevice <- function (...) {

        options()$f_device(...)

        par (bg       = "black")
        par (fg       = "ivory1")
    }

    options (device = blackdevice)
}

- Назначение оригинального device в другое место в options. Но это приводит к:

Error in (function (...)  : attempt to apply non-function

У меня нет идей. Можете ли вы помочь мне понять это?

Ответ 1

Ваша проблема здесь в том, что параметр device еще не установлен в то время. .Rprofile обрабатывается.
Поэтому в этом пункте options()$device имеет NULL, что приводит к ошибке, которую вы наблюдаете.

Функция .First() также запускается до того, как пакеты из options("defaultPackages") прикреплены, что дает такую же ошибку.

Если вы хотите что-то поместить в .Rprofile, это должно быть похоже:

setHook(
    packageEvent("grDevices", "onLoad"),
    function(...) {
        f_device <- getOption("device")

        blackdevice <- function(...) {
            f_device(...)
            par(bg = "black")
            par(fg = "ivory1")
        }

        options(device = blackdevice)
    }
)

Обратите внимание, что это решение для стандартного R GUI, но не для RStudio, которое впоследствии устанавливает свое собственное устройство "RStudioGD" (и требует, чтобы grDevices уже загружался).

(Это также объясняет неудобный подход (из связанного с вами вопроса) переопределения "RStudioGD" в .Rprofile чтобы .Rprofile его "tools:rstudio" на пути поиска)

Ответ 2

Одним из решений является определение "крюка", который вызывается при создании нового сюжета. Из документации plot.new:

Есть два крючка, называемые "before.plot.new" и "plot.new" (см. "SetHook"), вызываемые непосредственно перед и после продвижения кадра. Последний используется в тестовом коде для аннотирования новой страницы. Функция (и) hook вызывается без аргумента. (Если значение является символьной строкой, "get" вызывается на нем из "пространства имен графики").

Кажется, что работает следующее:

setHook("before.plot.new", function(...) {
  par(bg = "black",
    fg = "ivory1",
    col.axis = "ivory1",
    col.lab = "ivory1",
    col.main = "ivory1",
    col.sub = "ivory1")
})