How to use tidyverse map to iterate filtering and writing to csv in R

Viewed 409

I've got a data frame full of study metadata, with two key columns: citation information and questions of mine that they pertain to:

library(tidyverse)

citation <- c(letters) 
study_question <- rep(1:3, len = length(citation))

df <- as.data.frame(cbind(citation, study_question))

#so that df looks like: 

citation study_question
 [1,] "a"      "1"           
 [2,] "b"      "2"           
 [3,] "c"      "3"           
 [4,] "d"      "1"           
 [5,] "e"      "2"           
 [6,] "f"      "3"           
 [7,] "g"      "1"           
 [8,] "h"      "2"           
 [9,] "i"      "3"           
[10,] "j"      "1"           
[11,] "k"      "2"           
[12,] "l"      "3"           
[13,] "m"      "1"           
[14,] "n"      "2"           
[15,] "o"      "3"           
[16,] "p"      "1"           
[17,] "q"      "2"           
[18,] "r"      "3"           
[19,] "s"      "1"           
[20,] "t"      "2"           
[21,] "u"      "3"           
[22,] "v"      "1"           
[23,] "w"      "2"           
[24,] "x"      "3"           
[25,] "y"      "1"           
[26,] "z"      "2"           
> 

What I'd like to do is use an iterative function to filter for study question = 1, to get:

> df %>% filter(study_question == 1)
  citation study_question
1        a              1
2        d              1
3        g              1
4        j              1
5        m              1
6        p              1
7        s              1
8        v              1
9        y              1

then write that list of citations to a csv named "sq1_papers.csv", then do the same for study question = 2, with the output "sq2_papers.csv", and then the same for question 3.

I have tried this with a for loop, which has not worked, and would prefer to try it with a map function, which I have gotten to work in the past. Here is the code I tried:

for(i in study_question) {
  file <- df  %>% 
    filter(study_question == study_question[[i]]) 
  write_csv(file, "data/sq[i]_papers.csv")
}

2 Answers

With tidyverse, we can group split by 'study_question, loop over the list with iwalk and write to 'csv' with write_csv from readr

library(dplyr)
library(purrr)
library(readr)
library(stringr)
df %>%
      group_split(study_question) %>%
      iwalk(~ write_csv(.x, str_c('data/sq', .y, '_papers.csv'))

The below code should work for you:

## iterate through unique "study_questions"
for(i in unique(df$study_question)) {
  ## filter data frame by current "study question"
  file <- df  %>% 
    filter(study_question == i)
  ## create file name for export
  fileName <- paste0("data/sq",i,"_papers.csv")
  ## export filtered data to path of fileName
  write_csv(file, fileName)
}

I hope this helps!

Related