2011-05-10 29 views
10

R無法處理字符中的空字符串(\ 0),有誰知道如何處理?更具體地說,我想使用ODBC或JDBC連接將複雜的R對象存儲在數據庫中。由於複雜的R對象不容易被映射到數據框,我需要不同的可能性來存儲這些對象。一個目的可以是例如:如何處理R中的二進制字符串?

library(kernlab) 
data(iris) 
model <- ksvm(Species ~ ., data=iris, type="C-bsvc", kernel="rbfdot", kpar="automatic", C=10) 

由於>模型<不能被直接存儲在數據庫中,我使用的serialize()函數來檢索對象的二進制表示(爲了將其存儲在BLOB列):

serialModel <- serialize(model, NULL) 

現在我想通過ODBC/JDBC存儲這個。爲此,我需要對象的字符串表示,以便向數據庫發送查詢,例如,插入。由於結果是原料型矢量的矢量,我需要將其轉換:

stringModel <- rawToChar(serialModel) 

還有的問題是:

Error in rawToChar(serialModel) : 
    embedded nul in string: 'X\n\0\0\0\002\0\002\v\0...... 

R不能夠處理\ 0字符串。有沒有人有想法如何繞過這個限制?或者可能有完全不同的方法來實現這一目標?

在此先感謝

+0

支持此的明顯方法是數據庫連接器將原始向量存儲爲BLOB。 RODBC不支持這個嗎?如果沒有,我會感到驚訝。我知道RMySQL沒有。這是在我的待辦事項列表,雖然;) – Jeff 2011-05-10 15:03:01

+0

這是我正在尋找。但是,我不知道RODBC或RJDBC提供此功能的任何功能:/ – Thomas 2011-05-10 16:41:21

回答

10

你需要

stringModel <- as.character(serialModel) 

爲原始比特編碼的字符表示。 rawToChar將嘗試轉換原始位代碼,在這種情況下這不是您想要的。

所得stringModel可以通過稍後被轉換回原始模型:

newSerialModel <- as.raw(as.hexmode(stringModel)) 
newModel <- unserialize(newSerialModel) 
all.equal(model,newModel) 
[1] TRUE 

關於二進制類型的寫入到數據庫通過RODBC:作爲用於在今天,vignette of RODBC讀取(第11):

二進制類型目前只能 讀爲這樣,它們被返回作爲類「ODBC二進制」,這是 柱 原始矢量列表。

+0

爲了將對象轉換爲字符串並將其存儲在CLOB中,我已經有了類似的解決方案。我的問題是針對這個問題,如果有可能直接存儲二進制表示(在一個BLOB中)。轉換花費很多時間。所以我正在尋找一種解決方案來有效地在數據庫中保存對象。這是你在一行中提出的:unserialize(as.raw(as.hexmode(strsplit(paste(serialize(model,NULL),collapse =「」),「」)[[1]]))) Most的時間花費在paste()和strsplit()中 - 我寧願要一個直接使用二進制表示的解決方案。 – Thomas 2011-05-10 15:24:40

+0

@Thomas:我建議存儲stringModel。我真的沒有看到粘貼和strsplit來自哪裏。這根本不需要。你要求一個二進制表示的字符形式,那就是stringModel。 – 2011-05-10 15:45:45

+0

使用ODBC命令sqlQuery(conn,paste(「INSERT INTO bla VALUES('」,stringModel,「')」,sep =「」))只存儲了字符串向量的第一個值,因此我需要一些邏輯創建一個單一的字符串 - 當然還有一個方法來解串字符串... – Thomas 2011-05-10 15:52:58

4

完全不同的方法是簡單地的capture.output(dput(model))輸出存儲與描述性的名稱一起,然後用<-assign()重建它。請參閱下面關於capture.output()需求的評論。

> dput(Mat1) 
structure(list(Weight = c(7.6, 8.4, 8.6, 8.6, 1.4), Date = c("04/28/11", 
"04/29/11", "04/29/11", "04/29/11", "05/01/11"), Time = c("09:30 ", 
"03:11", "05:32", "09:53", "19:52")), .Names = c("Weight", "Date", 
"Time"), row.names = c(NA, -5L), class = "data.frame") 
> y <- capture.output(dput(Mat1)) 
> y <- paste(y, collapse="", sep="") # Needed because capture output breaks into multiple lines 
> dget(textConnection(y)) 
    Weight  Date Time 
1 7.6 04/28/11 09:30 
2 8.4 04/29/11 03:11 
3 8.6 04/29/11 05:32 
4 8.6 04/29/11 09:53 
5 1.4 05/01/11 19:52 
> new.Mat <- dget(textConnection(y)) 
+0

好的解決方案。但是你不能通過挖掘模糊的六角模型來展示你的R肌肉。 – 2011-05-10 14:53:35

+0

我承認你對內部人員Joris的指揮印象深刻。 – 2011-05-10 14:55:54

+0

dput()導致另一個複雜對象無法通過INSERT INTO查詢發送到數據庫。而且我不想將對象存儲在硬盤上。 – Thomas 2011-05-10 15:27:12

相關問題