首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将表示表达式的字符串传递给dplyr 0.7动词?

如何将表示表达式的字符串传递给dplyr 0.7动词?
EN

Stack Overflow用户
提问于 2017-06-17 00:07:00
回答 3查看 1.7K关注 0票数 5

我想了解如何将表示表达式的字符串传递给dplyr,以便将字符串中提到的变量作为dataframe中列的表达式进行计算。关于这个主题的main vignette介绍了如何传入查询,而根本不讨论字符串。

很明显,在表示表达式时,quosures比字符串更安全、更清晰,所以当可以使用quosures时,我们当然应该避免使用字符串。然而,当使用R生态系统之外的工具时,比如javascript或YAML配置文件,人们通常必须使用字符串而不是quosure。

例如,假设我想要一个使用用户/调用者传入的表达式进行分组计数的函数。正如预期的那样,以下代码不起作用,因为dplyr使用非标准计算来解释group_by的参数。

代码语言:javascript
复制
library(tidyverse)

group_by_and_tally <- function(data, groups) {
  data %>%
    group_by(groups) %>%
    tally()
}

my_groups <- c('2 * cyl', 'am')
mtcars %>%
  group_by_and_tally(my_groups)
#> Error in grouped_df_impl(data, unname(vars), drop): Column `groups` is unknown

在dplyr 0.5中,我们将使用标准评估,例如group_by_(.dots = groups),来处理这种情况。现在下划线动词被弃用了,我们应该如何在dplyr 0.7中做这样的事情呢?

在表达式只是列名的特殊情况下,我们可以使用this question的解决方案,但它们不适用于像2 * cyl这样不只是列名的更复杂的表达式。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-06-17 00:08:04

值得注意的是,在这个简单的示例中,我们可以控制如何创建表达式。因此,传递表达式的最佳方法是使用quos()直接构造和传递查询

代码语言:javascript
复制
library(tidyverse)
library(rlang)

group_by_and_tally <- function(data, groups) {
  data %>%
    group_by(UQS(groups)) %>%
    tally()
}

my_groups <- quos(2 * cyl, am)
mtcars %>%
  group_by_and_tally(my_groups)
#> # A tibble: 6 x 3
#> # Groups:   2 * cyl [?]
#>   `2 * cyl`    am     n
#>       <dbl> <dbl> <int>
#> 1         8     0     3
#> 2         8     1     8
#> 3        12     0     4
#> 4        12     1     3
#> 5        16     0    12
#> 6        16     1     2

但是,如果我们以字符串的形式从外部源接收表达式,我们可以简单地先解析表达式,这会将它们转换为查询:

代码语言:javascript
复制
my_groups <- c('2 * cyl', 'am')
my_groups <- my_groups %>% map(parse_quosure)
mtcars %>%
  group_by_and_tally(my_groups)
#> # A tibble: 6 x 3
#> # Groups:   2 * cyl [?]
#>   `2 * cyl`    am     n
#>       <dbl> <dbl> <int>
#> 1         8     0     3
#> 2         8     1     8
#> 3        12     0     4
#> 4        12     1     3
#> 5        16     0    12
#> 6        16     1     2

同样,我们应该只在从外部源获得表达式时才这样做,否则我们应该直接在R源代码中进行查询。

票数 10
EN

Stack Overflow用户

发布于 2017-06-17 00:46:15

使用字符串很诱人,但使用表达式几乎总是更好。现在你有了准引号,你可以很容易地以一种灵活的方式构建表达式:

代码语言:javascript
复制
lhs <- "cyl"
rhs <- "disp"
expr(!!sym(lhs) * !!sym(rhs))
#> cyl * disp

vars <- c("cyl", "disp")
expr(sum(!!!syms(vars)))
#> sum(cyl, disp)
票数 5
EN

Stack Overflow用户

发布于 2018-06-24 08:01:39

Package friendlyeval可以帮助您做到这一点:

代码语言:javascript
复制
library(tidyverse)
library(friendlyeval)

group_by_and_tally <- function(data, groups) {
  data %>%
    group_by(!!!friendlyeval::treat_strings_as_exprs(groups)) %>%
    tally()
}

my_groups <- c('2 * cyl', 'am')
mtcars %>%
  group_by_and_tally(my_groups)

# # A tibble: 6 x 3
# # Groups:   2 * cyl [?]
# `2 * cyl`    am     n
# <dbl> <dbl> <int>
# 1         8     0     3
# 2         8     1     8
# 3        12     0     4
# 4        12     1     3
# 5        16     0    12
# 6        16     1     2
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44593596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档