Take this simple dataset and function (representative of more complex problems):
x <- data.frame(a = 1:3, b = 2:4)
mult <- function(a,b,n) (a + b) * n
Using base R's Map
I could do this to add 2 new columns in a vectorised fashion:
ns <- 1:2
x[paste0("new",seq_along(ns))] <- Map(mult, x["a"], x["b"], n=ns)
x
# a b new1 new2
#1 1 2 3 6
#2 2 3 5 10
#3 3 4 7 14
purrr
attempt via pmap
gets close with a list output:
library(purrr)
library(dplyr)
x %>% select(a,b) %>% pmap(mult, n=1:2)
#[[1]]
#[1] 3 6
#
#[[2]]
#[1] 5 10
#
#[[3]]
#[1] 7 14
My attempts from here with pmap_dfr
etc all seem to error out in trying to map this back to new columns.
How do I end up making 2 further variables which match my current "new1"/"new2"
? I'm sure there is a simple incantation, but I'm clearly overlooking it or using the wrong *map*
function.
There is some useful discussion here - How to use map from purrr with dplyr::mutate to create multiple new columns based on column pairs - but it seems overly hacky and inflexible for what I imagined was a simple problem.
x %>% select(a,b) %>% pmap(mult, n=1:2) %>% bind_cols() %>% t()
– Ronak Shahx[paste0("new",seq_along(ns))] <- pmap(list(x['a'], x['b'], ns), mult)
? – mt1022pmap
/Map
are directly analogous. The only problem being that I am trying to fit this into someone else's piped code. Is there a way to feedx
into thatpmap
like the (non-working)x %>% pmap(list(a,b,ns), mult)
- I'm still lost at this stage. – thelatemaila
andb
fromx
topmap
. The most closest one I an get isx %>% {list(.['a'], .['b'], ns)} %>% pmap(mult) %>% setNames(paste0('new', seq_along(ns))) %>% cbind(x)
. – mt1022