2014-11-04 96 views
2

我有以下示例性數據使用可變的列名中dplyr(DO)

d.1 = data.frame(id=c(1,1,2,3,3), date=c(2001,2002,2001,2001,2003), measure=c(1:5)) 
d.2 = data.frame(id=c(1,2,2,3,3), date=c(2001,2002,2003,2002,2008), measure=c(1:5)) 
d = merge(d.1,d.2, all=T, by="id") 

d.1d.2兩種測量和我需要每id每個測量之一。測量結果應儘可能接近。我可以做到這一點dplyr

require(dplyr) 
d = d %>% 
    group_by(id) %>% 
    do(.[which.min(abs(.$date.x-.$date.y)),]) 

的問題是如何,我可以使用dplyr如果日期列的名稱保存在一個變量像name.x="date.x"name.y="date.y",因爲我不能用

... 
do(.[which.min(abs(.[, name.x]-.[, name.y])),]) 
.... 

我試着用evalas.symbol ANS東西一樣,要找到解決anaother,但我不能想出一個解決方案...

回答

3

d$date.x返回,而矢量返回一個data.frame,在函數內部傳遞時不起作用。所以,簡單地改變你的訪問此列d[[name.x]]的方式,它會工作:

d %>% group_by(id) %>% do(.[which.min(abs(.[[name.x]] -.[[name.y]])),]) 
0

由於0.4(這是發佈這個問題只是後回答),dplyr包括了標準的評估版本do_,這在理論上應該是比NSE版本更容易編程。

你可以同樣使用它:

interp <- lazyeval::interp 
d %>% 
    group_by(id) %>% 
    do_(interp(~ .[which.min(abs(.$x - .$y)), ], 
      x = as.name(name.x), y = as.name(name.y))) 

我不知道這是任何容易閱讀或大於NSE版本寫。對於其他動詞, code can remain concise同時也以編程方式訪問名稱。

但是,對於do_,必須使用圓點代名詞來訪問列名稱e.g. as discussed in this question。因此,我認爲,您始終需要使用interpdo_。這使得代碼在前面的答案中比NSE版本更加冗長。