Как обрабатывать двоичные строки в R?

R не может справиться с нулевыми строками (\ 0) в символах, знает ли кто-нибудь, как с этим справиться? Более конкретно, я хочу хранить сложные объекты R в базе данных с использованием соединения ODBC или JDBC. Поскольку сложные объекты 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. Для этого мне нужно строковое представление объекта, чтобы отправить запрос в базу данных, например. ВСТАВЬТЕ В. Поскольку результатом является вектор типа raw vector, мне нужно его преобразовать:

 stringModel <- rawToChar(serialModel)

И есть проблема:

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

R не может иметь дело с \0 в строках. Кто-нибудь знает, как обойти это ограничение? Или, возможно, существует совершенно другой подход для достижения этой цели?

Заранее спасибо

Ответ 1

Вам нужно

stringModel <- as.character(serialModel)

для символьного представления исходных битовых кодов. rawToChar попытается преобразовать необработанные битовые коды, что в этом случае не так.

Полученная строкаModel может быть преобразована позже в исходную модель с помощью:

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

Относительно написания бинарных типов в базах данных через RODBC: на сегодняшний день виньетка RODBC читает (p.11):

В настоящее время двоичные типы могут быть читать как таковые, и они возвращаются как столбец класса "ODBC двоичный", который список исходных векторов.

Ответ 2

Совершенно другой подход состоял бы в том, чтобы просто сохранить вывод 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))