在dplyr中使用变量列名(do)

时间:2014-11-04 15:35:59

标签: r variables dplyr

我有以下示例数据

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)),])

问题是,如果日期列的名称保存在dplyrname.x="date.x"之类的变量中,我将如何使用name.y="date.y",因为我无法使用

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

我尝试使用evalas.symbol这样的东西找到另一个解决方案,但我找不到解决方案......

2 个答案:

答案 0 :(得分:3)

d$date.x返回一个向量,而d[, name.x]返回一个data.frame,在函数内部传递时不起作用。因此,只需将您访问此列的方式更改为d[[name.x]]即可:

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

答案 1 :(得分: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。因此,我认为,您始终需要interp使用do_。这使得代码比早期答案中的NSE版本更加冗长。