[英]Using lm() of R, a formula object should be passed as character?
我發現了一個使用lm()的R的奇怪行為。
基於cars
對象,以下功能是繪制擬合的斷裂距離,並以速度30進行局部線性回歸。
func1 <- function(fm, spd){
w <- dnorm(cars$speed - spd, sd=5)
fit <- lm(formula = as.formula(fm), weights = w, data=cars)
plot(fitted(fit))
}
func2 <- function(fm, spd){
w <- dnorm(cars$speed - spd, sd=5)
fit <- lm(formula = fm, weights = w, data=cars)
plot(fitted(fit))
}
func1("dist ~ speed", 30)
func2(dist ~ speed, 30)
func1
有效。 但是func2
失敗並顯示以下消息:
Error in eval(expr, envir, enclos) : object 'w' not found
兩個函數之間的唯一區別是func2
接收公式類作為參數。
在這種風格中使用L的lm(),公式對象應該作為字符傳遞?
我用R-3.2.1,RStudio 0.99.467,Windows7測試了這個。
非常有趣的案例! 這與R的環境特征有很大關系。簡而言之,似乎我們不應該將外部定義的公式對象傳遞給函數。 雖然有一些方法可以調整,但這種行為可能讓我們感到驚訝。
?formula
說:
公式對象具有關聯的環境 ,並且model.frame 使用 此環境 (而不是父環境)來評估在提供的數據參數中找不到的變量。
在你的func1
,公式是在函數內部生成的,因此它與函數環境相關聯(函數形成一個環境)。 因此,當在data
找不到對象時, lm
調用在函數環境中查找它們。 這就是在func1
找到w
方式。
在第二個示例中,公式在函數外部定義,或者更確切地說,在全局環境中定義。 因此,如果在data
找不到,則公式會查找全局中的對象。 由於全球沒有w
,它失敗了。 更糟糕的是,如果你在全球范圍內有另一個w
,那么這個w
就會被混淆並用作權重。
這是一個突出顯示對象搜索順序的示例。 數據只有y
。 因此lm
調用在其他地方尋找x
。 但是有兩個x
。 fm
,全局中定義的公式x = 1:10
,而函數中定義的as.formula(ch)
查找x = 10:1
。 environment
告訴您公式與哪個環境相關聯。
fun <- function(fm, ch) {
x <- 10:1
dat <- data.frame(y = 1:10)
print(environment(fm))
print(lm(fm, data = dat))
cat("<--- refers to x in the global\n")
print(environment(as.formula(ch)))
print(lm(as.formula(ch), data = dat))
cat("<--- refers to x in the function\n\n")
}
x <- c(1:10)
fun(y ~ x, "y ~ x")
另請參閱: 環境 - 高級R。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.