【问题标题】:tidyr use glue strings later in functiontidyr 稍后在函数中使用胶水字符串
【发布时间】:2021-07-04 11:39:42
【问题描述】:

Tidy eval now supports glue strings

所以这很好用:

my_summarise5 <- function(data, mean_var ) {
  data %>% 
    mutate(
      "mean_{{mean_var}}" := mean({{ mean_var }}), 
    ) 
}

mtcars %>% my_summarise5(cyl)

然后

my_summarise5 <- function(data, mean_var ) {
  data %>% 
    mutate(
      "mean_{{mean_var}}" := mean({{ mean_var }}), 
    "mean_{{mean_var}}_plusone" :=  "mean_{{mean_var}}"+1
    )
}

mtcars %>% my_summarise5(cyl)

投掷

Error: Problem with `mutate()` input `mean_cyl_plusone`.
x non-numeric argument to binary

"mean_{{mean_var}}_plusone" := "mean_{{mean_var}}"+1 部分中的一些“粘贴”或“胶水”可以解决此问题吗?

请注意,这显然不是一个有用的案例,它是语法的 MWE。我实际上想定义两个具有不同名称的新列,一个使用另一个...否则我必须重复它也会变得混乱。

【问题讨论】:

    标签: r function dplyr tidyeval quasiquotes


    【解决方案1】:

    跨界使用:

    my_summarise5 <- function(data, mean_var ) {
      data %>% 
        mutate(
          "mean_{{mean_var}}" := mean({{ mean_var }}),
          across(last_col(), ~.+1, .names = "{col}_plusone")
        )
    }
    
    mtcars %>% my_summarise5(cyl) %>% head
    

    给予:

                       mpg cyl disp  hp drat    wt  qsec vs am gear carb mean_cyl mean_cyl_plusone
    Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4   6.1875           7.1875
    Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4   6.1875           7.1875
    Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1   6.1875           7.1875
    Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1   6.1875           7.1875
    Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2   6.1875           7.1875
    Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1   6.1875           7.1875
    

    【讨论】:

    • 我也忘记了“.names”!
    【解决方案2】:

    我喜欢 tidyverse,但使用 base R 可以带来巨大的回报,让您的代码具有可读性和可维护性。

    my_summarise5 <- function (data, mean_var) {
      mean_name <- paste0("mean_", mean_var)
      plus_one_name <- paste0(mean_name, "_plus_one")
    
      data[[mean_name]] <- mean(data[[mean_var]])
      data[[plus_one_name]] <- data[[mean_name]] + 1
    
      data
    }
    

    任何懂R的人都可以理解以上内容。

    tmp <- data.frame(a = 1:5)
    my_summarise5(tmp, "a")
    ##   a mean_a mean_a_plus_one
    ## 1 1      3               4
    ## 2 2      3               4
    ## 3 3      3               4
    ## 4 4      3               4
    ## 5 5      3               4
    
    

    如果你想将一个裸符号作为mean_var 传递,那么只需将此行添加到函数的开头:

    mean_var <- as.character(substitute(mean_var))
    

    这并不完美,因为它会破坏深度嵌套的函数。因此,您可以通过(类似)mean_var &lt;- enquo(mean_var) 来混合一些 tidyverse。但我仍然更喜欢简单的数据操作,而不是 mutateacross

    【讨论】:

      猜你喜欢
      • 2020-11-27
      • 2020-11-01
      • 1970-01-01
      • 2021-05-30
      • 2015-11-27
      • 2022-01-23
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多