【问题标题】:rlang: Curly curly operator and tunneling data-variables inside strings on RHSrlang:卷曲的卷曲运算符和在 RHS 上的字符串内隧道数据变量
【发布时间】:2021-05-09 18:59:08
【问题描述】:

我认为 curly curly 是 bang bang 的一个很好的继承者。尽管如此,我仍然在努力理解 tidyverse NSE。

假设我想创建一个在数据帧上运行的简单函数,它采用多列,以长格式重新调整它们,并从生成的重新调整的列中提取因子。我还想要定义因子水平的能力,或者默认情况下将它们按照所选列在重塑过程之前的顺序排列。

我使用 bang bang 和 curly 编写了相同的函数。

library(tidyverse)

df_test <- data.frame(
  id = c("id1", "id2"),
  item1 = c(0, 4),
  item2 = c(3, 2),
  item3 = c(1, 4),
  item4 = c(3, 4),
  item5 = c(1, NA)
)

# Bang bang way
vars_factor_to_long <- function(data, vars) {                     
  vars_enq <- rlang::enquo(vars)
  vars_name <- unname(tidyselect::vars_select(unique(names(data)), !!vars_enq))
  data <-
    data %>%
    tidyr::pivot_longer(cols = !!vars_enq, names_to = "item", values_to = "value") %>%
    dplyr::mutate(item = factor(item, levels = vars_name)) 
  data
}

vars_factor_to_long(df_test, item1:item5)
#> # A tibble: 10 x 3
#>    id    item  value
#>    <fct> <fct> <dbl>
#>  1 id1   item1     0
#>  2 id1   item2     3
#>  3 id1   item3     1
#>  4 id1   item4     3
#>  5 id1   item5     1
#>  6 id2   item1     4
#>  7 id2   item2     2
#>  8 id2   item3     4
#>  9 id2   item4     4
#> 10 id2   item5    NA

# Curly curly way works the same, but doesn't need the enquo
vars_factor_to_long2 <- function(data, vars) {                     
  vars_name <- unname(tidyselect::vars_select(unique(names(data)), {{vars}}))
  data <-
    data %>%
    tidyr::pivot_longer(cols = {{vars}}, names_to = "item", values_to = "value") %>%
    dplyr::mutate(item = factor(item, levels = vars_name))
    data
}

vars_factor_to_long2(df_test, item1:item5)
#> # A tibble: 10 x 3
#>    id    item  value
#>    <fct> <fct> <dbl>
#>  1 id1   item1     0
#>  2 id1   item2     3
#>  3 id1   item3     1
#>  4 id1   item4     3
#>  5 id1   item5     1
#>  6 id2   item1     4
#>  7 id2   item2     2
#>  8 id2   item3     4
#>  9 id2   item4     4
#> 10 id2   item5    NA

reprex package (v0.3.0) 于 2021-02-05 创建

这很好用,但我发现数据变量可以通过使用类似于glue 的语法在带有卷曲的字符串内部进行隧道传输。例如:

# Curly curly - tunneling data-variable inside strings with glue-like syntax
mean_by <- function(data, by, vars) {
  data %>%
    group_by({{ by }}) %>%
    summarise("{{ vars }}" := mean({{ vars }}, na.rm = TRUE))
}

mean_by(df_test, id, item1)
#> # A tibble: 2 x 2
#>   id    item1
#>   <fct> <dbl>
#> 1 id1       0
#> 2 id2       4
mean_by(df_test, id, item1:item2)
#> # A tibble: 2 x 2
#>   id    `item1:item2`
#>   <fct>         <dbl>
#> 1 id1             1.5
#> 2 id2             3

reprex package (v0.3.0) 于 2021-02-05 创建

有没有一种方法可以将数据变量名称(如第二个示例中)用作第一个示例中函数的因子级别?我怀疑如果提供了多个列,这种隧道会出现问题,但是,我怎样才能将至少一个列名隧道传输到 RHS?

关于这个新的 rlang 主题的任何讨论都会帮助我理解更多。 谢谢。

【问题讨论】:

    标签: r tidyverse rlang tidyeval


    【解决方案1】:

    无论如何,您都需要隧道用户选择然后获取名称,所以我认为您的方法很好。我会通过使用 dplyr 而不是低级别的 tidyselect 来简化它:

    vars_factor_to_long2 <- function(data, vars) {
      vars <- names(dplyr::select(data, {{ vars }}))
    
      data %>%
        tidyr::pivot_longer(
          cols = all_of(vars),
          names_to = "item",
          values_to = "value"
        ) %>%
        dplyr::mutate(
          item = factor(item, levels = vars)
        )
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 2021-07-04
      • 1970-01-01
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-10
      相关资源
      最近更新 更多