【问题标题】:R - parse unaligned XML attribute to data frameR - 将未对齐的 XML 属性解析为数据框
【发布时间】:2015-10-07 18:02:38
【问题描述】:

我有一个具有这种结构的 xml 文件。

<?xml version="1.0" encoding="utf-8"?>
<b>
    <c name="Foo" stuff="89" attr="First line&#xA;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&#xA;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
}

【问题讨论】:

  • 你能粘贴更大的文件块(或文件的链接),看看是否还有其他错误(以及有更多工作要做)吗?
  • 感谢您的快速响应。我已经编辑了原始帖子以反映实际的文件内容。

标签: xml r xml-parsing dataframe


【解决方案1】:

我们真的需要一个完整的例子。 NA 数据填充会有问题。

这里有一些东西可以帮助你开始:

library(XML)

xml <- '<b>
<c name="Foo" stuff="89" attr="First line&#xA;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"))

【讨论】:

    【解决方案2】:

    您可以尝试在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-15
      相关资源
      最近更新 更多