例如,我有以下XML代码
tt = '<Nummeraanduiding>
<identificatie>0010200000114849</identificatie>
<aanduidingRecordInactief>N</aanduidingRecordInactief>
<aanduidingRecordCorrectie>0</aanduidingRecordCorrectie>
<huisnummer>13</huisnummer>
<officieel>N</officieel>
<postcode>9904PC</postcode>
<tijdvakgeldigheid>
<begindatumTijdvakGeldigheid>2010051100000000</begindatumTijdvakGeldigheid>
</tijdvakgeldigheid>
<inOnderzoek>N</inOnderzoek>
<typeAdresseerbaarObject>Verblijfsobject</typeAdresseerbaarObject>
<bron>
<documentdatum>20100511</documentdatum>
<documentnummer>2010/NR002F</documentnummer>
</bron>
<nummeraanduidingStatus>Naamgeving uitgegeven</nummeraanduidingStatus>
<gerelateerdeOpenbareRuimte>
<identificatie>0010300000000444</identificatie>
</gerelateerdeOpenbareRuimte>
</Nummeraanduiding> '
目标是将此节点(Nummeraanduiding)转换为data.table(或data.frame也可以)。一个挑战是我有很多这些Nummeraanduiding节点(数百万个)。
以下代码可以处理数据:
library(XML)
# This parses the doc...
doc = xmlParse(tt)
# Solution (1) - this is the most obvious solution..
XML::xmlToDataFrame(doc)
# Solution (2) - apparently converting to a list is also possible..
unlist(xmlToList(doc))
# Solution (3) - My own solution
data.frame(as.list(unlist(xmlToList(doc))))
并非所有解决方案都能产生预期效果......最终只有Solution(3)的版本满足了我的需求。
然而,为我的所有数据运行这段代码变得非常慢。花了8个多小时来完成一个文件,其中包含2290000倍的Nummeraanduiding&#39; -node。
你们知道加快这个过程的方法吗?我的方法可以改进吗?我可能错过了一些有用的功能吗?
答案 0 :(得分:0)
鉴于每个字段已经在单独的行中grep
,请使用read.table
读取剩余内容并使用tapply
从长转换为宽来生成结果矩阵(如果需要,可以将其转换为数据帧或data.table)。请注意,在read.table
中,我们绕过引用,注释和类处理。最后,测试一下它是否更快。没有包使用。
nms <- c("identificatie", "aanduidingRecordInactief", "aanduidingRecordCorrectie",
"huisnummer", "officieel", "postcode", "tijdvakgeldigheid.begindatumTijdvakGeldigheid",
"inOnderzoek", "typeAdresseerbaarObject", "bron.documentdatum",
"bron.documentnummer", "nummeraanduidingStatus",
"gerelateerdeOpenbareRuimte.identificatie")
rx <- paste(nms, collapse = "|")
g <- chartr("<", ">", grep(rx, readLines(textConnection(tt)), value = TRUE))
long <- read.table(text = g, sep = ">", quote = "", comment.char = "",
colClasses = "character")[2:3]
names(long) <- c("field", "value")
long$field <- factor(long$field, levels = nms) # maintain order of columns
long$recno <- cumsum(long$field == "identificatie")
with(long, tapply(value, list(recno, field), c))
如果所有记录都具有完全相同的字段集,例如nms
中列出的字段,则最后一行可以替换为此字段(可能更快):
matrix(long$value, ncol = length(nms), byrow = TRUE, dimnames = list(NULL, nms))
tapply
行的另一种替代方法是使用基础R中的reshape
或使用reshape2包中的dcast
。