Поведение saveRDS() и readRDS() в отношении атрибутов объектов

saveRDS и readRDS соответственно сохраняют и восстанавливают все атрибуты объекта, в том числе созданные приложением (через attr)? Я попытался использовать этот подход вместо save и load, пытаясь найти обходной путь для моей проблемы, указанной ниже. Однако, похоже, это не так, если только я не делаю что-то не так: Могу ли я получить доступ к атрибутам объектов данных R без полной загрузки объектов из файла?.


person Aleksandr Blekh    schedule 18.05.2014    source источник


Ответы (1)


Да, они делают:

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 сильно зависит от этих функций (а также их вариантов). Например, они используются для сохранения рабочей области пользователя. Таким образом, было бы странно, если бы они не сохранили атрибуты.

Однако обратите внимание, что вы не можете хранить с ними некоторые «динамически созданные» объекты. Сюда входят обработчики соединений с файлами и базами данных SQL, обработчики временных результатов SQL и т. д. Пример с скомпилированными функциями RCpp:

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')

Теперь перезапускаем Р...

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
person gagolews    schedule 18.05.2014
comment
Большое спасибо! +1 и принять ваш ответ. Ну, я думаю, это означает, что моя проблема может быть где-то еще. Может быть, я создаю имена, используя as.name? Или, может быть, что-то еще? Был бы признателен, если бы вы взглянули на мой исходный вопрос, указанный выше. - person Aleksandr Blekh; 18.05.2014
comment
Убедитесь, что ни один из объектов, которые вы пытаетесь сериализовать (сохранить), не содержит указателей на динамически выделяемую память (попробуйте unlist(request) или sth). Если они это сделают, их следует каким-то образом преобразовать в чистые объекты R. - person gagolews; 18.05.2014
comment
Оцените ваше обновление и комментарий к динамическим объектам. Дзенкуйе! :-) - person Aleksandr Blekh; 18.05.2014