2

我正在尝试使用 R 从混合数据文件(ascii 和二进制)中读取二进制数据,数据文件以伪 xml 格式构造。我的想法是使用扫描功能,读取特定行,然后将二进制转换为数值,但我似乎无法在 R 中执行此操作。我有一个执行此操作的 python 脚本,但我想做R中的工作,python脚本如下。数据文件中的二进制部分由开始和结束标记以及 .

数据文件是包含光谱数据的专有格式,下面包含示例数据文件的链接。引用用户手册:

BinData 元素的数据以二进制字节数组的形式写入。二进制数组的每 8 个字节代表一个双精度浮点值。因此二进制数组的大小是 NumberOfPoints * 8 字节。对于二维数组,数据布局遵循 SafeArrays 使用的行优先格式。这意味着移动到下一个数组元素会增加最后一个索引。例如,如果以这种一维二进制字节数组形式写入二维数组(例如 Data(i,j)),则移动到二进制数组的下一个 8 字节元素会增加原始二维的最后一个索引数组(即数据(i,j+1))。在二进制数组的最后一个元素之后写入回车符和换行符的组合(ANSI 字符 13 和 10)。

感谢您提前提出任何建议!

链接到示例数据文件:

https://docs.google.com/file/d/0B5F27d7b1eMfQWg0QVRHUWUwdk0/edit?usp=sharing

Python脚本:

import sys, struct, csv
f=open(sys.argv[1], 'rb')
#
t = f.read()
i = t.find("<BinData>") + len("<BinData>") + 2 # add \r\n line end
header = t[:i]
#
t = t[i:]
i = t.find("\r\n</BinData>")
bin = t[:i]
#
doubles=[]
for i in range(len(bin)/8):
  doubles.append(struct.unpack('d', bin[i*8:(i+1)*8])[0])
#
footer = t[i+2:]
#
myfile = open("output.csv", 'wb')
wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
wr.writerow(doubles)
4

1 回答 1

2

我编写了pack 包以使这更容易。不过,您仍然必须搜索二进制数据的开始/结束。

b <- readBin("120713b01.ols", "raw", 4000)
# raw version of the start of the BinData tag
beg.raw <- charToRaw("<BinData>\r\n")
# only take first match, in case binary data randomly contains "<BinData>\r\n"
beg.loc <- grepRaw(beg.raw,b,fixed=TRUE)[1] + length(beg.raw)
# convert header to text
header <- scan(text=rawToChar(b[1:beg.loc]),what="",sep="\n")
# search for "<Number of Points"> tags and calculate total number of points
numPts <- prod(as.numeric(header[grep("<Number of Points>",header)+1]))

library(pack)
Data <- unlist(unpack(rep("d", numPts), b[beg.loc:length(b)]))
于 2013-07-31T16:54:16.957 回答