6

I'm applying a function to a nested dataframe using purrr::map to get a new dataframe list column.

Now I want to write each of these new dataframes to file using column values from the same row as part of the filename.

I'm stuck on how to pull the other column values out in order to pass to the filename for writing to file. I'm confident purrr::walk should be involved but the manner of how to access column variables and the list dataframe contents is the problem.

Reprex below:

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

# Data
data("mtcars")
mtcars_nest <- mtcars %>% rownames_to_column() %>% rename(rowname_1 = rowname) %>% select(-mpg) %>% group_by(cyl) %>% nest()
mtcars_mpg <- mtcars %>% rownames_to_column() %>% rename(rowname_2 = rowname) %>% select(rowname_2, mpg)

# Function to apply to nested dataframe
join_df <- function(df_nest, df_other) {
  df_all <- inner_join(df_nest, df_other, by = c("rowname_1" = "rowname_2"))
  return(df_all)
}

# 1. Apply function to `$data` to get new dataframe list column and add an extra 'case' column for filename
mtcars_nest %>%
  mutate(case = c("first", "second", "third")) %>%
  mutate(new_mpg = map(data, ~ join_df(., mtcars_mpg)))

# 2. Now write `$new_mpg` to file with filename sources from $cyl and $case
# I think `walk` is the correct to use but how to pass the two row values into filename?

## Not real code##
# mtcars_nest %>%
#  walk(., function(x) {write.csv(., file = paste0(cyl, "_", case, ".csv")})
mark
  • 537
  • 6
  • 25

1 Answers1

6

Use pwalk:

... %>%
select(cyl, case, new_mpg) %>%
pwalk(~ write.csv(..3, file = paste0(..1, '_', ..2, '.csv')))

Chain after your code:

mtcars_nest %>%
    mutate(case = c("first", "second", "third")) %>%
    mutate(new_mpg = map(data, ~ join_df(., mtcars_mpg))) %>%
    select(cyl, case, new_mpg) %>%
    pwalk(~ write.csv(..3, file = paste0(..1, '_', ..2, '.csv')))
Psidom
  • 209,562
  • 33
  • 339
  • 356
  • 3
    Just as an alternative, if you want to reference the names of those columns instead of the shorthands, you can use `pwalk(function(cyl, case, new_mpg) write.csv(new_mpg, paste0(cyl, "_", case, ".csv"))`. I always have trouble with the `.`, `.x`, `..1`, etc, and just spell things out for myself – camille May 02 '18 at 16:50
  • 2
    I find it useful to `pwalk(function(cyl, case, new_mpg)...`. for clarity in what's being passed @camille – mark May 02 '18 at 18:32