【问题标题】:Pass character string of column names (e.g. "c(speed, dist") to `across` function in R将列名的字符串(例如“c(speed,dist”)传递给R中的`across`函数
【发布时间】:2021-12-11 05:55:36
【问题描述】:

考虑以下玩具问题。 我想四舍五入dratwt。 这是执行此操作的常规方法:

library(tidyverse)
mtcars[1 ,5:7] %>% 
  mutate(across(.cols = c(drat, wt), .fns = round))
#>           drat wt  qsec
#> Mazda RX4    4  3 16.46

但我想做的是从数据中选择dratwt。 如下所示(不运行)。 我该怎么做?

mtcars_2 <- 
  mtcars[1 ,5:7] %>%
  bind_cols(data.frame(cols_to_modify = "c(drat, wt)"))

## view data
mtcars_2
#>           drat   wt  qsec cols_to_modify
#> Mazda RX4  3.9 2.62 16.46    c(drat, wt)

## my failed attempt
mtcars_2 %>% 
  mutate(across(.cols = eval(substitute(.$cols)),.fns = round))
#> Error: Problem with `mutate()` input `..1`.
#> ℹ `..1 = across(.cols = eval(substitute(.$cols)), .fns = round)`.
#> x Can't subset columns that don't exist.
#> x Column `c(drat, wt)` doesn't exist.

reprex package 创建于 2021-10-25 (v2.0.1)

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您不能在字符向量上使用substitute()eval()。您需要将这些字符向量解析为语言对象。否则,当你评估一个字符串时,你只会得到那个字符串。它不像其他语言中的eval。进行解析的一种方法是str2lang。然后,您可以使用 tidy evaluation 的 !! 将该表达式注入到 across 中。例如

    mtcars_2 %>% 
      mutate(across(.cols = !!str2lang(.$cols_to_modify),.fns = round))
    

    【讨论】:

    • 太棒了!非常感谢!顺便说一句,您建议我阅读什么以最终正确理解evalstr2langstr2expression 和其他类似功能?
    • 你可以通过Advanced R book。但实际上这里的问题似乎更多地与尝试将代码作为文本存储在 data.frame 的列中有关。最好不要一开始就这样做。也许只需使用列表列来保存名称向量,而不需要解析步骤。不得不说不知道你为什么要这样做。
    猜你喜欢
    • 2021-06-21
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    相关资源
    最近更新 更多