1

我正在尝试了解有关dplyr编程和非标准评估的新实现。所以verb_函数被enquo参数替换,然后应用!!在常规动词函数中。从select旧到新的工作正常,以下函数给出了类似的结果:

select_old <- function(x, ...) {
  vars <- as.character(match.call())[-(1:2)]
  x %>% select(vars)
}

select_new <- function(x, ...) {
  vars <- as.character(match.call())[-(1:2)]
  vars_enq <- enquo(vars)
  x %>% select(!!vars_enq)
}

但是,当我尝试使用arrange新的编程风格时,我会得到一个错误:

arrange_old <- function(x, ...) {
  vars <- as.character(match.call())[-(1:2)]
  x %>% arrange_(vars)
}

arrange_new <- function(x, ...){
  vars <- as.character(match.call())[-(1:2)]
  vars_enq <- enquo(vars)
  x %>% arrange(!!vars_enq)
}

mtcars %>% arrange_new(cyl)     
# Error in arrange_impl(.data, dots) : 
#  incorrect size (1) at position 1, expecting : 32

32 显然是 的行数mtcars, 的内部函数dplyr显然需要这个长度的向量。我的问题是为什么新的编程风格不适用arrange以及如何以新的风格进行翻译。

4

2 回答 2

2

你想多了。使用相应的函数来处理...。根本不需要使用match.call(在旧版本中也不需要,真的)。

arrange_new <- function(x, ...){
  dots <- quos(...)
  x %>% arrange(!!!dots)
}

当然这个函数和 normal 完全一样arrange,但我猜你只是用这个作为例子。

你可以用同样的方法写一个select函数。

arrange_old应该看起来像:

arrange_old <- function(x, ...){
  dots <- lazyeval::lazy_dots(...)
  x %>% arrange_(.dots = dots)
}
于 2017-07-19T09:11:05.333 回答
1

在这种情况下,您实际上不需要 rlang。这将起作用:

my_arrange <- function(x, ...) arrange(x, ...)

# test
DF <- data.frame(a = c(2, 2, 1, 1), b = 4:1)
DF %>% my_arrange(a, b)
于 2017-07-19T11:57:28.407 回答