2015-10-24 35 views
2

短版ř編程:當在多種環境

兩個變量,xy,其中x被包含在環境1 和y的表達式被包含在第二環境中存在的對象評價的表達式。程序員如何評估 表達式?

詳細版本

我有一個函數,它接受一個formula和data.frame作爲參數。在 formula的右側是函數splines::bs到 的調用生成一個B樣條的基礎。主力功能會執行一些操作,其中一項是 ,它需要從公式中提取bs呼叫並對其進行評估。我試圖解決的 問題涉及在參數 值包含在不同環境中時評估bs調用。

下面是重現我的工作問題所需的功能上

library(splines) 

extract_bmat <- function(form) { 
    B <- NULL 
    rr <- function(x) { 
    if (is.call(x) && grepl("bs", deparse(x[[1]]))) { 
     B <<- x 
    } else if (is.recursive(x)) { 
     as.call(lapply(as.list(x), rr)) 
    } else { 
     x 
    } 
    } 
    z <- lapply(as.list(form), rr) 
    B 
} 

some_workhorse <- function(formula, data) { 
    # ... lots of cool stuff ... 
    # fit <- lm(formula, data) 

    bmat <- eval(extract_bmat(formula), data) 
    bmat 
} 

# The following works when evaluated in the .GlobalEnv 
# The eval(extract_bmat(formula), data) call within the some_workhorse 
# function works without errors 
xi  <- c(3, 4.5) 
eg_data <- data.frame(x = 1:10, y = sin(1:10)) 
some_workhorse(y ~ bs(x, knots = xi), data = eg_data) 

現在,如果函數some_workhorsexi載體和eg_data data.frame是一個功能環境內產生導致錯誤。

foo <- function() { 
    xi_in_foo  <- c(2, 3) 
    eg_data_in_foo <- data.frame(x = 1:10, y = sin(1:10)) 

    some_workhorse(y ~ bs(x, knots = xi_in_foo), data = eg_data_in_foo) 
} 

foo() 
# Error in sort(c(rep(Boundary.knots, ord), knots)) : 
# object 'xi_in_foo' not found 

錯誤的位置是splines::bs調用中,但事實並非 重要組成部分;找不到xi_in_foo是要解決的重要問題。

我知道這個問題與我在我的河原 問題處理不當的環境是

  • 應如何 some_workhorse函數中調用eval(extract_bmat(formula), data)寫成這樣在調用時它正常工作 或.GlobalEnv或在函數環境中調用?

次要問題:

  • extract_bmat功能,我寧願定義環境 爲B和使用assign,而不是<<-。我懷疑<<-是最好的 選項,因爲發生遞歸水平的不確定性。這就是說,我想看看其他解決方案。

感謝您的幫助。

回答

2

你應該定義功能

some_workhorse <- function(formula, data) { 
    # ... lots of cool stuff ... 
    # fit <- lm(formula, data) 

    bmat <- eval(extract_bmat(formula), data, environment(formula)) 
    bmat 
} 

注意formula S IN [R捕捉他們所創建的環境。只要在定義公式的環境中存在xi_in_foo,就應該有效。變量將首先在data列表/ data.frame中查找,然後公式環境將用作封閉環境。如果您不使用公式,有時候人們使用parent.frame()作爲enclos=參數,以便在函數被調用的環境中查找變量,而不是將函數定義爲R的詞法範圍的默認值。

+0

謝謝你的幫助和解釋。我曾嘗試使用parent.frame()作爲沒有成功的機箱。我很欣賞你回答這個問題和其他問題的時間。 – Peter