R快速XML解析

时间:2014-04-06 01:29:59

标签: xml r

目前在R中将XML文件转换为数据帧的最快方法是什么?

XML看起来像这样:(注意 - 并非所有行都包含所有字段)

  <row>
    <ID>001</ID>
    <age>50</age>
    <field3>blah</field3>
    <field4 />
  </row>
  <row>
    <ID>001</ID>
    <age>50</age>
    <field4 />
  </row>

我尝试了两种方法:

  1. XML库中的xmlToDataFrame函数
  2. 面向速度的xmlToDF函数已发布here
  3. 对于8.5 MB的文件,使用1.6k&#34;行&#34;和114&#34;列&#34;,xmlToDataFrame耗时25.1秒,而xmlToDF在我的机器上耗时16.7秒。

    与python XML解析器(例如xml.etree.ElementTree)相比,这些时间非常大,能够在0.4秒内完成工作。

    在R中是否有更快的方法可以做到这一点,或者R中有哪些基本因素阻止我们加快速度?

    对此有所了解会非常有用!

2 个答案:

答案 0 :(得分:4)

更新了评论

d = xmlRoot(doc)
size = xmlSize(d)

names = NULL
for(i in 1:size){
    v = getChildrenStrings(d[[i]])
    names = unique(c(names, names(v)))
}

for(i in 1:size){
    v = getChildrenStrings(d[[i]])
    cat(paste(v[names], collapse=","), "\n", file="a.csv", append=TRUE)
}

对于1000x100 xml记录,这将在大约0.4秒内完成。如果你知道变量名,你甚至可以省略第一个for循环。

注意:如果xml内容包含逗号,引号,则可能需要特别注意它们。在这种情况下,我建议使用下一个方法。


如果要动态构建data.frame,可以使用data.table执行此操作,data.table比上面的csv方法慢一点,但速度比data.frame <快/ p>

m = data.table(matrix(NA,nc=length(names), nr=size))
setnames(m, names)
for (n in names) mode(m[[n]]) = "character"
for(i in 1:size){
    v = getChildrenStrings(d[[i]])
    m[i, names(v):= as.list(v), with=FALSE]
}
for (n in names) m[, n:= type.convert(m[[n]], as.is=TRUE), with=FALSE]

对于同一份文件,它在大约1.1秒内完成。

答案 1 :(得分:0)

为了防患于未然,我发现在我的用例中使用data.table的解决方案甚至更快,因为它仅在完成循环遍历行之后才将数据转换为data.table:

library(XML)
library(data.table)

doc <- xmlParse(filename)
d <- getNodeSet(doc,  "//Data")
size <- xmlSize(d)

dt <- rbindlist(lapply(1:size, function(i) {
    as.list(getChildrenStrings(d[[i]]))
}))