2014-09-02 57 views
1
x <- y <- 1:5 
df = data.frame(m=x,n=y) 

myfun <- function(data, var) { 
    library(dplyr) 
    select(data, var) 
} 


myfun(df, m) 

錯誤的eval(expr中,ENVIR,enclos):對象的 'm' 未找到如何在data.frame通過列具有dplyr的功能的功能內

+0

你的第一個版本,我覺得實際工作,你只是通過不存在的'select'列索引參數的任意數目。 – joran 2014-09-02 02:53:33

+0

但是,這兩個調用不適合我。沒有線索 – kurt 2014-09-02 02:59:49

+0

我會重複一遍,你用兩列創建了一個df,然後詢問列1:5。 – joran 2014-09-02 03:34:32

回答

2

理查茲回答能夠繞過的參數任意數量。但要分別控制這種選擇呼叫的每個參數,您必須知道: 在select(data, m)中,m是而不是這是一個變量,它在此處具有指定的值!它只是一個符號,它在數據框「數據」的上下文中有一些意義。 myfun(df, m)將在參數m(在選擇調用中就是這種情況)時立即失敗,因爲m沒有值(或者來自全局環境的值,您肯定不想要!)在內部,dplyr將使用substitute函數將其轉換爲符號(而不是評估它)。將var轉換爲符號(或呼叫,例如m:n等選項)後,您可以使用do.call撰寫和評估新的選擇呼叫。

對於您的示例代碼,這意味着:

x <- y <- 1:5 
df = data.frame(m=x,n=y) 

myfun <- function(data, var) { 
    library(dplyr) 
    var <- substitute(var) 
    do.call('select', list(data, var)) 
} 


myfun(df, m) 

將推廣到更多的參數是直線前進。

對於要轉換爲符號或呼叫您可以使用

myfun <- function(...) { 
    args <- substitute(list(...)) 
    # Now args[i] is a symbol/call representing the i-th argument 
} 
+0

以這種方式使用'do.call()'是極不推薦的 - 它消除了dplyr的許多優點,因爲它必須構造至少一個(也許是兩個)額外的數據副本。 – hadley 2014-09-03 00:48:27

0

select使用select.data.frame,數據幀的方法。 select的第二個參數是...列表,以便可以將參數傳遞給其他方法。您的函數在其第二個參數中使用名稱var,並且由於dplyr.()函數,所以將基本R方差函數var傳遞給select中的其他函數。

長話短說,改變你的參數名稱。我會去與

myfun <- function(z, ...) select(z, ...) 
myfun(df, x) 
myfun(df, y) 

您也可以使用select方法

> select.myfun <- function(.data, ...) UseMethod("select") 
> myfun(df, exclude = "x") 
> methods(select)[6] 
[1] "select.myfun" 

作爲一個無恥的插頭,我將把你a question I asked about ... arguments。答案中有兩個非常好的解釋。

編輯按照要求,看看.()

> `.` 
function (..., .env = parent.frame()) 
{ 
    structure(as.list(match.call()[-1]), env = .env, class = "quoted") 
} 
<environment: namespace:plyr> 

> .(x) 
List of 1 
$ x: symbol x 
- attr(*, "env")=<environment: R_GlobalEnv> 
- attr(*, "class")= chr "quoted" 
+0

讚賞!這很有用,很好理解。例如, – kurt 2014-09-02 03:26:03

+0

,如果我有兩個選擇在我的功能。我怎麼能通過不同的參數給每一個。 – kurt 2014-09-02 03:32:15

+0

@Scriven你能指出哪裏。()函數是。我在dplyr文檔中找不到它。謝謝 – kurt 2014-09-02 04:34:47