问题
Given a 3 level nested list:
mylist <- list("1000"=list("cars"=list("fast"=mtcars[1:10,], "slow"=mtcars[11:15,]), "flower"=iris), "2000"=list("tooth"=ToothGrowth, "air"=airquality, "cars"=list("cruiser"=mtcars[5:12,], "fast"=mtcars[1:3,], "mild"=mtcars[9:18,])))
(ie: mylist$1000$cars$fast
, where fast
is a dataframe, and cars
and 1000
are nested lists in mylist
)
I'd like to save each innermost dataframe, (ie: fast
) as a .csv with the df name as it's file name, ie: fast.csv
, and I want the file to be saved in a directory that is named after the second level of list, ie: ~/1000/fast.csv
.
Each directory already exists, so I do not need to create a new 1000
and 2000
directory.
My instinct is to do a nested lapply
or lapply
/mapply
combination...but keeping track of the different levels and their names is challenging me. I know that purrr
has the iwalk
function, but I'm not sure how to use it within deeply nested list.
My current attempt fails.
lapply(mylist, function(d){
lapply(names(mylist), function(id){
lapply(names(d$cars), function(s){
lapply(d$cars, function(a){
write.csv(a, paste0(outdir, id, "/", s, ".csv"))})})})})
The output results in a single file being saved under multiple names into all the directories. ie: ~/1000/cruiser.csv
, ~/1000/fast.csv
, ~/1000/mild.csv
, ~/2000/cruiser.csv
, ~/2000/fast.csv
, ~/2000/mild.csv
... where all the files are actually just a csv of mylist$2000$cars$mild
回答1:
Assuming the sub-folders are within the working directory:
purrr::iwalk(mylist, function(el, folder){
purrr::walk(el,
function(sub_el, folder){
if(class(sub_el) == "list"){
purrr::iwalk(sub_el,
function(dat, dat_name, folder){
write.csv(dat,
# below line specifies file path of new file
paste0(folder, "/", dat_name, ".csv"))
},
folder = folder)
}
},
folder = folder)
})
来源:https://stackoverflow.com/questions/52819642/saving-deeply-nested-files-to-specific-directories-with-specific-filenames