我有一个具有这种结构的xml文件。
<?xml version="1.0" encoding="utf-8"?>
<b>
<c name="Foo" stuff="89" attr="First line
Second line"/>
<c name="Bar" ID="ontime" stuff="23" attr="Blahs"/>
<c ID="delay" name="Dog" newattr="Clahs"/>
...
</b>
正如您所看到的,属性非常混乱;缺少值和未对齐。我想将其转换为R语言中的以下数据框(或任何其他类似表格的结构)以供进一步分析。
╔══════════╦══════════════╦══════════════════════════════════╦════════════════╦═════════╗
║ name ║ stuff ║ attr ║ ID ║ newattr ║
╠══════════╬══════════════╬══════════════════════════════════╬════════════════╬═════════╣
║ 1 Foo ║ 89 ║ "First line
Second line" ║ NA ║ NA ║
║ 2 Bar ║ 23 ║ "Blahs" ║ "ontime" ║ NA ║
║ 3 Dog ║ NA ║ NA ║ "delay" ║ "Clahs" ║
╚══════════╩══════════════╩══════════════════════════════════╩════════════════╩═════════╝
由于我有限的R和解析经验,我失败了。我有一种感觉xapplySApply
可能有用,但无法弄清楚如何设置路径。
我想探索的另一种技术是让代码自己识别新属性。换句话说,代码中没有对属性的名称进行硬编码。例如,当它看到第3行时,它会自动将新列添加到数据框并将其命名为“newattr”。
非常感谢你的帮助。
------------------- 2015年7月18日新增---------------------- -
这是我的蛮力方法。我相当确定有更好的方法来做到这一点,因为它超级慢(在现代个人笔记本电脑上处理一个~250MB xml的6小时)。
myxmlToDataFrame2 <- function(file) {
xL <- xmlToList(xmlParse(file))
xL <- unname(xL)
# initialize data frame
df <- data.frame(t(xL[[1]]), stringsAsFactors = FALSE)
number_of_attribute <- length(df)
number_of_row <- length(xL)
for (i in 2:number_of_row) {
# examine each element in the new row
for (j in 1:length(xL[[i]])) {
df[i,attributes(xL[[i]])$names[j]] <- xL[[i]][[j]]
}
}
df
}
答案 0 :(得分:0)
我们真的需要一个完整的例子。填写NA
数据会有问题。
这是让你入门的东西:
library(XML)
xml <- '<b>
<c name="Foo" stuff="89" attr="First line
Second line"/>
<c name="Bar" ID="ontime" stuff="23" attr="Blahs"/>
<c ID="delay" name="Dog" attr="Clahs"/>
</b>'
xml <- xmlParse(xml)
attr_vals <- unlist(xpathApply(xmlParse(xml), "//b/c/@attr"))
stuff_vals <- unlist(xpathApply(xmlParse(xml), "//b/c/@stuff"))
ids_vals <- unlist(xpathApply(xmlParse(xml), "//b/c/@ID"))
答案 1 :(得分:0)
您可以尝试在c节点上使用xmlAttrsToDataFrame
XML:::xmlAttrsToDataFrame(xml["//c"])
name stuff attr ID newattr
1 Foo 89 First line\nSecond line <NA> <NA>
2 Bar 23 Blahs ontime <NA>
3 Dog <NA> <NA> delay Clahs