如何使用glue语法和rlang转换和过滤函数中的多个变量,而无需输入变量名称?

问题描述 投票:0回答:1

查看之前问题的答案后(例如 which-rlang-function-should-i-use-to-evaluate-a-glue-string-as-a-variable-nameglue-and-rlang -how-to-tunnel-data-variables-within-a-glue-string),我创建了一个 reprex,可以在不同情况下使用粘合语法和 rlang 函数(使用

case_when()
pivot_longer()
mutate() 
,...)。

如果您发现一些可能的改进可以添加到我的代码中,请随时发表评论。

r rlang r-glue
1个回答
0
投票
my_mean <- function(data,
                   input_var1,
                   output_var) {
  input_var1_name_torgersen <- rlang::englue("{{ input_var1 }}.Torgersen")
  input_var1_name_biscoe <- rlang::englue("{{ input_var1 }}.Biscoe")
  input_var1 <- rlang::englue("{{ input_var1 }}")
  output_name_torgersen <- rlang::englue("{{ output_var }}.Torgersen")
  output_name_biscoe <- rlang::englue("{{ output_var }}.Biscoe")

  data |>
    dplyr::filter(
      dplyr::case_when(
        species == input_var1 ~ island == "Torgersen" | island == "Biscoe"
      )
    ) |>
    tidyr::pivot_wider(
      names_from = c(species, island),
      names_sep = ".",
      values_from = body_mass_g
    ) |>
    dplyr::group_by(year, sex) |> 
    dplyr::summarise(
      "{input_var1_name_torgersen}" := dplyr::coalesce(eval(rlang::sym(input_var1_name_torgersen)), 0),
      "{input_var1_name_biscoe}" := dplyr::coalesce(eval(rlang::sym(input_var1_name_biscoe)), 0),
      "{output_name_torgersen}" := mean(eval(rlang::sym(input_var1_name_torgersen))),
      "{output_name_biscoe}" := mean(eval(rlang::sym(input_var1_name_biscoe)))
    ) |>
    dplyr::relocate(year, sex) |>
    tidyr::pivot_longer(
      cols = all_of(c(output_name_torgersen, output_name_biscoe)),
      names_to = "species.stat.island",
      values_to = "mean_body_mass_g_per_year_sex"
    ) |>
    dplyr::select(-species.stat.island)  |> 
    tidyr::pivot_longer(
      cols = all_of(c(input_var1_name_torgersen, input_var1_name_biscoe)),
      names_to = "species.island",
      values_to = "body_mass_g"
    ) |>
    tidyr::separate_wider_delim(
      cols = species.island,
      delim = ".",
      names = c("species", "island")
    ) |> 
    dplyr::relocate(c(species, island, body_mass_g), .after = sex) |> 
    dplyr::distinct(year, sex, species, island, .keep_all = TRUE) |> 
    tidyr::drop_na(sex)
}
out <- palmerpenguins::penguins |>
  dplyr::mutate(
    species = as.character(species),
    island = as.character(island)
  ) |>
  my_mean(
    input_var1 = Adelie,
    output_var = Adelie.mean_bodymass
  )
#> Warning: Returning more (or less) than 1 row per `summarise()` group was deprecated in
#> dplyr 1.1.0.
#> ℹ Please use `reframe()` instead.
#> ℹ When switching from `summarise()` to `reframe()`, remember that `reframe()`
#>   always returns an ungrouped data frame and adjust accordingly.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.
#> `summarise()` has grouped output by 'year', 'sex'. You can override using the
#> `.groups` argument.
out
#> # A tibble: 12 × 6
#> # Groups:   year, sex [6]
#>     year sex    species island    body_mass_g mean_body_mass_g_per_year_sex
#>    <int> <fct>  <chr>   <chr>           <dbl>                         <dbl>
#>  1  2007 female Adelie  Torgersen        3800                         2138.
#>  2  2007 female Adelie  Biscoe              0                         2138.
#>  3  2007 male   Adelie  Torgersen        3750                         2415.
#>  4  2007 male   Adelie  Biscoe              0                         2415.
#>  5  2008 female Adelie  Torgersen           0                         1656.
#>  6  2008 female Adelie  Biscoe           3500                         1656.
#>  7  2008 male   Adelie  Torgersen           0                         1974.
#>  8  2008 male   Adelie  Biscoe           4300                         1974.
#>  9  2009 female Adelie  Torgersen           0                         1597.
#> 10  2009 female Adelie  Biscoe           3725                         1597.
#> 11  2009 male   Adelie  Torgersen           0                         1892.
#> 12  2009 male   Adelie  Biscoe           4725                         1892.
out |> dplyr::glimpse()
#> Rows: 12
#> Columns: 6
#> Groups: year, sex [6]
#> $ year                          <int> 2007, 2007, 2007, 2007, 2008, 2008, 2008…
#> $ sex                           <fct> female, female, male, male, female, fema…
#> $ species                       <chr> "Adelie", "Adelie", "Adelie", "Adelie", …
#> $ island                        <chr> "Torgersen", "Biscoe", "Torgersen", "Bis…
#> $ body_mass_g                   <dbl> 3800, 0, 3750, 0, 0, 3500, 0, 4300, 0, 3…
#> $ mean_body_mass_g_per_year_sex <dbl> 2138.462, 2138.462, 2414.583, 2414.583, …
© www.soinside.com 2019 - 2024. All rights reserved.