0

This question is not about how to make it work, if you are looking for that, here are some good answers. Thread1 , Thread2

My question is why this version does not work

#Creating a simple list
n <- 5
my_list <- lapply(1:n, function(i)  data.frame(x = rnorm(10), y = rnorm(10)) )
names(my_list) <- letters[1:n]

#Trying to write as per my intuition, produces error
lapply(my_list,write.csv,paste0(names(my_list),".csv"))

Error in file(file, ifelse(append, "a", "w")) : 
  invalid 'description' argument
In addition: Warning message:
In if (file == "") file <- stdout() else if (is.character(file)) { :
  the condition has length > 1 and only the first element will be used

However, desired results can easily be achieved with

lapply(1:length(my_list), function(i) write.csv(my_list[[i]], 
                                      file = paste0(names(my_list[i]), ".csv")))

As I do not understand this error, I have so many doubts.

  • Why do we need to write another function which works on individual list elements?
  • Are there other similar functions, which can't be used directly with lapply and need a similar treatment? And (even better), How do I recognize that whether a function needs such kind of treatment?
  • What are the potential benefits of such functions over the functions which can directly be used with lapply?
Gaurav Singhal
  • 998
  • 2
  • 10
  • 25
  • 2
    You give the argument `paste0(names(my_list),".csv")` to `lapply()`. What should that mean in the context of `lapply()` (compared to the documentation of the function `lapply()`)? You even not used a parameter name for the additional argument (which was given as part of `...` to the function working over the elements of the list). – jogo Feb 16 '18 at 10:08
  • 3
    Try `mapply(write.csv, mylist, paste0(names(my_list),".csv"))`. It's doing a "zipper", of `my_list` elements with their names. – r2evans Feb 16 '18 at 10:10
  • You are passing multiple names in a single call to the `file` argument of `write.csv()`. – tushaR Feb 16 '18 at 10:11
  • Thanks for the direction. What about `as.list(paste0(names(my_list),".csv"))`. Again, my intuition could be totally wrong. – Gaurav Singhal Feb 16 '18 at 10:11
  • 2
    @GauravSinghal Another point: which parameter of `write.csv()` should take this argument `as.list(paste0(names(my_list),".csv"))` (a list of names)? There is no such parameter in `write.csv()` which could take it (compare with the documentation of `write.csv()`). – jogo Feb 16 '18 at 10:15
  • 1
    `names(my_list)` itself returns a `vector` which is easily iterable using `lapply`. However, as you need the content of the `data.frame` and the corresponding name of the `data.frame` together to accomplish your task you need to use `mapply` like this: `mapply(write.csv,my_list,names(my_list))` – tushaR Feb 16 '18 at 10:16
  • @jogo , so correct me if I am wrong (yet again), "the parameters which come after the function name in `lapply' will be same for all the elements of the list" – Gaurav Singhal Feb 16 '18 at 10:20
  • 1
    @GauravSinghal yepp. You can use `mapply()` to iterate (parallel) over two or more lists (see the comment of @r2evans). – jogo Feb 16 '18 at 10:24

0 Answers0