2014-12-02 45 views
2

我希望能夠在函數內調用lm,並將weights變量指定爲傳遞給外部函數的參數,然後傳遞給lm。下面是一個可重複使用的示例,其中調用在函數外部調用lm時生效,但在從包裝器函數內調用時生成錯誤消息Error in eval(expr, envir, enclos) : object 'weightvar' not found在R中將參數傳遞給lm函數

olswrapper <- function(form, weightvar, df){ 
    ols <- lm(formula(form), weights = weightvar, data = df) 
    } 

df <- mtcars 

ols <- lm(mpg ~ cyl + qsec, weights = gear, data = df) 
summary(ols) 

ols2 <- olswrapper(mpg ~ cyl + qsec, weightvar = gear, df = df) 
#Produces error: "Error in eval(expr, envir, enclos) : object 'weightvar' not found" 
+0

當你輸入'gear'時,你會得到什麼?沒有什麼,它不是全局定義的,你的'olswrapper'不知道在'df'內部尋找它。讓它工作的一種方法是將'weightvar =「gear」'作爲一個字符,然後在你的'lm'中調用'weights = df [weightvar]'。 – Gregor 2014-12-03 00:10:57

+0

[R:將參數傳遞給R函數內部的glm]的可能重複(http://stackoverflow.com/questions/10858318/r-pass-argument-to-glm-inside-an-r-function) – user20650 2014-12-03 00:26:42

回答

2

建立在評論上,gear沒有全局定義。它可以在您指定您正在使用的數據的獨立呼叫lm內工作,所以lm知道要從df獲取gear

不過,gear本身並不存在那個獨立的lm功能之外。這是由gear

> gear 
Error: object 'gear' not found 

輸出顯示可以通過gear到使用df$gear

weightvar <- df$gear 
ols <- olswrapper(mpg ~ cyl + qsec, weightvar , df = df) 
+0

爲什麼這種行爲與將'df $ gear'直接傳遞給包裝器(產生相同的錯誤)不同? – Michael 2014-12-03 00:27:10

1

我知道我遲到了這個功能,但我相信前面的解釋是不完整的。聲明weightvar <- df$gear,然後將它傳遞給該函數僅適用,因爲您使用weightvar作爲您的weight參數的名稱。這只是使用weightvar作爲全局變量。這就是爲什麼df$gear不能直接工作。如果您使用除weightvar以外的任何名稱,它也不起作用。

它不起作用的原因是lm在兩個地方查找數據:dataframe參數(如果指定)和公式的環境。在這種情況下,您公式的環境是R_GlobalEnv。 (您可以通過從olswrapper內部運行print(str(form))來測試此操作)。因此,lm將只在全球環境和df,而不是功能環境。

編輯:在lm文檔中的數據參數的描述表示:在包含該模型中的變量 「可選的數據幀,列表或環境(或對象強制轉換由as.data.frame到的數據幀)。 如果未在數據中找到,則變量取自環境(公式),通常是調用lm的環境。「

一個快速的解決方法是說environment(form) <- environment()來改變你的公式的環境。這不會導致任何問題,因爲公式中的數據位於您指定的數據框中。