【问题标题】:R: How to best extract two XML attributes from a node?R:如何最好地从一个节点中提取两个 XML 属性?
【发布时间】:2016-12-22 16:12:14
【问题描述】:

以下代码从 XML 文件中提取一个(或全部)属性:

library(xml2);library(magrittr);library(readr);library(tibble);library(knitr)   
fname<-'https://raw.githubusercontent.com/wardblonde/ODM-to-i2b2/master/odm/examples/CDISC_ODM_example_3.xml'
fname
x<-read_xml(fname)
xpath="//d1:ItemDef"
itemsNames <- x %>% xml_find_all(xpath, ns=xml_ns(x)) %>%  xml_attr('Name')
items <- x %>% xml_find_all(xpath, ns=xml_ns(x))

项目如下所示:

<ItemDef OID="IT.ABNORM" Name="Normal/Abnormal/Not Done" DataType="integer" Length="1" ...

示例文件可以在这里查看:https://raw.githubusercontent.com/wardblonde/ODM-to-i2b2/master/odm/examples/CDISC_ODM_example_3.xml

使用管道和 xml_attr,提取 NameDataType 属性并重新绑定它们的最佳方法是什么?

理想情况下,它将是一行超级高效的管道代码。我可以提取名称和类型并拥有“data.frame(name=names,type=types)”,但这似乎不是最好和最现代的。

结果应该是一个带有列名和数据类型的小标题。

【问题讨论】:

    标签: r xml-parsing xml2


    【解决方案1】:
    library(purrr)
    
    map(items, xml_attrs) %>% 
      map_df(as.list) %>% 
      select(Name, DataType)
    ## # A tibble: 94 × 2
    ##                                   Name DataType
    ##                                  <chr>    <chr>
    ## 1             Normal/Abnormal/Not Done  integer
    ## 2          Actions taken re study drug     text
    ## 3                 Actions taken, other     text
    ## 4    Stop Day - Enter Two Digits 01-31     text
    ## 5                    Derived Stop Date     text
    ## 6  Stop Month - Enter Two Digits 01-12     text
    ## 7    Stop Year - Enter Four Digit Year     text
    ## 8                              Outcome     text
    ## 9           Relationship to study drug     text
    ## 10                            Severity     text
    ## # ... with 84 more rows
    

    一个“基础”版本:

    lapply(items, xml_attrs) %>% 
      lapply(function(x) as.data.frame(as.list(x))[,c("Name", "DataType")]) %>% 
      do.call(rbind, .) %>%
      tbl_df()
    

    注意:^^ 的一个问题是,如果缺少 NameDataType,那么您就是 SOL。您可以通过以下方式缓解这种情况:

    lapply(items, xml_attrs) %>% 
      lapply(function(x) as.data.frame(as.list(x))[,c("Name", "DataType")]) %>% 
      data.table::rbindlist(fill=TRUE) %>% 
      tbl_df()
    

    或:

    lapply(items, xml_attrs) %>% 
      lapply(function(x) as.data.frame(as.list(x))[,c("Name", "DataType")]) %>% 
      bind_rows() %>% 
      tbl_df()
    

    如果你不喜欢purrr

    【讨论】:

    • 我确实喜欢咕噜声。谢谢。
    猜你喜欢
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 2016-04-27
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多