2015-11-22 31 views
1

假設我具有以下函數,其參數爲var_namevar_name引用數據框中變量的名稱。現在考慮下面的功能:參考R中的選擇函數中的變量

library(dplyr) 
calculate_mean <- function(data, var_name) { 
    lapply(select(data, var_name), mean, na.rm=TRUE) 
} 

不過,我得到的錯誤:

Error: All select() inputs must resolve to integer column positions. 
    The following do not: * var_name 

回答

2
df <- head(iris) 

f <- function(data, var_name) { 
    select(data, var_name) 
} 

f(df, "Petal.Width") 
#Error: All select() inputs must resolve to integer column positions. 
#The following do not: 
#* var_name 

那個包的作者往往寫的接受字符串作爲參數的函數可選版本。嘗試添加下劃線給該函數:

f2 <- function(data, var_name) { 
    select_(data, var_name) 
} 

f2(df, "Petal.Width") 
# Petal.Width 
#1   0.2 
#2   0.2 
#3   0.2 
#4   0.2 
#5   0.2 
#6   0.4 

另外說明一般沒有引號的字符串被認爲是可變的。如果我們在控制檯中嘗試x,則評估程序將在環境中搜索具有該名稱的變量。與功能一起使用時,將發生相同的搜索。使用mean(x)必須定義變量x

當函數寫入不搜索變量時,此行爲可能會變得混淆。它被稱爲非標準評估,NSE。有一個使用NSE的base R函數。 subset(df, select= -Petal.Width)返回沒有Petal.Width的數據幀。這種便利使得編程更容易。 select是以類似的方式設計的。

當你創建你的函數時,它以標準的方式進行評估;沒有引用的論點被認爲是變量。但是,您正在將其用於NSE功能select。即使您期待它被用戶輸入替換,該功能也會尋找var_name。讓我們通過創建一個文本var_name列可以說明問題:

df$var_name <- 1 
f(df, "Petal.Width") 
    var_name 
1  1 
2  1 
3  1 
4  1 
5  1 
6  1 

select原函數返回的列var_name,不是我們所希望的列。部分地,Hadley Wickham創建了select_,以預測這種差異。

有關NSE http://adv-r.had.co.nz/Computing-on-the-language.html更多信息

+0

什麼之間的區別選擇()和SELECT_()? – Neel

+0

@Neel - 一個使用非標準評估('select()'),另一個使用標準('select _()')。 –