2009-09-08 21 views
7

मैं अक्सर एक संबंधपरक डेटाबेस से बाहर डेटा पर nonparametric आंकड़े (नींद, कर्नेल घनत्व, आदि) बनाते हैं। डेटा प्रबंधन को आसान बनाने के लिए मैं अपने डीबी के अंदर आर आउटपुट को वापस स्टोर करना चाहता हूं। यह संख्या या पाठ के सरल डेटा फ्रेम के साथ आसान है, लेकिन मुझे पता नहीं चला है कि मेरे रिलेशनशिप डेटाबेस में आर ऑब्जेक्ट्स को वापस कैसे स्टोर किया जाए। तो क्या कर्नेल घनत्व के वेक्टर को स्टोर करने का कोई तरीका है, उदाहरण के लिए, एक रिलेशनल डेटाबेस में वापस?एक रिलेशनल डेटाबेस में आर ऑब्जेक्ट्स संग्रहीत करना

अभी मैं आर ऑब्जेक्ट्स को नेटवर्क ड्राइव स्पेस में सहेजकर इस पर काम करता हूं ताकि अन्य आवश्यक वस्तुओं को लोड कर सकें।

उत्तर

9

किसी भी आर ऑब्जेक्ट को (कच्चे या वर्ण) स्ट्रिंग में बदलने के लिए क्रमबद्धता सुविधा का उपयोग करें, फिर उस स्ट्रिंग को स्टोर करें। help(serialize) देखें।

पुनर्प्राप्ति के लिए इसे उलट दें: स्ट्रिंग प्राप्त करें, फिर unserialize() एक आर ऑब्जेक्ट में प्राप्त करें।

9

एक उदाहरण आर चर, कि काफी जटिल है:

library(nlme) 
model <- lme(uptake ~ conc + Treatment, CO2, random = ~ 1 | Plant/Type) 

सबसे अच्छा आर चर के लिए भंडारण डेटाबेस विधि आप इसे कैसे उपयोग करना चाहते हैं पर निर्भर करता है।

मैं

में डेटाबेस विश्लेषिकी मूल्यों पर करने के लिए इस मामले में की जरूरत है, तो आप वस्तु मान जो डेटाबेस देशी रूप संभाल कर सकते हैं में टूट की जरूरत है। इसका आमतौर पर इसका मतलब है एक या अधिक डेटा फ्रेम में परिवर्तित करना। ऐसा करने का सबसे आसान तरीका broom पैकेज का उपयोग करना है।

library(broom) 
coefficients_etc <- tidy(model) 
model_level_stats <- glance(model) 
row_level_stats <- augment(model) 

मैं सिर्फ भंडारण

इस मामले आप अपने अनुसंधान चर क्रमानुसार करने चाहते हैं चाहते हैं। यही है, उन्हें एक स्ट्रिंग या बाइनरी ब्लॉब के रूप में परिवर्तित करना। इसके लिए कई तरीके हैं।


मेरे डेटा, आर के अलावा अन्य कार्यक्रमों के द्वारा सुलभ हो गया है और मानव पठनीय होने की जरूरत है

आप एक पार मंच पाठ प्रारूप में अपने डेटा स्टोर करना चाहिए; शायद जेएसओएन या वाईएएमएल। JSON Inf जैसी कुछ महत्वपूर्ण अवधारणाओं का समर्थन नहीं करता है; वाईएएमएल अधिक सामान्य है लेकिन आर में समर्थन परिपक्व नहीं है। एक्सएमएल भी संभव है, लेकिन बड़े एरे भंडारण के लिए उपयोगी होने के लिए भी वर्बोज़ है।

library(RJSONIO) 
model_as_json <- toJSON(model) 
nchar(model_as_json) # 17916 

library(yaml) 
# yaml package doesn't yet support conversion of language objects, 
# so preprocessing is needed 
model2 <- within(
    model, 
    { 
    call <- as.character(call) 
    terms <- as.character(terms) 
    } 
) 
model_as_yaml <- as.yaml(model2) 
nchar(model_as_yaml) # 14493 

मेरे डेटा आर के अलावा अन्य कार्यक्रमों के द्वारा सुलभ हो गया है, और मानव पठनीय होने की जरूरत नहीं है

आप एक खुले, पार मंच के लिए अपने डेटा लिख ​​सकता है एचएफडी 5 जैसे बाइनरी प्रारूप। वर्तमान में एचएफडी 5 फाइलों के लिए समर्थन (rhdf5 के माध्यम से) सीमित है, इसलिए जटिल वस्तुएं समर्थित नहीं हैं। (आप शायद unclass सब कुछ करने की आवश्यकता होगी।)

library(rhdf5) 
h5save(rapply(model2, unclass, how = "replace"), file = "model.h5") 
bin_h5 <- readBin("model.h5", "raw", 1e6) 
length(bin_h5) # 88291 not very efficient in this case 

feather पैकेज आइए आप एक प्रारूप में डेटा फ्रेम दोनों आर और अजगर द्वारा पठनीय सहेजें।इसका उपयोग करने के लिए, आपको पहले मॉडल ऑब्जेक्ट को डेटा फ्रेम में कनवर्ट करना होगा, जैसा कि उत्तर में ब्रूम अनुभाग में वर्णित है।

library(feather) 
library(broom) 
write_feather(augment(model), "co2_row.feather") # 5474 bytes 
write_feather(tidy(model), "co2_coeff.feather") # 2093 bytes 
write_feather(glance(model), "co2_model.feather") # 562 bytes 

एक अन्य विकल्प (पिछले अनुभाग देखें) ज़िपित फाइल करने के लिए डेटाबेस में चर का एक पाठ संस्करण बचाने के लिए और अपने बाइट्स स्टोर करने के लिए है।

writeLines(model_as_json) 
tar("model.tar.bz", "model.txt", compression = "bzip2") 
bin_bzip <- readBin("model.tar.bz", "raw", 1e6) 
length(bin_bzip) # only 42 bytes! 

मेरे डेटा केवल आर द्वारा सुलभ होने की जरूरत है, और मानव पठनीय

वहाँ एक स्ट्रिंग में एक चर बदल लिए दो विकल्प हैं की जरूरत है: serialize और deparse

p <- function(x) 
{ 
    paste0(x, collapse = "\n") 
} 

serialize एक पाठ कनेक्शन के लिए भेजा जाना है, और बजाय फाइल करने के लिए लिखने की तुलना में, आप कंसोल के लिए लिख सकते हैं और यह कब्जा कर सकते हैं की जरूरत है।

model_serialized <- p(capture.output(serialize(model, stdout()))) 
nchar(model_serialized) # 23830 

control = "all" साथ उपयोग deparse जब बाद में फिर से पार्स करने उलटने अधिकतम करने के लिए।

model_deparsed <- p(deparse(model, control = "all")) 
nchar(model_deparsed) # 22036 

मेरे डेटा केवल आर द्वारा सुलभ होने की जरूरत है, और मानव पठनीय

यहां पिछले अनुभाग में दिखाया तकनीक का एक ही प्रकार लागू किया जा सकता होने की जरूरत नहीं है । आप एक धारावाहिक या विकृत चर को ज़िप कर सकते हैं और कच्चे वेक्टर के रूप में इसे फिर से पढ़ सकते हैं।

serialize बाइनरी प्रारूप में चर भी लिख सकते हैं। इस मामले में, इसका उपयोग आसानी से इसके रैपर saveRDS के साथ किया जाता है।

zz<-textConnection('tempConnection', 'wb') 
saveRDS(myData, zz, ascii = T) 
TEXT<-paste(textConnectionValue(zz), collapse='\n') 

#write TEXT into SQL 
... 
closeAllConnections() #if the connection persists, new data will be appended 

#reading back: 
#1. pull from SQL into queryResult 
... 
#2. recover the object 
recoveredData <- readRDS(textConnection(queryResult$TEXT)) 
+0

यह आखिरी वाला _very_ अक्षम है। 'saveRDS' ऑब्जेक्ट को फ़ाइल में लिखता है, और फिर' readBin' इसे स्मृति में पढ़ता है। जहां तक ​​मुझे पता है, 'serialize' सीधे' कनेक्शन = NULL' के साथ स्मृति में लिखता है। –

2

textConnection/saveRDS/loadRDS का प्रयोग शायद सबसे बहुमुखी और उच्च स्तर है

RSQLite::dbGetQuery(db.conn, 'INSERT INTO data VALUES (:blob)', params = list(blob = list(serialize(some_object))) 

some_object के आसपास list रैपर नोट करें। serialize का उत्पादन एक कच्चा वेक्टर है। list के बिना, प्रत्येक वेक्टर तत्व के लिए INSERT कथन निष्पादित किया जाएगा। एक सूची में इसे लपेटने से इसे RSQLite::dbGetQuery को एक तत्व के रूप में देखने की अनुमति मिलती है।

वस्तु डेटाबेस से वापस पाने के लिए:

some_object <- unserialize(RSQLite::dbGetQuery(db.conn, 'SELECT blob FROM data LIMIT 1')$blob[[1]]) 

यहां होता आप क्षेत्र blob ले जाता है (जो एक सूची के बाद से RSQLite पता नहीं है कि कितने पंक्तियों क्वेरी द्वारा रिटर्न हो जाएगा) । चूंकि LIMIT 1 आश्वासन देता है कि केवल 1 पंक्ति लौटा दी गई है, हम इसे [[1]] के साथ लेते हैं, जो मूल कच्चा वेक्टर है। फिर आपको अपनी ऑब्जेक्ट प्राप्त करने के लिए unserialize कच्चे वेक्टर की आवश्यकता है।

2

sqlite (और संभवतः अन्य) के लिए::

CREATE TABLE data (blob BLOB); 
अब

R में:

saveRDS(model, "model.rds") 
bin_rds <- readBin("model.rds", "raw", 1e6) 
length(bin_rds) # 6350 
संबंधित मुद्दे