Home > front end >  Using purrr::map2 (?) to add new columns to a data frame
Using purrr::map2 (?) to add new columns to a data frame

Time:11-04

I'm again stuck with this hopefully simple task.

I have the following data frame:

df <- data.frame(x1 = 1:3,
                 x2 = 2:4,
                 x3 = 3:5,
                 y1 = 1:3,
                 y2 = 2:4,
                 y3 = 3:5)

I now simply wanted to "loop" through each subscript and multiply the x* with the y* column, i.e. x1 * y1, x2 * y2 and so on and add these results to my data.

With these kind of tasks, I always think this should be easily doable with a map approach, but I don't get it to work, e.g.

library(tidyverse)
df |>
  map2(.x = _,
       .y = 1:3,
       .f = ~.x |>
         mutate(!!sym(paste0(results, .y)) := !!sym(paste0(x, .y)) * !!sym(paste0(y, .y))))

doesn't work.

I also thought about using something with across, but that also doesn't work, because I can't tell across to "vectorize" over the x and y inputs.

Any ideas?

CodePudding user response:

The trick is to use across twice:

library(dplyr)
df |>
  mutate(across(starts_with("x"), .names = "xy{gsub('x', '', col)}") * across(starts_with("y")))

#  x1 x2 x3 y1 y2 y3 xy1 xy2 xy3
#1  1  2  3  1  2  3   1   4   9
#2  2  3  4  2  3  4   4   9  16
#3  3  4  5  3  4  5   9  16  25

CodePudding user response:

Using reduce instead of map2 you could do:

library(dplyr)
library(purrr)

df |>
  reduce(1:3,
    .f = ~ .x |>
      mutate(!!sym(paste0("results", .y)) := !!sym(paste0("x", .y)) * !!sym(paste0("y", .y))),
    .init = _
  )
#>   x1 x2 x3 y1 y2 y3 results1 results2 results3
#> 1  1  2  3  1  2  3        1        4        9
#> 2  2  3  4  2  3  4        4        9       16
#> 3  3  4  5  3  4  5        9       16       25
  • Related