将(可能是格式错误的)xml转换为R中的数据框

马特·威廉姆森

我正在尝试将xml文件从美国联邦公报档案库转换为数据框,其中每一行对应于一个特定的动作(例如,通知,规则,提议的规则),并且每一列都包含与该动作相关的属性(例如,代理商类型,主题等)。我尝试了以下方法:

> setwd("C:/Users/mwilliamson/Desktop/FedReg/2000/01/")
> url = "FR-2000-01-18.xml"
> doc <- xmlInternalTreeParse("FR-2000-01-18.xml")
> doc_list <- xmlToList(doc)
> library(plyr)
> j <- ldply(doc_list, data.frame)

但是,它返回一个错误:

Error in data.frame(SECTNO = "§ 831.502", SUBJECT = "Automatic separation;  
exemption.",  : 
arguments imply differing number of rows: 1, 0

似乎空白值的数量和变量长度的差异在R处理XML时造成了问题(我可能是错的,对xml包没有太多经验)。我认为可能可以使用架构(.xsd)文件来避免这种情况,但是目前尚不清楚如何将xmlToList与架构一起使用。本质上,我正在寻找“最佳”方式来将xml处理到我描述的数据帧中,并用NA填充所有空白单元格。我已经将架构和示例文件上传到:

https://www.dropbox.com/sh/pluje12t185w1v2/ys1xHzilQO

您可以提供的任何帮助都会很棒!

更新:我也尝试过:

xmlToDataFrame(doc, colClasses = character, homogeneous = NA)

但收到以下信息:

Error: duplicate subscripts for columns

再次感谢您提供的任何帮助。

更新:看来/ AGENCY节点是数据开始真正适合我尝试创建的格式的位置;但是,我似乎无法提取所有其余数据(即,我可以获得包含115个记录的唯一列来标识代理商,但无法获取与这115个记录相关的其余信息)。我尝试了以下方法:

out <- getNodeSet(doc, "//*", fun=xmlToList)
df <- data.frame(do.call(rbind, out))
head(df)

但这似乎导致R崩溃。我希望我的不断更新会激发别人的帮助。再次感谢您提供的任何帮助。

克里斯·S

这个XML很乱,我的猜测是您需要分别解析每个动作。

table(xpathSApply(doc, "//FEDREG/child::node()", xmlName))
    DATE  NEWPART       NO  NOTICES PRESDOCS PRORULES    RULES UNITNAME      VOL 
      12        6       12        1        3        1        1       12       12 

table(xpathSApply(doc, "//NOTICES/child::node()", xmlName))
   NOTICE 
       92 

使用getNodeSet获取通知

z <- getNodeSet(doc, "//NOTICE")
z[[1]]
# check node names
sapply(z, xmlSApply, xmlName)
x <- xmlToDataFrame(z)
dim(x)
[1] 92  4

因此,这混和了PREAMB和SUPLINFO的许多细节,因此您可能需要分别解析这些节点。

如果您只是服用PREAMB,那也是一团糟...

z2 <- getNodeSet(doc, "//NOTICE/PREAMB")
# check node names and notice different formats
sapply(z2, xmlSApply, xmlName)
## and count
sort( table(unlist(sapply(z2, xmlSApply, xmlName))) )
AUTH   BILCOD     NOTE GPOTABLE    STARS  PRTPAGE     DATE     FTNT      GPH  EFFDATE      ADD    DATES       FP      SIG   DEPDOC  EXTRACT      SUM 
   2        3        3        5        5        8       15       15       15       16       19       24       32       37       45       47       52 
 AGY   FURINF   SUBAGY      ACT   AGENCY  SUBJECT       HD        P 
  54       54       55       57       92       92      103      663 

我在这里看到了三种不同的格式,因此xmlToDataFrame可以与某些节点一起使用,但不是所有节点

x <- xmlToDataFrame(z2[1:4])

将这10列与代码中ldply的结果进行比较

doc_list <-  getNodeSet(doc, "//NOTICE/PREAMB", fun=xmlToList)
## this returns 31 columns since it grabs every child node...
j <- ldply(doc_list[1:4], data.frame)
names(j)

我认为有时最好循环遍历getNodeSet结果并解析您需要的内容,如果节点不存在,请确保添加NA(在此处使用xp函数)。有关免费创建子文档和修复内存泄漏的信息,请参见?getNodeSet,但对于最常见的格式,可能是这样的。您可以添加带有大量HD,EXTRACT和P标签的通知的支票并获取其他列。

xp <- function (doc, tag){
   n <- xpathSApply(doc, tag, xmlValue)
   if (length(n) > 0) 
      # paste multiple values?  BILCOD and probably others..
      paste0(n, collapse="; ") 
   else NA
}


  z <- getNodeSet(doc, "//NOTICE")
  n <-length(z)
  notices <-vector("list",n)
  for(i in 1:n)
  {
     z2<-xmlDoc(z[[i]])
     notices[[i]] <- data.frame(
      AGENCY = xp(z2, "//AGENCY"),
      SUBAGY = xp(z2, "//SUBAGY"),
      SUBJECT = xp(z2, "//PREAMB/SUBJECT"),    ##  SUBJECT node in SECTION too, so it helps to be as specific as possible
      ACT= xp(z2, "//ACT"),
      SUM = xp(z2, "//SUM"),
      DATES = xp(z2, "//DATES"),
      ADD = xp(z2, "//ADD"),
      FURINF = xp(z2, "//FURINF"),
      SIG = xp(z2, "//PREAMB/SIG"),     ## SIG in SUPLINF too
      SUPLINF = xp(z2, "//SUPLINF"),
      FRDOC = xp(z2, "//FRDOC"),
      BILCOD = xp(z2, "//BILCOD"),
      DEPDOC = xp(z2, "//DEPDOC"),
      PRTPAGE = xp(z2, "//PRTPAGE"),
       stringsAsFactors=FALSE)
     free(z2)  
  }
  x <- do.call("rbind", notices)
  head(x)
  table(is.na(x$ACT) )
  FALSE  TRUE 
     57    35 

您仍然有SUPLINF之类的列,其中将许多结构化数据混在一起-如果需要,可以将其分解...

table(xpathSApply(doc, "//NOTICE/SUPLINF/child::node()", xmlName))

AMDPAR APPENDIX     AUTH   BILCOD     DATE  EXTRACT       FP     FTNT      GPH GPOTABLE       HD   LSTSUB        P  PRTPAGE      SIG     text 
     1        1       10        1        4       10       23       31       10       12      186        1      783        4       52        1 

xpathSApply(doc, "//NOTICE/SUPLINF/GPH", xmlValue)
[1] "EN18JA00.000" "EN18JA00.001" "EN18JA00.002" "EN18JA00.003" "EN18JA00.004" "EN18JA00.005" "EN18JA00.006" "EN18JA00.007" "EN18JA00.008" "EN18JA00.009"
 ## since SIG is in PREAMB and SUPLINF, you may want to parse that separately
 xpathSApply(doc, "//NOTICE/SUPLINF/SIG", xmlValue) 

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将网站完全以XML格式转换为pandas数据框

来自分类Dev

将列表格式的数据框转换为 R 中的矩阵格式

来自分类Dev

R:将XML数据转换为数据框

来自分类Dev

将R数据框中的多列转换为日期格式

来自分类Dev

将尾注 XML 转换为 R 数据框

来自分类Dev

将xml数据转换为数据框

来自分类Dev

将数据框转换为XML

来自分类Dev

将XML转换为pandas数据框

来自分类Dev

将xml转换为数据框

来自分类Dev

将数据框转换为XML

来自分类Dev

将类规则的对象转换为R中的数据框

来自分类Dev

R数据框:将多行中的值转换为列表

来自分类Dev

将数据框转换为R中的列表

来自分类Dev

将列表从R中的knoema包转换为数据框

来自分类Dev

R数据框:将多行中的值转换为列表

来自分类Dev

将日期列表转换为R中的数据框

来自分类Dev

R:将列表中数据框的因数转换为数值

来自分类Dev

将项目列表转换为R中的数据框

来自分类Dev

将列表转换为R中的数据框

来自分类Dev

将Facebook htm文件转换为R中的数据框

来自分类Dev

将级别转换为 r 中的数据框列

来自分类Dev

在 R 中将 XML 转换为数据框

来自分类Dev

将格式转换为R(大量数据)

来自分类Dev

将Pandas数据框转换为Spark数据框错误

来自分类Dev

将json格式数据转换为数据框

来自分类Dev

R - 将列表转换为数据框

来自分类常见问题

在数据框中从长格式转换为宽格式

来自分类Dev

在数据框中从长格式转换为宽格式

来自分类Dev

如何将基于列的大型数据框转换为R中的数据框列表