简体   繁体   中英

dplyr mutate: pass list of variables to create multiple new variables

I'm trying to do something that intuitively feels straightforward but I can't figure it out. I'm hoping to calculate delta's for a number of columns: I have columns A1, B1, C1 and A2, B2, C2 and would like to create columns A_delta, B_delta, C_delta by subtracting A2 - A1 etc.

Here's what I thought I could do with dplyr (using mtcars as example):

# Create test data with changed columns
d.test <- mtcars %>% 
            rownames_to_column() %>% 
            mutate(mpg2 = mpg - 4, 
                   cyl2 = cyl - 1)

# Calculate deltas & add as new columns
d.test %>% mutate(!!c("mpg_delta", "cyl_delta") := c(mpg2, cyl2) - c(mpg, cyl))

Clearly it doesn't work like this, but I cannot for the life of me figure out the right syntax. I've been reading up on using purrr but that seems applicable when trying to do different actions per row (like here dplyr mutate using variable columns ), not when trying to create multiple new columns...

Any pointers would be great!

One dplyr and purrr possibility could be:

map2_dfr(.x = d.test %>%
          select(mpg2, cyl2),
         .y = d.test %>%
          select(mpg, cyl), 
         ~ .x - .y) %>%
 setNames(c("mpg_delta", "cyl_delta"))

   mpg_delta cyl_delta
       <dbl>     <dbl>
 1        -4        -1
 2        -4        -1
 3        -4        -1
 4        -4        -1
 5        -4        -1
 6        -4        -1
 7        -4        -1
 8        -4        -1
 9        -4        -1
10        -4        -1

Or:

my_diff <- function(d, newvars, vars1, vars2) {
  cmd <- unlist(pmap(list(newvars, vars1, vars2), ~exprs(!!..1 := !!..2 - !!..3)))
  d %>%
    mutate(!!!cmd)
}
d.test %>%
  my_diff(vars(delta_mpg, delta_cyl), vars(mpg2, cyl2), vars(mpg, cyl))

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