0

我在使用 dplyr 编写函数时尝试使用新的 quo 功能并遇到以下问题:

df <- tibble(
  g1 = c(1, 1, 2, 2, 2),
  g2 = c(1, 2, 1, 3, 1),
  a = sample(5), 
  b = sample(5)
)

按变量排列数据框很简单:

my_arrange <- function(df, arrange_var) {
  quo_arrange_var <- enquo(arrange_var)
  df %>%
    arrange(!!quo_arrange_var)
}

但是如果我想设置优惠订单怎么办?例如,任何排列变量都有 2 作为顶部变量,然后正常排序。使用以前版本的 dplyr 我会使用:

arrange(-(arrange_var == 2), arrange_var)

但在新结构中,我不确定如何处理。我努力了:

my_arrange <- function(df, arrange_var) {
  quo_arrange_var <- enquo(arrange_var)

  df %>%
    arrange(-!!quo_arrange_var==2, !!quo_arrange_var)
}

但我得到了错误

 Error in arrange_impl(.data, dots) : 
  incorrect size (1) at position 1, expecting : 5 

我也尝试过使用 quo_name:

my_arrange <- function(df, arrange_var) {
  quo_arrange_var <- enquo(arrange_var)

  df %>%
    arrange(-!!(paste0(quo_name(quo_arrange_var), "==2")), !!quo_arrange_var)
}

但得到这个错误:

 Error in arrange_impl(.data, dots) : 
  Evaluation error: invalid argument to unary operator. 

任何帮助,将不胜感激

4

1 回答 1

1

最简单的解决方法是在 bang-bang 周围加上括号。这与 和 的运算符优先级!有关==。如果你有!!a==b,它会被解析为!!(a==b)即使你想要(!!a)==b的。quo(a)==2并且由于某种原因,您可以将 quosure 与返回的数值进行比较,FALSE因此您的表达式正在评估arrange(-FALSE, g2)哪个会给您相同的错误消息。

my_arrange <- function(df, arrange_var) {
  quo_arrange_var <- enquo(arrange_var)

  df %>%
    arrange(-((!!quo_arrange_var)==2), !!quo_arrange_var)
}
my_arrange(df, g2)
# # A tibble: 5 x 4
#      g1    g2     a     b
#   <dbl> <dbl> <int> <int>
# 1     1     2     5     4
# 2     1     1     2     5
# 3     2     1     4     3
# 4     2     1     3     1
# 5     2     3     1     2
于 2017-07-13T21:24:18.110 回答