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
4

2 回答 2

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。您应该就此联系包维护者。

于 2013-10-07T08:28:52.037 回答
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.marginto"green"但这不是随后由plot.qcc.

似乎您应该向包维护者请求一些代码修改,因为这可能不是最好的设置。

编辑:一种解决方法是使用assignInNamespace局部变量来覆盖全局变量。(显然,这会全局更改参数,并会影响所有后续绘图,除非更新参数。)

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

在此处输入图像描述

于 2013-10-07T08:28:45.257 回答