标签: rlang

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

我想了解如何将表示表达式的字符串传递给dplyr,以便将字符串中提到的变量计算为数据帧中列的表达式.关于这个主题的主要内容包括传递,并且根本不讨论字符串.

很明显,在表示表达式时,quosures比字符串更安全,更清晰,所以当使用quosures时我们当然应该避免使用字符串.但是,在使用R生态系统之外的工具(例如javascript或YAML配置文件)时,通常需要使用字符串而不是quosures.

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

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
Run Code Online (Sandbox Code Playgroud)

在dplyr 0.5中,我们将使用标准评估group_by_(.dots = groups)来处理这种情况.既然下划线动词已弃用,我们应该如何在dplyr 0.7中执行此类操作?

在只是列名的表达式的特殊情况下,我们可以使用这个问题的解决方案,但它们不适用于更复杂的表达式,例如2 * cyl不仅仅是列名.

r dplyr tidyeval rlang

4
推荐指数
2
解决办法
1472
查看次数

在dplyr 0.7+功能中重命名

我在使用dplyr重命名函数中的列时遇到困难.我已经找到了关于非标准评估和enquo的使用的有用帖子(例如,http://dplyr.tidyverse.org/articles/programming.html 和 在自定义dplyr函数中更改结果变量的名称).最终目标是使用该函数汇总每个组,然后将列重命名为比原始变量名更有意义的列.

这是一个简单的例子,除了注释掉的行外,它都有效.

library(tidyverse)

myfunc <- function(df, groupvar, colvar, grouplab, collab) {
  groupvar <- enquo(groupvar)
  colvar <- enquo(colvar)
  grouplab <- enquo(grouplab)  # quo_name instead?
  collab <- enquo(collab)  # quo_name instead?

t <- df %>%
  select(!!groupvar, !!colvar) %>%
  group_by(!!groupvar, !!colvar) %>%
  summarise(
    Frequencies = length(!!colvar),
    Percentages = length(!!colvar) / nrow(df)
    ) %>%
  mutate(
    Frequencies = scales::comma(Frequencies),
    Percentages = scales::percent(Percentages)
    ) #%>%
# rename(
#    (!!grouplab) = !!groupvar,  # add a more descriptive grouping var label
#    (!!collab) …
Run Code Online (Sandbox Code Playgroud)

r function dplyr nse rlang

4
推荐指数
2
解决办法
1276
查看次数

将列名称的向量传递给mutate中的paste()(dplyr)

我正在尝试编写一个函数,它将来自用户的列名称向量作为其参数之一.列名将用于指定将数据帧的哪些列粘贴在一起以在dplyr :: mutate中形成新列.我试图首先折叠参数向量的元素,然后在mutate中使用折叠的字符串 - 这是错误的.请参阅下面的最新尝试.我做了其他尝试,但我不理解dplyr中的新quo,enquo,UQ,!!!,!!等等.有人可以展示我需要做什么吗?

df <- data.frame(.yr = c("2000", "2001", "2002"), .mo = c("12", "01", "02"), .other = rnorm(3))
cols <- colnames(df)[1:2]

do_want <- df %>%
  mutate(new = paste(.yr, .mo, sep = "-"))

my_func <- function(dat, vars){
  .vars <- paste(vars, collapse = ",")

  result <- dat %>%
    mutate(new = paste(.vars, sep = "-" ))
  return(result)
}

my_func(dat = df, vars = cols)
Run Code Online (Sandbox Code Playgroud)

编辑:这是我尝试使用quo和!! 在函数定义中.结果是一列重复的字符串".yr,.mo"

my_func <- function(dat, vars){
  .vars <- quo(paste(vars, collapse = ","))

  result <- dat %>%
    mutate(new …
Run Code Online (Sandbox Code Playgroud)

r dplyr rlang

4
推荐指数
1
解决办法
3522
查看次数

在函数中传播多个列

通常我需要spread多个值列,就像在这个问题中一样.但我经常这样做,我希望能够编写一个这样做的功能.

例如,给定数据:

set.seed(42)
dat <- data_frame(id = rep(1:2,each = 2),
                  grp = rep(letters[1:2],times = 2),
                  avg = rnorm(4),
                  sd = runif(4))
> dat
# A tibble: 4 x 4
     id   grp        avg        sd
  <int> <chr>      <dbl>     <dbl>
1     1     a  1.3709584 0.6569923
2     1     b -0.5646982 0.7050648
3     2     a  0.3631284 0.4577418
4     2     b  0.6328626 0.7191123
Run Code Online (Sandbox Code Playgroud)

我想创建一个返回类似的函数:

# A tibble: 2 x 5
     id     a_avg      b_avg      a_sd      b_sd
  <int>     <dbl>      <dbl>     <dbl>     <dbl>
1     1 …
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyr rlang

4
推荐指数
1
解决办法
2051
查看次数

rlang包中sym()和parse_expr()有什么区别?

使用rlang包,我想知道sym()和parse_expr()之间有什么区别.考虑以下表达式:

ex1 = sym('a')
ex2 = parse_expr('a')
Run Code Online (Sandbox Code Playgroud)

他们都回来了

a

identical(ex1, ex2)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

假设我现在需要一个问题:

ex3 = quo(!!sym('a'))
ex4 = quo(!!parse_expr('a'))
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,结果是:

<quosure>
expr: ^a
env:  global

identical(ex3, ex4)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

但是,由于某些原因,以下两个不一样.

ex5 = quo(!!sym('a - b'))
ex6 = quo(!!parse_expr('a - b'))
Run Code Online (Sandbox Code Playgroud)

显然他们两个都是相同的:

<quosure>
expr: ^a - b
env:  global
Run Code Online (Sandbox Code Playgroud)

然而,

identical(ex5, ex6)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

我的一些问题是sym()和parse_expr()之间有什么区别?一个人做了什么,另一个不能?为什么ex5显然与ex6相似但相同(ex5,ex6)返回FALSE?

string evaluation r rlang

4
推荐指数
1
解决办法
1293
查看次数

如何计算R quosure中的变量数?

假设我有一个函数,它使用非标准评估(NSE)从该数据框中获取数据框和不同数量的变量.是否有更快/更直接的方法来计算提供的变量数量而不是select()这些变量并计算列数?

# Works but seems non-ideal
nvar <- function(df, vars) {
  vars_en <- rlang::enquo(vars)
  df_sub <- dplyr::select(df, !!vars_en)
  ncol(df_sub)
}
nvar(mtcars, mpg:hp)
#> 4
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyverse tidyeval rlang

4
推荐指数
1
解决办法
116
查看次数

R如何使用带有filter或filter_的curl curl?

我在评论者建议!! ensym的地方回答这个问题,我认为这可能是使用卷曲{{的好地方,但我无法使其正常工作(也许不适用?)。

在不使用filter_,eval / parse或quote-unquote的情况下,如何执行此过滤器操作?会帮助吗?

我的解决方案(1g)使用filter_和使用粘贴建立的条件。1a有效(但是可以使用{{}}吗?)

如果我们想按多个变量过滤该怎么办?这是您看到2g在下面工作的地方(而2a不再工作了)。

library(tidyverse)
set.seed(1234)
A <- matrix(rnorm(30),nrow = 10, ncol = 3) %>% as_tibble() %>% set_names(paste("var", seq(1:3), sep = ""))
varnames_1 <- c("var2")

(expected_result_1 <- filter(A, var2 > 0))
#> # A tibble: 3 x 3
#>     var1   var2   var3
#>    <dbl>  <dbl>  <dbl>
#> 1 -2.35  0.0645  0.460
#> 2  0.429 0.959  -0.694
#> 3 -0.890 2.42   -0.936

(answer_1a <- filter(A,!!ensym(varnames_1) > 0)) # works (thanks joran and aosmith)
#> # A …
Run Code Online (Sandbox Code Playgroud)

r filter dplyr tidyeval rlang

4
推荐指数
2
解决办法
165
查看次数

使用带有 `dplyr::_join` 函数的 `rlang` quasiquotation

我正在尝试编写一个自定义函数,在其中使用rlang's quasiquotation。此函数也在内部使用dplyrjoin函数。我在下面提供了一个最小的工作示例来说明我的问题。

# needed libraries 
library(tidyverse)

# function definition
df_combiner <- function(data, x, group.by) {
  # check how many variables were entered for this grouping variable
  group.by <- as.list(rlang::quo_squash(rlang::enquo(group.by)))

  # based on number of arguments, select `group.by` in cases like `c(cyl)`,
  # the first list element after `quo_squash` will be `c` which we don't need,
  # but if we pass just `cyl`, there is no `c`, this will take care of that
  # issue …
Run Code Online (Sandbox Code Playgroud)

r dplyr rlang quasiquotes

4
推荐指数
1
解决办法
228
查看次数

在 R 包中使用 tidy eval

我有一个stacked_plot()使用整洁评估来制作堆叠图的函数。我想将它包含在我的包中,并从该包中调用另一个函数来调用它。这是最小的例子:

stacked_plot <- function(data, what, by = NULL, date_col = date){

  by <- rlang::enquo(by)
  what <- rlang::ensym(what)
  date_col <- rlang::ensym(date_col)
  data <- data %>%
    dplyr::group_by(!!date_col, !!by) %>%
    dplyr::summarise(!!what := sum(!!what, na.rm = TRUE)) %>%
    dplyr::ungroup() %>%
    tidyr::complete(!!date_col, !!by, fill = rlang::list2(!!what := 0))

  p <- data %>%
    ggplot2::ggplot(ggplot2::aes(!!date_col, !!what, fill = !!by)) +
    ggplot2::geom_area(position = 'stack')
  print(p)
}

#' @importFrom rlang .data
call_plot <- function() {
  to_plot <- data.frame(date = rep(seq(lubridate::ymd('2020-01-01'),
                                       lubridate::ymd('2020-03-30'),
                                       by = '1 day'), each = …
Run Code Online (Sandbox Code Playgroud)

r dplyr r-package tidyeval rlang

4
推荐指数
1
解决办法
193
查看次数

Dplyr,非标准评估和海象算子和卷曲卷曲

一个真正的问题。每当我需要编写 dplyr 函数时,我都在旁听。我知道 curl-curly 运算符可以简化很多任务。

https://www.tidyverse.org/blog/2019/06/rlang-0-4-0/

https://www.tidyverse.org/blog/2020/02/glue-strings-and-tidy-eval/

我不清楚什么时候使用简单的“=”和海象运算符“:=”。例如,考虑帖子末尾的片段。函数mean_by 和mean_by2 的不同只是因为前者依赖于“=”,后者依赖于“:=”,但结果是一样的。但是,如果我尝试编写一个依赖于 mutate 来添加新列的函数,如果我在创建新列时使用“=”而不是“:=”,我会收到一条错误消息。有人可以向我澄清为什么不同吗?这是否意味着使用 Walrus 运算符而不是“=”更安全?

谢谢!

library(tidyverse)


mean_by <- function(data, by, var) {
  data %>%
    group_by({{ by }}) %>%
    summarise(avg = mean({{ var }}, na.rm = TRUE))
}



mean_by2 <- function(data, by, var) {
  data %>%
    group_by({{ by }}) %>%
    summarise(avg := mean({{ var }}, na.rm = TRUE))
}



add_new_col <- function(data, old_col, new_col){

    data %>%
        mutate({{new_col}}:={{old_col}})


}


iris %>% mean_by(Species, Sepal.Width)
#> # A tibble: 3 x 2
#> …
Run Code Online (Sandbox Code Playgroud)

r dplyr nse rlang

4
推荐指数
1
解决办法
603
查看次数

标签 统计

r ×10

rlang ×10

dplyr ×9

tidyeval ×4

nse ×2

evaluation ×1

filter ×1

function ×1

quasiquotes ×1

r-package ×1

string ×1

tidyr ×1

tidyverse ×1