2016-03-20 21 views
7

Jak przekonwertować surowy wektor z powrotem na obiekt R bez zapisu na dysku? Chcę odczytać strumień danych base64 i przekonwertować go na reprezentację obiektu R. Oto przykład - jak odzyskać obiekt lm z surowego wektora?Konwertuj wektor surowy na obiekt R

## some rdata -- writes to temp file! 
mod <- lm(mpg ~ cyl, data=mtcars) 
f1 <- tempfile() 
save(mod, file=f1, compress="bzip2") 

library(base64enc) 
r1 <- readBin(f1, "raw", n=file.info(f1)[1, "size"]) 
r2 <- base64decode(base64encode(file(f1, "rb"))) # emulate input base64 
identical(r1, r2) 

## I can get mod back by writing to file and loading, but how to just 
## load from a raw vector? 
rm(mod) # get rid of mod 
f2 <- tempfile() 
writeBin(r2, f2) 
load(f2) # mod is back 

Odpowiedz

5

Wewnątrz mojego pakietu RcppRedis używam pakiet RApiSerialize (który jest oparty na kodzie baza R początkowo pożyczonych w pakiecie Rhpc), aby zrobić te konwersji w locie:

R> mod <- lm(mpg ~ cyl, data=mtcars)  # your example 
R> 
R> library(RApiSerialize) 
R> modraw <- serializeToRaw(mod)   # serialized 
R> str(modraw)       # really just a raw vector now 
raw [1:6819] 58 0a 00 00 ... 
R> 

Więc w tym momencie możesz zrobić, co chcesz z surowym wektorem. Zapisz go na dysku, zapisywać do bazy danych (jak robimy z RcppRedis), ....

Ale najważniejsze, można również uzyskać z powrotem swój model:

R> summary(unserializeFromRaw(modraw)) 

Call: 
lm(formula = mpg ~ cyl, data = mtcars) 

Residuals: 
    Min  1Q Median  3Q Max 
-4.981 -2.119 0.222 1.072 7.519 

Coefficients: 
      Estimate Std. Error t value Pr(>|t|)  
(Intercept) 37.885  2.074 18.27 < 2e-16 *** 
cyl   -2.876  0.322 -8.92 6.1e-10 *** 
--- 
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 3.21 on 30 degrees of freedom 
Multiple R-squared: 0.726, Adjusted R-squared: 0.717 
F-statistic: 79.6 on 1 and 30 DF, p-value: 6.11e-10 

R> 
+0

Chyba mogę skompresować _after_ serializacji i rozpakować _przed deserializacją. Ale prawdopodobnie chcesz zajrzeć do 'saveRDS()' i 'readRDS()', które są lepsze od 'save()' i 'load()' i _already use compression_, chyba że go wyłączysz. I tak, cały temat jest nieco mylący, ale funkcje '* RDS()' oraz moje funkcje (seryjne) serializacji (de) pomagają w dobrym kawałku. Jest w tym coś więcej niż tylko "base64" ... –

2

Do stosowania dostępu R szczebla unserialize(serialize(mod, NULL)) w obie strony z obiektu R do wektora surowego iz powrotem.