Using purrr::pmap() in a rowwise manner outside of mutate()

491 Views Asked by At

I am trying to use purrr::pmap() to apply a custom function in a rowwise fashion along some dataframe rows. I can achieve my desired end result with a for-loop and with apply(), but when I try to use pmap() I can only get the result I want in combination with mutate(), which in my real-life applied case will be insufficient.

Is there a way to use pmap() to apply my custom function and just have the output print rather than be stored in a new column?

library(dplyr)
library(purrr)
library(tibble)

Create demo data & custom function

set.seed(57)

ds_mt <- 
  mtcars %>% 
    rownames_to_column("model") %>% 
    mutate(
      am = factor(am, labels = c("auto", "manual")), 
      vs = factor(vs, labels = c("V", "S"))
    ) %>% 
  select(model, mpg, wt, cyl, am, vs) %>% 
  sample_n(3)

foo <- function(model, am, mpg){
  print(
    paste("The", model, "has a", am, "transmission and gets", mpg, "mpgs.")
  )
}

Successful example of rowwise for-loop:

for (row in 1:nrow(ds_mt)) {
  foo(
    model = ds_mt[row, "model"], 
    am    = ds_mt[row, "am"],
    mpg   = ds_mt[row, "mpg"]
  )
}

Successful example using apply():

row.names(ds_mt) <- NULL # to avoid named vector as output

  apply(
    ds_mt, 
    MARGIN = 1, 
    FUN = function(ds) 
      foo(
        model = ds["model"],
        am = ds["am"],
        mpg = ds["mpg"]
      )
  ) 

Example using pmap() within mutate() that is almost what I need.

ds_mt %>% 
  mutate(new_var = 
    pmap(
      .l = 
        list(
          model = model,
          am = am,
          mpg = mpg
        ),
      .f = foo
    ))

FAILING CODE: Why doesn't this work?

ds_mt %>% 
  pmap(
    .l = 
      list(
        model = model,
        am = am,
        mpg = mpg
      ),
    .f = foo
  )
1

There are 1 best solutions below

0
On BEST ANSWER

So after some more reading it seems this is a case for pwalk() rather than pmap(), because I am trying to get output to print (i.e., a side effect) rather than to be stored in a dataframe.

library(dplyr)
library(purrr)
library(tibble)

set.seed(57)

ds_mt <- 
  mtcars %>% 
  rownames_to_column("model") %>% 
  mutate(
    am = factor(am, labels = c("auto", "manual")), 
    vs = factor(vs, labels = c("V", "S"))
  ) %>% 
  select(model, mpg, wt, cyl, am, vs) %>% 
  sample_n(3)

foo <- function(model, am, mpg){
  print(
    paste("The", model, "has a", am, "transmission and gets", mpg, "mpgs.")
  )
}

ds_mt %>% 
  select(model, am, mpg) %>% 
  pwalk(
  .l = .,
  .f = foo
)