2009-09-08 3 views
7

관계형 데이터베이스에서 추출한 데이터에 비모수 통계 (황토, 커널 밀도 등)를 자주 작성합니다. 데이터 관리를 더 쉽게하기 위해 R 출력을 내 DB에 저장하고 싶습니다. 숫자 나 텍스트의 간단한 데이터 프레임에서는 쉽지만 R 객체를 관계형 데이터베이스에 다시 저장하는 방법을 찾지 못했습니다. 그렇다면 관계형 데이터베이스에 커널 밀도 벡터를 저장하는 방법이 있습니까?관계형 데이터베이스에 R 객체 저장

지금 나는 네트워크 드라이브 공간에 R 개체를 저장하여 다른 사람들이 필요에 따라 개체를로드 할 수 있도록했습니다.

답변

9

R 개체를 (원시 또는 문자) 문자열로 변환 한 다음 해당 문자열을 저장하는 직렬화 기능을 사용하십시오. help(serialize)을 참조하십시오.

검색 할 때이를 뒤집어서 문자열을 가져온 다음 unserialize()을 R 객체에 넣습니다.

9

의 예 R 변수, 즉 상당히 복잡하다 : R 변수

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) 

난 그냥 당신이 당신의 R 변수를 직렬화하려면이 경우 저장

를 원한다. 즉, 문자열 또는 2 진 BLOB로 변환합니다. 이를위한 몇 가지 방법이 있습니다.


내 데이터가 R 이외의 다른 프로그램에서 액세스 할 수 있으며, 사람이 읽을 수 있어야

당신은 크로스 플랫폼 텍스트 형식으로 데이터를 저장한다 아마 JSON 또는 YAML. JSON은 Inf과 같은 몇 가지 중요한 개념을 지원하지 않습니다. YAML은 더 일반적이지만 R의 지원은 성숙하지 않습니다. XML도 가능하지만 큰 배열을 저장하는 데 너무 장황하다.

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 

내 데이터는 R 이외의 다른 프로그램에서 액세스 할 수 있으며, 사람이 읽을 수있을 필요가 없습니다

당신은 개방형, 크로스 플랫폼에 데이터를 쓸 수

HFD5와 같은 바이너리 형식. 현재 rhdf5을 통한 HFD5 파일 지원은 제한되어 있으므로 복잡한 개체는 지원되지 않습니다. (당신은 아마 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 패키지하자 당신은 R 및 Python 모두 형식으로 데이터 프레임 읽을 저장합니다.이를 사용하려면 먼저 답안의 빗자루 섹션에 설명 된대로 모델 개체를 데이터 프레임으로 변환해야합니다.

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! 

내 데이터는 R에 의해 액세스 할 수 있어야하고, 문자열로 변수를 돌려 두 가지 옵션이 있습니다

사람이 읽을 수 있어야합니다 : serializedeparse가.

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 
는 R에 의해 액세스 할 수 있어야하고,

사람이 읽을 수있는 이전 섹션에 표시된 기술의 같은 종류가 여기에 적용 할 수있을 필요가 없습니다 . 직렬화 또는 분해 된 변수를 압축하여 원시 벡터로 다시 읽을 수 있습니다.

serialize 또한 변수를 이진 형식으로 쓸 수 있습니다. 이 경우 래퍼 saveRDS과 함께 가장 쉽게 사용할 수 있습니다. sqlite (및 기타)에 대한

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

이 마지막 것은 매우 비효율적 인 것 같습니다. 'saveRDS'는 객체를 파일에 쓰고,'readBin'은 그것을 메모리로 읽어들입니다. 내가 아는 한,'serialize'는'connection = NULL'을 사용하여 메모리에 직접 씁니다. –

2

는 textConnection/saveRDS/loadRDS를 사용하는 것은 아마도 가장 다양하고 높은 수준이다

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

list 래퍼 주위 some_object에 유의하십시오. serialize의 출력은 원시 벡터입니다. list이 없으면 각 벡터 요소에 대해 INSERT 문이 실행됩니다. 목록에 넣으면 RSQLite::dbGetQuery을 하나의 요소로 볼 수 있습니다.

는 다시 데이터베이스에서 개체를 얻으려면 :

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

여기에서 발생하면 (RSQLite 쿼리에 의해 반환되는 행 수를 알 수 없기 때문에 목록 인) 분야 blob을한다 . LIMIT 1은 1 행만 반환한다는 것을 보장하기 때문에 원래의 원시 벡터 인 [[1]]을 사용합니다. 그런 다음 객체를 얻기 위해 unserialize 원시 벡터가 필요합니다.

2

: R에서 지금

CREATE TABLE data (blob BLOB); 

:

saveRDS(model, "model.rds") 
bin_rds <- readBin("model.rds", "raw", 1e6) 
length(bin_rds) # 6350 
관련 문제