【问题标题】:In R, how to extracting two values from XML file, looping over 5603 files and write to table在 R 中,如何从 XML 文件中提取两个值,循环 5603 个文件并写入表
【发布时间】:2014-04-29 23:56:51
【问题描述】:

由于我对 R 比较陌生,因此我正在尝试学习如何从 XML 文件中提取两个值并循环遍历工作目录中的 5603 个其他(小,

我已经阅读了很多关于“循环”的主题,但发现这相当混乱 - 特别是因为循环 XML 文件似乎不同于循环其他文件,对吗?

我正在使用 XML 结构的在线数据。

对于每个 XML 文件,我想将“ZipCode”和“AwardAmount”写入表格。

运行以下代码,我确实检索了 ZipCode 和 AwardAmount,但仅从第一个文件中检索。如何编写正确的循环并将其写入表?

xmlfiles=list.files(pattern="*.xml")
for (i in 1:length(xmlfiles)){
    doc= xmlTreeParse("xmlfiles[i]", useInternal=TRUE)
    zipcode<-xmlValue(doc[["//ZipCode"]])
    amount<-xmlValue(doc[["//AwardAmount"]])
}

有人有什么建议吗?

【问题讨论】:

  • 好吧"xmlfiles[i]" 绝对行不通。尝试使用 paste(xmlfiles, seq_along(xmlfiles), sep = "") 创建文件名

标签: xml r parsing loops


【解决方案1】:

这可能对你有用。我摆脱了for 循环并选择了sapply

xmlfiles <- list.files(pattern = "*.xml")
txtfiles <- gsub("xml", "txt", xmlfiles, fixed = TRUE)

txtfiles 是一组新文件名,用作每次运行的输出文件。

sapply(seq(xmlfiles), function(i){

  doc <- xmlTreeParse(xmlfiles[i], useInternal = TRUE)
  zipcode <- xmlValue(doc[["//ZipCode"]])
  amount <- xmlValue(doc[["//AwardAmount"]])
  DF <- data.frame(zip = zipcode, amount = amount)
  write.table(DF, quote = FALSE, row.names = FALSE, file = txtfiles[i])

})

请在运行时告诉我是否有问题。

【讨论】:

    【解决方案2】:

    与 Richard 的方法略有不同(仅略有不同)。使用ldply 制作数据框,然后再将其写入文件。您应该选择他的答案,因为 ldply 函数的“胆量”是他的,但这只是显示了另一种方法(假设您想要一个文件而不是多个文件):

    setwd("LOCATION_OF_XML_FILES")
    
    xmlfiles <- list.files(pattern = "*.xml")
    
    dat <- ldply(seq(xmlfiles), function(i){
    
      doc <- xmlTreeParse(xmlfiles[i], useInternal = TRUE)
    
      zipcode <- xmlValue(doc[["//ZipCode"]])
      amount <- xmlValue(doc[["//AwardAmount"]])
    
      return(data.frame(zip = zipcode, amount = amount))
    
    })
    
    head(dat)
    ##         zip amount
    ## 1 442420001  45000
    ## 2 479072114 400580
    ## 3 303320420  22050
    ## 4 326112002  12000
    ## 5 265066845  37000
    ## 6 168027000 300000
    
    write.csv(dat, "zipamount.csv", row.names=FALSE)
    

    您可以将append=TRUE 与Richard 的方法一起使用,并在write.table 中使用单个文件名来做同样的事情。您还可以调整write.csv(或write.table)的输出设置,以获得您最终想要使用的输出格式。

    您还可以将 recursive = TRUE 添加到 list.files 以遍历所有子目录,而不是将所有约 5,600 个文件放入一个目录(在某些文件系统/操作系统上可能会出现性能问题)。

    【讨论】:

    • hrbrmstr,非常感谢您的 cmets。使用您的方法,我能够构建一个文件。您的 cmets 帮助我更好地理解了正在发生的事情。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-09-04
    • 2020-08-16
    • 2020-05-02
    • 1970-01-01
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    相关资源
    最近更新 更多