1
votes

I have created a list of objects in my work environment

data <- c("variable1", "variable2", "variable3")

i would like to save the files to different directories with the variable name as the directory... so i did this to give me a list of file names to pass to the save function via lapply..

paste0(data,"/",data,".rda")


lapply(data,FUN=save,file = paste0(data,"/",data,".rda"))

i get the error

Error in FUN(X[[i]], ...) : object ‘X[[i]]’ not found

i'm not sure what i'm doing wrong here..

2
lapply is used where you want a list for the return value of each iteration, and offers no advantage here. I would suggest using for instead. - Matthew Lundberg
could you demonstrate @MatthewLundberg - cdcaveman

2 Answers

4
votes

Do you have a list of objects, or a list of names of objects? You say you have the former, but the code you give is for the latter.

Also, if you only have one object per file, then it's better to use the saveRDS function (and loadRDS to load it).

lapply(data, function(x) saveRDS(get(x), paste0(x, "/", x, ".rds")))

If you have to use save:

lapply(data, function(x) save(list=x, file=paste0(x, "/", x, ".rds")))
2
votes

Several things going on here.

First, you need not use lapply when you don't care about the return value of the function called at each iteration. It offers nothing in this case.

Second, and more importantly, what you are doing is writing objects to files with names derived from their variable names in R. That's an anti-pattern.

Instead, create a list of the objects, and use for for the work. We need to use saveRDS for this (thanks Hong Ooi) as l[[n]] is also not the name of an object in the environment.

l <- list(variable1 = variable1, variable2 = variable2, variable3=variable3)
for (n in names(l)) {
    fname = paste0(n, '/', n, '.rda')
    saveRDS(file=fname, l[[n]])
}

It would be better to just save the entire list, but then all the data would be in one file in one directory.

As for what's actually wrong with your code:

  • You pass the same value for file to all invocations of save, and you don't intend to do so. This value is a vector, but what you want is that each iteration gets one element from this vector.
  • The way lapply computes the value to pass to the function confuses save. In particular, it does this:

names <- as.character(substitute(list(...)))[-1L]

That results in something like the following, which is not the name of an object in the environment.

c("variable1", "variable2", "variable3")[[1]]