【问题标题】:xml parser in R with hierarchical nodes, tags and valuesR中带有分层节点、标签和值的xml解析器
【发布时间】:2017-04-21 19:40:22
【问题描述】:

我正在尝试从以下 xml 文件中解析 sample_attributes(最好是全部)。尝试了几件事,但 XML 被聚集到一个节点中:

xml.url <- "http://www.ebi.ac.uk/ena/data/view/ERS445758&display=xml"
xmlfile <- xmlTreeParse(xml.url)
xmltop = xmlRoot(xmlfile)
IBDcat <- xmlSApply(xmltop, function(x) xmlSApply(x, xmlValue))

还尝试了此处提到的解决方案: How to parse XML to R data framehow to create an R data frame from a xml file 但当我尝试类似:

data <- xmlParse("http://www.ebi.ac.uk/ena/data/view/ERS445758&display=xml")
xml_data <- xmlToList(data)
xmlToDataFrame(nodes=getNodeSet(data,"/SAMPLE_ATTRIBUTE"))[c("age","sex","body site","body-mass index")]

我收到一个错误提示选择了未定义的列

任何帮助将不胜感激!

【问题讨论】:

    标签: r xml xml-parsing


    【解决方案1】:

    这是一个 tidyverse 选项; xml2 有一个简单的 read_xml 函数,它具有关联的 as_list 函数。 purrr 是一个非常方便的列表操作包,当然,如果您愿意,也可以在基础 R 中做同样的事情。

    library(xml2)
    library(purrr)
    
    x <- read_xml("http://www.ebi.ac.uk/ena/data/view/ERS445758&display=xml")
    
    x_list <- as_list(x)
    
    x_df <- x_list %>% map('SAMPLE_ATTRIBUTES') %>% flatten() %>% map_df(flatten)
    
    x_df
    #> # A tibble: 35 × 3
    #>                       TAG                               VALUE UNITS
    #>                     <chr>                               <chr> <chr>
    #> 1      investigation type                          metagenome  <NA>
    #> 2            project name                                BMRP  <NA>
    #> 3     experimental factor                          microbiome  <NA>
    #> 4             target gene                            16S rRNA  <NA>
    #> 5      target subfragment                                V1V2  <NA>
    #> 6             pcr primers                            27F-338R  <NA>
    #> 7   multiplex identifiers                          TGATACGTCT  <NA>
    #> 8       sequencing method                      pyrosequencing  <NA>
    #> 9  sequence quality check                            software  <NA>
    #> 10          chimera check ChimeraSlayer; Usearch 4.1 database  <NA>
    #> # ... with 25 more rows
    

    或者改为在 XPath 中进行子集设置:

    x %>% xml_find_all('//SAMPLE_ATTRIBUTE') %>% map(as_list) %>% map_df(flatten)
    

    返回相同的东西。

    【讨论】:

    • 感谢您的两个回答!我目前在 RStudio 中运行 R 3.2.2。我尝试安装 Purr,但它不适用于此版本:/ 所以实际上无法使用地图功能...需要 R 的重大更新,但迫不及待想尝试解决方案!
    • 它应该可用并在 3.2.2 上工作;它具有的最高 R 版本依赖项是 3.1.2(通过 dplyr)。更新到最新版本的 R 总是一件好事,但请确保您拥有三个“r”;该错误通常是包名拼写错误的结果:install.packages("purrr") 或只是执行install.packages("tidyverse"),其中包括purrrxml2 和其他一些有用的包。
    • 这是第三个 r
    【解决方案2】:

    至少对于您的第二次尝试,您只需要使用 // 选择 any SAMPLE_ATTRIBUTE 节点。然后按标签子集。

    doc <- xmlParse(xml.url)
    x <- xmlToDataFrame(getNodeSet(doc,"//SAMPLE_ATTRIBUTE"))
    ## OR 
    xmlToDataFrame(doc["//SAMPLE_ATTRIBUTE"])
                      TAG      VALUE UNITS
    1  investigation type metagenome  <NA>
    2        project name       BMRP  <NA>
    3 experimental factor microbiome  <NA>
    4         target gene   16S rRNA  <NA>
    5  target subfragment       V1V2  <NA>
    ...
    
    
    subset(x, TAG %in% c("age","sex","body site","body-mass index") )
                   TAG         VALUE UNITS
    15             age            28 years
    16             sex          male  <NA>
    17       body site Sigmoid colon  <NA>
    19 body-mass index    16.9550173  <NA>
    

    【讨论】:

      【解决方案3】:

      @allistaire 非常有创意的方法略有不同:

      library(xml2)
      
      doc <- read_xml("http://www.ebi.ac.uk/ena/data/view/ERS445758&display=xml")
      
      xml_find_all(doc, ".//SAMPLE_ATTRIBUTE") %>% 
        map(xml_children) %>% 
        map_df(~as.list(setNames(xml_text(.), xml_name(.))))
      

      【讨论】:

      • 感谢您的两个回答!我目前在 RStudio 中运行 R 3.2.2。我尝试安装 Purr,但它不适用于此版本:/ 所以实际上无法使用地图功能...需要 R 的重大更新,但迫不及待想尝试解决方案!
      猜你喜欢
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-05
      • 2016-11-12
      相关资源
      最近更新 更多