【问题标题】:Faster way to put large nested xml into R dataframe将大型嵌套 xml 放入 R 数据帧的更快方法
【发布时间】:2023-02-24 08:04:15
【问题描述】:

我有一个 XML 文件,它的嵌套与我见过的其他示例不同。这是它采用的格式。我对 np 节点中的数据感兴趣,但我还想要每一行中的组和 ID 信息。

我在下面有一个可行的解决方案,但实际文件非常大,有数千个节点。该解决方案需要数小时才能在大文件上运行,尽管它适用于下面的示例代码。

我的问题是 - 有没有更快的方法来获取我想要的数据框?

<File>
  <Time>
    <date>20220301</date>
    <Name>1</Name>
<folder>
      <group>800</group>
      <ID>ESK</ID>
      <Type>S</Type>
      <Customer>1</Customer>
      <currency>USD</currency>
      <Port>
        <ec>X</ec>
        <np>
          <A>FIRST</A>
          <B>ES</B>
          <C>GOR</C>
          <D>2021</D>
          <E>-1000</E>
        </np>
        <np>
          <A>TEST</A>
          <B>ES</B>
          <C>RUN</C>
          <D>202303</D>
          <E>202303</E>
          <F>C</F>
          <G>3200</G>
          <H>32</H>
        </np>
      </Port>
</folder>
<folder>
      <group>900</group>
      <ID>ABC</ID>
      <Type>D</Type>
      <Customer>1</Customer>
      <currency>USD</currency>
      <Port>
        <ec>X</ec>
        <np>
          <A>CAT</A>
          <B>ES</B>
          <C>GO</C>
          <D>202303</D>
          <E>-500</E>
        </np>
       </Port>
</folder>
</Time>
</File>

这是我目前的工作解决方案。这适用于小的 xml 文件,但对于具有该 xml 格式的大文件,它太慢并且需要数小时才能运行。


URL <- 'H:/testSO.xml'
doc <- read_xml(URL)

df <-
  xml_find_all(doc, ".//np") %>%
  map_df( function(x) {
    set_names( c(  
      xml_find_all( x, "./ancestor::folder/group") %>% xml_text(),
      xml_find_all( x, "./ancestor::folder/ID") %>% xml_text(),
      xml_find_all( x, ".//A") %>% xml_text(),
      xml_find_all( x, ".//B") %>% xml_text(),
      xml_find_all( x, ".//C") %>% xml_text(),
      xml_find_all( x, ".//D") %>% xml_text(),
      xml_find_all( x, ".//E") %>% xml_text()), 
      #set the column names
      c( "group","id", "A", "B", "C","D","E") ) %>% 
      as.list() %>% #make list
      flatten_df() 
  }) %>%
  type_convert() 

head(df)

谢谢!

【问题讨论】:

    标签: r xml dataframe performance


    【解决方案1】:

    您可以利用 xml2 库的矢量化并避免 map_df 循环,这应该会显着提高速度。

    该例程查找所有 np 节点并提取一系列向量中的请求信息,然后创建包含结果的数据框。

    library(xml2)
    library(dplyr)
    npnodes <- xml_find_all(doc, ".//np") 
       
    group <- npnodes %>% xml_find_first( "./ancestor::folder/group") %>% xml_text()
    id <- npnodes %>% xml_find_first("./ancestor::folder/ID") %>% xml_text()
    A <- npnodes %>% xml_find_first(".//A") %>% xml_text()
    B <- npnodes %>% xml_find_first(".//B") %>% xml_text()
    C <- npnodes %>% xml_find_first(".//C") %>% xml_text()
    D <- npnodes %>% xml_find_first(".//D") %>% xml_text()
    E <- npnodes %>% xml_find_first(".//E") %>% xml_text() 
    
    answer <- data.frame(group,id, A, B, C, D, E)
    answer
    
      group  id     A  B   C      D      E
    1   800 ESK FIRST ES GOR   2021  -1000
    2   800 ESK  TEST ES RUN 202303 202303
    3   900 ABC   CAT ES  GO 202303   -500
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-09
      • 2021-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多