简体   繁体   中英

Pass character string of column names (e.g. "c(speed, dist") to `across` function in R

Consider the following toy problem. I would like to round drat and wt . Here is the normal way to do this:

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

But what I want to do is select drat and wt from the data. Like below (doesn't run). How might I do this?

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.

Created on 2021-10-25 by the reprex package (v2.0.1)

You can't use substitute() or eval() on character vectors. You need to parse those character vectors into language objects. Otherwise when you eval a string, you just get that string back. It's not like eval in other languages. One way to do the parsing is str2lang . Then you can inject that expression into the across using tidy evaulation's !! . For example

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM