2013-10-07 3 views
2

Я изо всех сил пытаюсь назначить переменную пространства имен внутри функции. Рассмотрим этот пример, используя CRAN-пакет «qcc»: qcc() генерирует график, но параметры отображения этого графика контролируются qcc.options().Назначение переменных пространства имен внутри функции

При работе в глобальном, все в порядке:

library(qcc) 
qcc.options(bg.margin="red")  # sets margin background colour, i.e. 
            # qcc:::.qcc.options$bg.margin is "red" 
qcc(rnorm(100), type = "xbar.one") # generates a plot with red margin 

Но при работе в локальной среде функции, qcc и qcc.options, кажется, используют пространство имен по-разному:

foo <- function(x){ 
    qcc.options(bg.margin=x) 
    qcc(rnorm(100), type = "xbar.one") 
} 

foo("green") # generates a default plot with grey margins 

ответ

3

Это из-за чего qcc.options сохраняет свою переменную .qcc.options. Работа в глобальном режиме - это qcc:::.qcc.options, но когда вы находитесь внутри функции, она хранит ее в локальной переменной, которая называется .qcc.options, поэтому, когда вы пытаетесь использовать plot.qcc (вызывается qcc), она извлекает параметры из глобального (не-) qcc:::.qcc.options, а не местное .qcc.options.

Вот функция, которая показывает, что происходит с параметрами:

bar <- function(x){ 
    pre <- qcc:::.qcc.options 
    pre.marg <- qcc.options("bg.margin") 
    qcc.options(bg.margin=x) 
    post1 <- qcc:::.qcc.options 
    post2 <- .qcc.options 
    post.marg <- qcc.options("bg.margin") 
    qcc(rnorm(100), type = "xbar.one") 
    list(pre,post1,post2,pre.marg,post.marg) 
} 
bar('green') 

Если вы посмотрите на результаты, вы увидите, что qcc.options создает локальную переменную и изменяет свое значение bg.margin в "green", но этот ISN 't объект, который впоследствии ссылается на plot.qcc.

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

EDIT: Обходной путь заключается в использовании assignInNamespace для использования локальной переменной для перезаписи глобальной. (Очевидно, это то изменяет параметр глобально и будет влиять на все последующие участки, если параметр не обновляется.)

foo <- function(x){ 
    qcc.options(bg.margin=x) 
    assignInNamespace('.qcc.options',.qcc.options,ns='qcc') 
    qcc(rnorm(100), type = "xbar.one") 
} 
foo('green') 

enter image description here

+0

Большое спасибо! Я знал, что происходит, я просто не знал, как правильно назначить переменную. 'assignInNamespace' отлично работает. – albifrons

+0

@ user2853399 Звучит хорошо. Я бы определенно упомянул об этом разработчику пакета, хотя вам не нужно было делать этот шаг (так как не очевидно, что именно делает qcc.options). – Thomas

+0

Я отправил письмо сопровождающему со ссылкой на эту страницу сразу после получения ответа :) Еще раз спасибо! – albifrons

4

Вот некрасиво хак:

foo <- function(x){ 
    old.qcc.options <- get(".qcc.options", asNamespace("qcc")) 
    assign(".qcc.options", qcc.options(bg.margin=x), asNamespace("qcc")) 
    res <- qcc(rnorm(100), type = "xbar.one") 
    assign(".qcc.options", old.qcc.options, asNamespace("qcc")) 
    invisible(res) 
} 

foo("green") 

Конечно, проблемы обзора будут лучше решены путем изменения qcc.options. Об этом вам следует обратиться в службу поддержки пакетов.

+0

Спасибо, Роланд! Это в основном аналогичное обходное решение, предложенное Томасом, просто установив исходные параметры обратно после использования (хорошая точка). Я уже отправил почтовые рассылки. Еще раз спасибо, хак просто идеально подходит для меня. – albifrons

Смежные вопросы