Rでバイナリファイルにデータを書き出すときにはwriteBin関数を使用します。
このwiteBin関数はベクトルしか出力することが出来ないため、行列をそのままバイナリに出力することが出来ません。そのため、行列から行ベクトル(もしくは列ベクトル)を取り出して出力する必要があります。そこで、下記のサンプルコードでは16~18行目で列ごとにデータを出力しています。
また、バイナリのヘッダに行数・列数を記録しておくと、読み取りの時に便利になります。13行目で列数と行数を出力しています。
2022/2/4追記
型を明示していないと思わぬ値が書き込まれている事がありました。
特に整数型を書き込むときは要注意です。
writeBin関数のときにas.integer, as.double などで型を明示しておくのが良さそうです。
ついでに、バイナリファイルの読み込みのサンプルを追記しました。
sDir <- "D:/Working/dir"
setwd(sDir)
# 行列を作成する
iRow <- 12
iCol <- 10
mtDat <- matrix(1:(iRow*iCol)/10, nrow=iRow, ncol=iCol)
#### データの書き込み ####
con <- file("./Date.bin", "wb")
#ヘッダ
writeBin(as.integer(c(ncol(mtDat), nrow(mtDat))), con, endian="little")
#データの中身
for(i in 1:ncol(mtDat)){
writeBin(as.double(mtDat[,i]), con, endian="little")
}
#ファイルを閉じる
close(con)
#Date.binの容量
# ヘッダ:8Byte = 2 × sizeof(int)
# データ:480Byte = 120 × sizeof(double)
#### バイナリ読み取り
con <- file("./Date.bin", "rb")
iNC <- readBin(con, "int", n=1, endian="little")
iNR <- readBin(con, "int", n=1, endian="little")
mt3 <- matrix(1:(iNR*iNC), nrow=iNR, ncol=iNC)
for (i in 1:iNR){
mt3[i,] = readBin(con, "double", n=iNC, endian="little")
}
close(con)
下記は、上記で出力したバイナリファイルをC#で読み取っているサンプルです。
const string sIn = @"D:\Working/dir\Date.bin";
const string sOF = @"D:\Working/dir\Date.csv";
static void Main(string[] args) {
using (FileStream fsI = new FileStream(sIn, FileMode.Open, FileAccess.Read))
using (StreamWriter sw = new StreamWriter(sOF, false, Encoding.ASCII)) {
sw.WriteLine("Col,Row,Value");
byte[] buf = new byte[8];
fsI.Read(buf, 0, 8);
int iNc = BitConverter.ToInt32(buf, 0);
int iNr = BitConverter.ToInt32(buf, 4);
buf = new byte[8 * iNr];
for(int iC = 0; iC < iNc; iC++) {
fsI.Read(buf, 0, 8 * iNr);
for(int iR = 0; iR < iNr; iR++) {
double dV = BitConverter.ToDouble(buf, 8 * iR);
sw.WriteLine("{0},{1},{2:e2}", iC + 1, iR + 1, dV);
}
}
}
}