Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing multiple data frames into .csv files using R

I have used lapply to apply a function to a number of data frames:

data.cleaned <- lapply(data.list, shooter_cleaning)

And then labeled each of the resulting data frames in the list according to their subject number (e.g., 100):

names(data.cleaned) <- subject.names

What I want to do is to save each new data frame as an individual .csv file based on its subject number. For example, for subject 100 I'd like the .csv file to be labeled as "100.csv" Normally to do this (for a single data frame) I would just write (where x is the data frame):

write.csv(x, "100.csv", row.names = F)

But, obviously using lapply to do this for my list of data frames will just produce many copies of "100.csv" when instead I would like the files to be unique, based on their subject number. How can I (use apply to?) save each of these data frames to their own unique .csv file?

like image 420
David Johnson Avatar asked Nov 03 '14 04:11

David Johnson


People also ask

How do I append multiple data frames in R?

To append data frames in R, use the rbind() function. The rbind() is a built-in R function that can combine several vectors, matrices, and/or data frames by rows. To join two data frames (datasets) vertically, use the rbind() function.

Which of the following commands are used to read and write CSV files in R?

The CSV file to be read should be either present in the current working directory or the directory should be set accordingly using the setwd(…) command in R. The CSV file can also be read from a URL using read. csv() function.

Are CSV files data frames?

CSV files are Comma-Separated Values Files used to represent data in the form of a table. These files can be read using R and RStudio. Data frames are used in R to represent tabular data.


3 Answers

This is a common operation. You need to split the dataframe into a list of dataframes then write them to many separate csvs. I will demonstrate 2 approaches with base R, and 2 approaches with tidyverse.

base R

A for loop makes the iteration very explicit.

# example data.frame
df  <- data.frame(x = 1:4, y = c("a", "a", "b", "b"))

# split the dataframe into a list by the y column
l  <- split(df, df$y)

# make filepaths from list names, which are unique values of the y column
file_out <- paste0(names(l), ".csv")

# iterate over the list and the vector of list names to write csvs
for(i in 1:length(l)) {
  write_csv(l[[i]], file_out[i])
}

Or using mapply():

mapply(
  function(x, y) write_csv(x, y), 
  l, 
  file_out
)

tidyverse approach

library(tidyverse)

# we pass walk2 two inputs: a list of dataframes (.x) and filepaths (.y)
# `walk` is a silent `map` that doesn't print output to the console
walk2(l, file_out, ~write_csv(.x, .y))

Or, avoiding intermediate variables:

df %>% 
  group_split(y) %>% 
  walk(~write_csv(.x, paste0(.x$y[1], ".csv")))
like image 142
Rich Pauloo Avatar answered Oct 19 '22 04:10

Rich Pauloo


Here's a self-contained example along the lines of Richard's comment, but uses the names of the dataframes in the list as filenames for the CSV files:

# Create a list of n data frames

n <- 10

my_list <- lapply(1:n, function(i)  data.frame(x = rnorm(10), y = rnorm(10)) )

# name the data frames

names(my_list) <- letters[1:n]

# save each new data frame as an individual .csv file based on its name

lapply(1:length(my_list), function(i) write.csv(my_list[[i]], 
                                      file = paste0(names(my_list[i]), ".csv"),
                                      row.names = FALSE))
like image 19
Ben Avatar answered Oct 19 '22 02:10

Ben


In case this helps: I had an environment with multiple data frames, and only those data frames, and I wanted to output each data frame as a separate CSV file. With the help of Ben's answer, and discovering mget, I was able to do that with the following code:

for(i in 1:length(ls())) {
  write.table(
  mget(ls()[[i]]),
  file = paste0(ls()[[i]], ".csv"),
  sep = ";",
  qmethod = "double",
  row.names = FALSE)
}
like image 2
Sean Burns Avatar answered Oct 19 '22 02:10

Sean Burns