简体   繁体   中英

How to pass multiple columns as string to function in dplyr::mutate_at

I have the following (heavily simplified) dplyr example for mutate :

xx <- data.frame(x = 1:10, y = c(rep(1,4),rep(2,6)))
bla_fun <- function(x,y){cat(x," ",y,"\n"); min(x,y)}

xx %>% rowwise() %>%
  mutate( z = bla_fun(x,y))

I would like to get it working with mutate_at which enables to pass me the column names as strings.

xx %>% rowwise() %>% 
   mutate_at( c("x","y"), funs("bla_fun") )

But this does not work. How to get it working?

mutate_at mutates every single column separately.

Your particular example can be solved (assuming the min is a placeholder that cannot be replaced by pmin ) like this:

xx %>% 
   mutate(z = map2(!!sym("x"), !!sym("y"), !!sym("bla_fun")))
syms <- rlang::syms(c("x", "y"))
xx %>% 
  rowwise() %>%
  mutate( z = bla_fun(!!! syms))

Side note 1: mutate_at is typically for applying n unary functions to n variables, not 1 n-ary function to n variables. mutate does the job.

Side note 2: there is no need to group rowwise. You could more simply mutate(xx, z = purrr::map2_dbl(x, y, bla_fun)) or rewrite/vectorize bla_fun with pmin() to mutate directly.
Combine this with the use of syms for strings: mutate(xx, z = mapply(bla_fun, !!! syms)) for instance, or mutate(xx, z = purrr::pmap_dbl(list(!!! syms), bla_fun)) .

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