如何在 R 中读取大 (~20 GB) xml 文件?

Posted

技术标签:

【中文标题】如何在 R 中读取大 (~20 GB) xml 文件?【英文标题】:How to read large (~20 GB) xml file in R? 【发布时间】:2015-04-24 10:14:33 【问题描述】:

我想从大型 xml 文件 (20 GB) 中读取数据并对其进行操作。我厌倦了使用“xmlParse()”,但它在加载之前给了我内存问题。有什么有效的方法吗?

我的数据转储是这样的,

<tags>                                                                                                    
    <row Id="106929" TagName="moto-360" Count="1"/>
    <row Id="106930" TagName="n1ql" Count="1"/>
    <row Id="106931" TagName="fable" Count="1" ExcerptPostId="25824355" WikiPostId="25824354"/>
    <row Id="106932" TagName="deeplearning4j" Count="1"/>
    <row Id="106933" TagName="pystache" Count="1"/>
    <row Id="106934" TagName="jitter" Count="1"/>
    <row Id="106935" TagName="klein-mvc" Count="1"/>
</tags>

【问题讨论】:

您需要一次在工作区中的整个文档树吗?否则你可以逐行阅读 无需一次加载全部数据。我可以逐行阅读并处理它们吗?或者我可以将数据作为块加载,然后处理它们。如果您能提出任何建议,我将不胜感激。 您可以使用函数 readLines 并将 n 设置为您要阅读的行数。也应该可以使用 SAX 解析器(您使用的包提供了它)。我可以稍后添加一个示例(这台机器上没有 R)。也许你可以解释更多你想对你的文件做什么,而不是提供一个有意义的例子。 也许***.com/questions/22643580/… 也有帮助。 【参考方案1】:

在 XML 包中,xmlEventParse 函数实现了 SAX(读取 XML 并调用您的函数处理程序)。如果您的 XML 足够简单(在一个根元素中重复元素),您可以使用 branches 参数为每​​个元素定义函数。

例子:

MedlineCitation = function(x, ...) 
  #This is a "branch" function
  #x is a XML node - everything inside element <MedlineCitation>
  # find element <ArticleTitle> inside and print it:
  ns <- getNodeSet(x,path = "//ArticleTitle")
  value <- xmlValue(ns[[1]])
  print(value)

调用XML解析:

xmlEventParse(
  file = "http://www.nlm.nih.gov/databases/dtd/medsamp2015.xml", 
  handlers = NULL, 
  branches = list(MedlineCitation = MedlineCitation)
)

闭包解决方案:

就像马丁摩根一样,Storing-specific-xml-node-values-with-rs-xmleventparse:

branchFunction <- function() 
  store <- new.env() 
  func <- function(x, ...) 
    ns <- getNodeSet(x, path = "//ArticleTitle")
    value <- xmlValue(ns[[1]])
    print(value)
    # if storing something ... 
    # store[[some_key]] <- some_value
  
  getStore <- function()  as.list(store) 
  list(MedlineCitation = func, getStore=getStore)


myfunctions <- branchFunction()

xmlEventParse(
  file = "medsamp2015.xml", 
  handlers = NULL, 
  branches = myfunctions
)

#to see what is inside
myfunctions$getStore()

【讨论】:

这对我来说很好用!。是否可以在 R 中使用 Hadoop 解决这个问题?假设我想计算每个 TagName。 我正在做与您提到的类似的事情。问题是它随着时间的推移而变慢。一开始打印出来的东西非常快。我尝试使用“rm(list -ls())”,但没有任何帮助。 更新了 M. Morgan 的解决方案(带有闭包)。 @Karthick 你有没有想过一种方法可以在不降低内存速度的情况下做到这一点?我正在经历同样的事情。 @Karthick 你有没有想过一种方法可以在不降低内存速度的情况下做到这一点?我正在经历同样的事情

以上是关于如何在 R 中读取大 (~20 GB) xml 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 .NET 中读取大 (1GB) 文本文件?

如何在lua中读取大文件(> 1GB)?

将 20 GB csv 文件加载到 R 中的最佳方法是啥?

如何在 Java 中解析大 (50 GB) XML 文件

使用 Python 或 R 将非常大的 sql 文件导出到 csv

如何读取大约 2 GB 的文本文件? [复制]