Как проанализировать атрибуты XML с родительским атрибутом во фрейме данных в R - PullRequest
0 голосов
/ 11 февраля 2019

Я пытаюсь проанализировать узлы и атрибуты файла XML.Внутри файла есть набор узлов с атрибутами.Вложенная структура XML похожа на фрейм данных, и я хочу разобрать это в фрейм данных.

Вот пример файла:

<?xml version="1.0" encoding="UTF-8"?>
<TrackMate version="3.8.0">
  <Model spatialunits="µm" timeunits="sec">
    <AllTracks>
      <Track name="Track_2" TRACK_ID="2" NUMBER_SPOTS="140" NUMBER_GAPS="0" >
        <Edge SPOT_SOURCE_ID="960769" SPOT_TARGET_ID="960778" LINK_COST="0.08756957830926632" />
        <Edge SPOT_SOURCE_ID="958304" SPOT_TARGET_ID="958308" LINK_COST="1.4003359672950089" />
        <Edge SPOT_SOURCE_ID="958316" SPOT_TARGET_ID="958322" LINK_COST="1.6985623204008202" />
      </Track>
      <Track name="Track_145" TRACK_ID="145" NUMBER_SPOTS="141" NUMBER_GAPS="0" >
        <Edge SPOT_SOURCE_ID="961623" SPOT_TARGET_ID="961628" LINK_COST="2.2678642015413755" />
        <Edge SPOT_SOURCE_ID="962122" SPOT_TARGET_ID="962127" LINK_COST="38.20777704254654" />
        <Edge SPOT_SOURCE_ID="961869" SPOT_TARGET_ID="961873" LINK_COST="0.2895609647324684" />
      </Track>
    </AllTracks>
  </Model>
</TrackMate>

Я хотел бы создать фрейм данныхсо всеми атрибутами ребер и родительским атрибутом TRACK_ID.Я могу легко создать фрейм данных со всеми атрибутами ребер с помощью этого:

edges = data.frame(t(data.frame(xml_attrs(xml_find_all(xmlDoc, xpath = paste0('/TrackMate/Model/AllTracks//Edge'))))))
row.names(edges) = NULL

Но тогда соответствующий идентификатор трека теряется.Я могу решить это с помощью цикла for, но это часто не «путь R».Мне было интересно, если есть более простое решение?(например, с запросом xpath).

Таким образом, конечным желаемым результатом будет этот фрейм данных: output data frame

Редактировать: это подходит ближе, но затем отслеживаются узлы иКраевые узлы смешаны в списке.

xml_find_all(xmlDoc, xpath = paste0('/TrackMate/Model/AllTracks//Edge | /TrackMate/Model/AllTracks/Track'))

1 Ответ

0 голосов
/ 11 февраля 2019

Хитрость заключается в том, чтобы получить список всех ребер-узлов и работать с xpath оттуда ... Вы можете выбрать узел Trach из каждого узла Edge, используя ancestor из xpath.

используемые библиотеки

#load libraries
library( xml2 )
library( magrittr )

пример данных

doc <- read_xml('<?xml version="1.0" encoding="UTF-8"?>
  <TrackMate version="3.8.0">
    <Model spatialunits="µm" timeunits="sec">
      <AllTracks>
      <Track name="Track_2" TRACK_ID="2" NUMBER_SPOTS="140" NUMBER_GAPS="0" >
        <Edge SPOT_SOURCE_ID="960769" SPOT_TARGET_ID="960778" LINK_COST="0.08756957830926632" />
          <Edge SPOT_SOURCE_ID="958304" SPOT_TARGET_ID="958308" LINK_COST="1.4003359672950089" />
            <Edge SPOT_SOURCE_ID="958316" SPOT_TARGET_ID="958322" LINK_COST="1.6985623204008202" />
              </Track>
              <Track name="Track_145" TRACK_ID="145" NUMBER_SPOTS="141" NUMBER_GAPS="0" >
                <Edge SPOT_SOURCE_ID="961623" SPOT_TARGET_ID="961628" LINK_COST="2.2678642015413755" />
                  <Edge SPOT_SOURCE_ID="962122" SPOT_TARGET_ID="962127" LINK_COST="38.20777704254654" />
                    <Edge SPOT_SOURCE_ID="961869" SPOT_TARGET_ID="961873" LINK_COST="0.2895609647324684" />
                      </Track>
                      </AllTracks>
                      </Model>
                      </TrackMate>')

код

#find all edge nodes
edge.nodes <- xml_find_all( doc, ".//Edge")
#build the data.frame
data.frame( TRACK_ID = xml_find_first( edge.nodes, ".//ancestor::Track") %>% xml_attr("TRACK_ID"),
            SPOT_SOURCE_ID = edge.nodes %>% xml_attr("SPOT_SOURCE_ID"),
            SPOT_TARGET_ID = edge.nodes %>% xml_attr("SPOT_TARGET_ID"),
            LINK_COST = edge.nodes %>% xml_attr("LINK_COST") )

выход

#   TRACK_ID SPOT_SOURCE_ID SPOT_TARGET_ID           LINK_COST
# 1        2         960769         960778 0.08756957830926632
# 2        2         958304         958308  1.4003359672950089
# 3        2         958316         958322  1.6985623204008202
# 4      145         961623         961628  2.2678642015413755
# 5      145         962122         962127   38.20777704254654
# 6      145         961869         961873  0.2895609647324684
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...