【问题标题】:Using purrr and dplyr: is rlang::sym the best way使用 purrr 和 dplyr: 是 rlang::sym 最好的方法
【发布时间】:2018-01-06 20:28:49
【问题描述】:

我想编写使用 dplyr 动词的函数,这意味着我必须涉足 rlang 的浑水。

举一个具体的例子,假设我想使用purrr::map_df() 来迭代dplyr::group_by() 中的变量。 programming with dplyr 小插图介绍了编写 my_summarise() 函数;方法是在分组变量上使用rlang::enquo(),然后用!! 取消引用。 这种方法可以创建一个新的类似 dplyr 的函数,该函数采用不带引号的变量名(小插图中的my_summarise(df, g1))。

相比之下,我想将变量名作为字符串提供。 rlang::sym() 是正确的方法吗?似乎不是,因为在 dplyr 编程小插图中没有提到 sym(),在 rlang tidy evaluation article 中也几乎没有提到。有没有更好的办法?

library(tidyverse)
my_summarise <- function(df, group_var) {
  group_var <- rlang::sym(group_var)

  df %>%
    group_by(!!group_var) %>%
    summarise(mpg = mean(mpg))
}

# This works. Is that a good thing?
purrr::map_df(c("cyl", "am"), my_summarise, df = mtcars)

# A tibble: 5 x 3
    cyl   mpg    am
  <dbl> <dbl> <dbl>
1  4.00  26.7 NA   
2  6.00  19.7 NA   
3  8.00  15.1 NA   
4 NA     17.1  0   
5 NA     24.4  1.00

作为后续,为什么有时简单地取消引用(没有先应用enquosym)会起作用?在下面的示例中,为什么 select() 可以按预期工作,而 group_by() 不能?

x <- "cyl"
select(mtcars, !!x)
group_by(mtcars, !!x)

更新:答案不是取消引用。就是select更灵活,可以处理字符串,而group_by不能。

其他参考:这是 Edwin Thoen 的 blog post

【问题讨论】:

  • 我只想说,最近,使用 sym() 已经解决了我所有看似无法解决的引用问题。有时!!sym() 尤其是当有表达式时。另外,我认为最好将其分为两个问题。
  • 小插图草稿确实使用了symrpubs.com/lionel-/programming-draft
  • 谢谢@Elin 和@G-Grothendieck!

标签: r dplyr purrr rlang


【解决方案1】:

简短回答:是的。

如果您想在列上使用mapsym 是一个很好的方法。 Lionel Henry 在draft vignette 中演示了sym

如果您想传递列名,但不尝试迭代,Kirill Müller prefers quo。在下面的示例中,它们具有相同的效果。

library(dplyr)

x <- rlang::quo(cyl)
y <- rlang::sym("cyl")
identical(group_by(mtcars, !!x), group_by(mtcars, !!y))  # TRUE

【讨论】:

猜你喜欢
  • 2021-03-30
  • 2018-08-18
  • 2019-02-04
  • 2020-02-29
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多