Behavior of saveRDS() and readRDS() in regard to objects' attributes
Asked Answered
D

1

11

Do saveRDS and readRDS, correspondingly, save and restore all object's attributes, including ones created by an application (via attr)? I tried to use this approach instead of save and load, in an attempt to find a workaround for my problem linked below. However, it doesn't seem to be the case, unless I'm doing something wrong: Can I access R data objects' attributes without fully loading objects from file?.

Domicile answered 18/5, 2014 at 12:13 Comment(0)
F
16

Yes, they do:

test <- structure(1:10, names=LETTERS[1:10], color='red', xxx='yyy')
attr(test, which='uuu') <- 'zzz'
test
##  A  B  C  D  E  F  G  H  I  J 
##  1  2  3  4  5  6  7  8  9 10 
## attr(,"color")
## [1] "red"
## attr(,"xxx")
## [1] "yyy"
## attr(,"uuu")
## [1] "zzz"
saveRDS(test, '/tmp/test.rds')
test2 <- readRDS('/tmp/test.rds')
identical(test, test2)
## [1] TRUE

R relies heavily on these functions (as well as their variants). For example, they are used to save the user's workspace. Thus, it would be odd if they hadn't stored the attributes.

However, do note that you cannot store some "dynamically created" objects with these. This includes file and SQL db connections handlers, temporary SQL result handlers, etc. An example with RCpp compiled functions:

library('Rcpp')
library('inline')   
cppFunction("int one() { return 1; }")
one() # it works
## [1] 1
one # contains a pointer to dynamically allocated mem chunk
## function () 
## .Primitive(".Call")(<pointer: 0x7f52c33a7680>)
saveRDS(one, '/tmp/one.rds')

Now we restart R...

one <- readRDS('/tmp/one.rds')
one # the pointer is no longer valid
## function () 
## .Primitive(".Call")(<pointer: (nil)>)
one() # doesn't work
## Error in .Primitive(".Call")(<pointer: (nil)>) : 
##  NULL value passed as symbol address
Flounce answered 18/5, 2014 at 12:17 Comment(3)
Thanks a lot! +1 and accept your answer. Well, I guess, it means my problem might be somewhere else. Could it be in a way I construct names, by using as.name? Or maybe something else? Would appreciate, if you'd take a look at my original question, linked above.Domicile
Make sure any of the objects you are trying to serialize (store) does not contain pointers to dynamically allocated memory (try unlist(request) or sth). If they do, they should be converted somehow to "pure R" objects.Flounce
Appreciate your update and comment on dynamic objects. Dziękuję! :-)Domicile

© 2022 - 2024 — McMap. All rights reserved.