2013-10-07 53 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 

但在函數的局部環境中工作時,qccqcc.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該對象後來被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') 

enter image description here

+0

非常感謝Thomas!我知道發生了什麼,我只是不知道如何正確分配變量。 '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

非常感謝Roland!這基本上與托馬斯提出的類似的解決方法,只是在使用(好點)後設置原始選項。我已經郵寄了包裹mantainers。再次感謝,黑客對我來說非常完美。 – albifrons