Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?.

like image 706
Aleksandr Blekh Avatar asked May 18 '14 12:05

Aleksandr Blekh


1 Answers

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
like image 200
gagolews Avatar answered Sep 28 '22 19:09

gagolews