Dplyr "Arrange"函数在函数内传递参数时无法工作

3

我一直在查找有关在自定义函数中传递参数给dplyr函数的帖子,并且我无法解决以下情况:

我创建了以下功能来获取数据框的子集。

library(Lahman)

top_leaders <- function(df, metric, n) {
     # metric is the name of the column of Batting df which I would like to analyze
     # n is the number of top players leaders on that metric

    stat_leader <- enquo(metric)

    df %>%
      dplyr::select(playerID, !!stat_leader) %>% 
      dplyr::top_n(n)
  }

这个函数在对n个球员的领先状态进行子集划分时效果很好。例如:

> top_leaders(Lahman::Batting, "R", 5)
Selecting by R
   playerID   R
1 oneilti01 167
2 brownto01 177
3 hamilbi01 198
4  ruthba01 177
5 gehrilo01 167

然而,我希望结果是有序的,所以我使用了arrange函数按状态对其进行排序。

top_leaders <- function(df, metric, n) {
    stat_leader <- enquo(metric)

    df %>%
      dplyr::select(playerID, !!stat_leader) %>% 
      dplyr::top_n(n) %>%
      dplyr::arrange(desc(!!stat_leader))
  }

但是它会显示以下错误:

Selecting by R
 Error: incorrect size (1) at position 1, expecting : 5 

我后来尝试使用 arrange_(desc(!!stat_leader)),但仍然出现了错误:
Selecting by R
 Error: Quosures can only be unquoted within a quasiquotation context.

  # Bad:
  list(!!myquosure)

  # Good:
  dplyr::mutate(data, !!myquosure)

我完全不知道如何解决这个问题。


当您使用裸列名称调用它时,例如 R 而不是 "R",它是否有效?这是这些基于 dplyr 的函数中的惯例。 - camille
2个回答

2
利用Rlang的新大括号符号
top_leaders <- function(df, playerID, metric, n) {
  df %>%
    dplyr::select({{playerID}}, {{metric}}) %>% 
    dplyr::top_n(n) %>%
    dplyr::arrange(desc({{metric}})) %>% 
    return(.)
}

top_leaders(as_tibble(Lahman::Batting), playerID, R, 5)

#Selecting by R
## A tibble: 5 x 2
#  playerID      R
#  <chr>     <int>
#1 hamilbi01   198
#2 brownto01   177
#3 ruthba01    177
#4 oneilti01   167
#5 gehrilo01   167

你还需要将playerID传递给该函数,但这只是一个小改动。

1
我们可能需要在这里转换为符号,因为我们正在传递一个字符串。
top_leaders <- function(df, metric, n) {
    stat_leader <- ensym(metric)

     df %>%
       dplyr::select(playerID, !!stat_leader) %>% 
       dplyr::top_n(n) %>%
       dplyr::arrange(desc(!!stat_leader))
     }
top_leaders(Lahman::Batting, "R", 5)
#Selecting by R
#   playerID   R
#1 hamilbi01 198
#2 brownto01 177
#3  ruthba01 177
#4 oneilti01 167
#5 gehrilo01 167

如果我们传递未加引号的变量名,它也可以工作。
top_leaders(Lahman::Batting, R, 5)
#Selecting by R
#   playerID   R
#1 hamilbi01 198
#2 brownto01 177
#3  ruthba01 177
#4 oneilti01 167
#5 gehrilo01 167

使用OP的函数时,它只期望未引用的参数而不是带引号的参数。

1
谢谢@akrun。这个也可以,而且在引用参数时灵活性很好。 - darh78

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接