5

I'm trying to use saveRDS in a loop, I have a list named XDATA which contains 21 matrices and a list called names containing 21 names that I want to save these matrices under. Here are two solutions I tried, neither worked:

for (i in 1:21) {
  assign(names[i],XDATA[[i]])
  saveRDS(as.name(names[i]),file = paste(names[i],'.RDS',sep=''),compress=TRUE)
}

This just saves a 1kb file containing the symbol which is as.name(names[i]). My second attempt was:

for (i in 1:21) {
  assign(names[i],XDATA[[i]])
  eval(parse(paste('saveRDS(',names[i],",file=paste(names[i],'.RDS',sep=''),compress=TRUE)", sep="")))
}

This results in the following error:

Error in file(filename, "r") : cannot open the connection In addition: Warning message: In file(filename, "r") : cannot open file 'saveRDS(Sub_502,file=paste(names[1],'.RDS',sep=''),compress=TRUE)': No such file or directory

I'd appreciate a working solution to this problem and perhaps an explanation why you passing with as.name in the first solution failed despite the syntax seems to make perfect sense.

Thanks!

Serpahimz
  • 175
  • 1
  • 8

1 Answers1

9

You probably should just do

for (i in 1:21) {
  assign(names[i],XDATA[[i]])
  saveRDS(get(names[i]),file = paste(names[i],'.RDS'),compress=TRUE)
}

the first object you pass to saveRDS needs to be the object you want to save, not just it's name. A "name" is a variable type that you can save as well; it is different from the object itself. Here, get() returns the value of the objects given the character version of its name.

I'm not entirely sure why you are bothering with the assign() anyway. Unlike with save()/load(), saveRDS does not perserve the objects name. You could just do

for (i in 1:21) {
  saveRDS(XDATA[[i]],file = paste(names[i],'.RDS'),compress=TRUE)
}
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • That's a good point about saveRDS not preserving the name, I completely forgot about that... Still, the first syntax would come in handy in case I want to use save and not saveRDS I suppose... Thanks for the help :) – Serpahimz Nov 10 '14 at 21:34
  • It appears that "save(get(names[i]),file = paste(names[i],'.RDS',sep=""),compress=TRUE)" does not work. I get an error "object ‘get("Sub_502")’ not found" despite there is an object named Sub_502. Any suggestions? – Serpahimz Nov 10 '14 at 21:48
  • I didn't mean to imply this would work for `save()`. The `save()` function uses non-standard evaluation to extract both variable name and value. When using save with character values for the names, you should use the `list=` parameter: ie `save(list=names[i],file = paste(names[i],'.RDS',sep=""),compress=TRUE)` – MrFlick Nov 10 '14 at 21:54
  • Awesome. Sorry for the hassle :) – Serpahimz Nov 10 '14 at 21:58