【发布时间】: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