Сохранение глубоко вложенных файлов в определенные каталоги с конкретными именами файлов - PullRequest
0 голосов
/ 15 октября 2018

Для 3-уровневого вложенного списка:

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,]))) 

visual nested list example

(то есть: mylist$1000$cars$fast, где fast - это кадр данных, иcars и 1000 - это вложенные списки в mylist)

Я бы хотел сохранить каждый самый внутренний фрейм данных (т.е.: fast) как .csv с именем df в качестве имени файла, т.е.: fast.csv, и Я хочу, чтобы файл был сохранен в каталоге, который назван в честь второго уровня списка, то есть: ~/1000/fast.csv.

Каждый каталог уже существует, поэтому мне не нужно создавать новый каталог 1000 и 2000.

Мой инстинкт состоит в том, чтобы делать вложенную комбинацию lapply или lapply / mapply ... но отслеживание различных уровней и их названий бросает мне вызов.Я знаю, что purrr имеет функцию iwalk, но я не уверен, как использовать ее в глубоко вложенном списке.

Моя текущая попытка не удалась.

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"))})})})})

В результате один файл сохраняется под несколькими именами во всех каталогах.то есть: ~/1000/cruiser.csv, ~/1000/fast.csv, ~/1000/mild.csv, ~/2000/cruiser.csv, ~/2000/fast.csv, ~/2000/mild.csv ... где все файлы на самом деле просто CSV из mylist$2000$cars$mild

1 Ответ

0 голосов
/ 15 октября 2018

Предполагается, что подпапки находятся в рабочем каталоге:

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)
})
...