2016-07-25 18 views
1

Ich wäre sehr dankbar, wenn mir jemand zeigen könnte, wie man Daten von XML nach R extrahiert. Unten ist ein Beispiel von 1 Verbindung aus meiner XML-Datei, aber die echte Datei enthält mehrere hundert solcher Verbindungen. Ich weiß, dass es mehrere ähnliche Fragen gibt, aber bisher war ich nicht in der Lage, die vorherigen Antworten zu meinen Anforderungen zu entwickeln. Zum Beispiel kann ichDaten aus XML in Datenrahmen extrahieren

doc <- xmlParse("isotope information.xml") 
xmlToDataFrame(
    getNodeSet(doc, "//isotope"), 
    colClasses=c("character","numeric") 
) 

eine sehr lange Liste von „mz“ zu extrahieren und „Fülle“ Wert, aber diese sind nicht von Nutzen, wenn sie auf die entsprechende Verbindung verbunden sind und probieren etc. Auch diese Methode funktioniert scheint nicht zu funktionieren, wenn ich weiter oben am Baum versuche, ich denke, ein Teil des Grundes ist wegen der verschiedenen Arten von Informationen und/oder Leerzeichen in den Namen?

Jede Hilfe sehr geschätzt. Ich bin neu bei R und hatte noch nie von xPath gehört, bis ich mit dieser Datei angefangen habe!

<?xml version="1.0" encoding="utf-8"?> 
<compounds> 
    <compound identifier="24.24_355.2087m/z" retentionTime="24.2409"> 
    <statistics> 
     <anova>0.0013522641768629606</anova> 
     <maxFoldChange>18.444703223432118</maxFoldChange> 
     <mean lowest="Group A" highest="Group B" /> 
    </statistics> 
    <condition name="Group A"> 
     <sample name="ACU_S1_D1_MSonly" normalizedAbundance="0.16176030585271"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.131459235488</mz> 
      <abundance>0.115052197015018</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S4_D1_MSonly" normalizedAbundance="0.648153833258576"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.210174560547</mz> 
      <abundance>0.45734640955925</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S7_D1_MSonly" normalizedAbundance="0"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.206065493636</mz> 
      <abundance>0</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S9_D1_MSonly" normalizedAbundance="0"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.206065493636</mz> 
      <abundance>0</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S10_D1_MSonly" normalizedAbundance="1.40543741447065"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.222929359468</mz> 
      <abundance>0.998472798001696</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.785247802734</mz> 
      <abundance>0.00450361325390688</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S11_D1_MSonly" normalizedAbundance="0"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.206065493636</mz> 
      <abundance>0</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S14_D1_MSonly" normalizedAbundance="0"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.206065493636</mz> 
      <abundance>0</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S17_D1_MSonly" normalizedAbundance="0"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.206065493636</mz> 
      <abundance>0</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
    </condition> 
    <condition name="Group B"> 
     <sample name="ACU_S2_D1_MSonly" normalizedAbundance="8.08281443709004"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.217085869147</mz> 
      <abundance>6.34168970755279</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.720179758869</mz> 
      <abundance>1.01208656740541</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S3_D1_MSonly" normalizedAbundance="1.74468788905785"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.236865028724</mz> 
      <abundance>1.25719554540164</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S5_D1_MSonly" normalizedAbundance="1.20519908118674"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.221413778655</mz> 
      <abundance>0.693123193025995</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S6_D1_MSonly" normalizedAbundance="11.8264838326202"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.208446325351</mz> 
      <abundance>5.67846393951768</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.712529790798</mz> 
      <abundance>0.718700468540192</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S12_D1_MSonly" normalizedAbundance="6.62039336582067"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.195225774627</mz> 
      <abundance>4.80023810084345</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S13_D1_MSonly" normalizedAbundance="9.10340543014277"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.231293658837</mz> 
      <abundance>8.75476514173928</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.73683673041</mz> 
      <abundance>1.118534732035</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S15_D1_MSonly" normalizedAbundance="0"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.206065493636</mz> 
      <abundance>0</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
     <sample name="ACU_S16_D1_MSonly" normalizedAbundance="2.27851790546988"> 
     <adduct charge="2"> 
      <isotope> 
      <mz>355.242192813064</mz> 
      <abundance>1.25391817825056</abundance> 
      </isotope> 
      <isotope> 
      <mz>355.704849713088</mz> 
      <abundance>0</abundance> 
      </isotope> 
     </adduct> 
     </sample> 
    </condition> 
    </compound> 

UPDATE ZU ORIGINAL POST Hallo wieder, auf die Antworten vielen Dank für Ihre erste Hilfe sowohl XML und xml2 mit ich versucht habe zu erarbeiten den Datenrahmen zu bekommen, die ich brauche, aber ich bin immer noch kämpfen, also bin ich weitere Informationen Hinzufügen ...

ich die Struktur des xML-Dokuments als Wesen festgestellt habe:

# load necessary package(s) 
library(XML) 

# parse the xml file in to an R object call xmlfile 
xmlfile = xmlTreeParse("QI isotope information.xml") 


# check that the xmlfile object is recognised as an xml class 
class(xmlfile) # the output should be: "XMLInternalDocument" "XMLAbstractDocument" 

# find the root of the xml file 
xmltop = xmlRoot(xmlfile) 
class(xmltop) # "XMLInternalElementNode" "XMLInternalNode"  "XMLAbstractNode" 
xmlName(xmltop) # "compounds" 
xmlSize(xmltop) # 4278 

# the root of the xmlfile is "compounds" and it has 4278 children 
# to view the content of the first child use: 
xmltop[[1]] 

# this contains all of the information from a unique compound identifier: 
# <compound identifier="106.16_603.4571m/z" retentionTime="106.16268333333333"> 
# <statistics> 
# <anova>1.1102230246251565E-16</anova> 
# <maxFoldChange>321.93091917042375</maxFoldChange> 
# <mean lowest="D9" highest="D1"/> 
# </statistics> 
# <condition name="D1"> 
# <sample name="ACU_S1_D1_MSonly" normalizedAbundance="2016.23926856296"> 
#  <adduct charge="1"> 
#  <isotope> 
#   <mz>603.509454467435</mz> 
#   <abundance>1017.28655636311</abundance> 
#  </isotope> 
#  <isotope> 
#   <mz>604.51484984744</mz> 
#   <abundance>346.272257983685</abundance> 
#  </isotope> 
#  <isotope> 
#   <mz>605.519216627667</mz> 
#   <abundance>64.8701884746552</abundance> 
#  </isotope> 
#  </adduct> 
# </sample> 
# N.B. this list is repeated for each sample name, in this case n=64 samples 

xmlSize(xmltop[[1]]) # gives the number of nodes under the root, in this case n=5 
xmlSApply(xmltop[[1]], xmlName) # gives the names of these 5 nodes 
# statistics condition condition condition condition 
# "statistics" "condition" "condition" "condition" "condition" 
xmlSApply(xmltop[[1]], as.list) 

xmltop[[1]][[1]] # takes you to the statistics output: 
# <statistics> 
# <anova>1.1102230246251565E-16</anova> 
# <maxFoldChange>321.93091917042375</maxFoldChange> 
# <mean lowest="D9" highest="D1"/> 
# </statistics> 

xmltop[[1]][[2]] # takes you to the "condition" level, i.e. condition name="D1" 

xmltop[[1]][[2]][[1]] # takes you to the "sample" level, i.e. sample name="ACU_S1_D1_MSonly" 

xmltop[[1]][[2]][[2]] # takes you to the "sample" level number 2, i.e. sample name="ACU_S2_D1_MSonly" 

xmltop[[1]][[2]][[1]][[1]] # takes you to the "charge" level, i.e. adduct charge="1" 

xmltop[[1]][[2]][[1]][[1]][[1]] # takes you to the "isotope" level, which includes m/z and abundance 

# incrementing the last index number takes you to each isotope for that compound 
# for example: 

xmltop[[1]][[2]][[1]][[1]][[1]][[1]] # <mz>603.509454467435</mz> 
xmltop[[1]][[2]][[1]][[1]][[1]][[2]] # <abundance>1017.28655636311</abundance> 
xmltop[[1]][[2]][[1]][[1]][[2]][[1]] # <mz>604.51484984744</mz> 
xmltop[[1]][[2]][[1]][[1]][[2]][[2]] # <abundance>346.272257983685</abundance> 
xmltop[[1]][[2]][[1]][[1]][[3]][[1]] # <mz>605.519216627667</mz> 
xmltop[[1]][[2]][[1]][[1]][[3]][[2]] # <abundance>64.8701884746552</abundance> 
xmltop[[1]][[2]][[1]][[1]][[4]][[1]] # NULL 
xmltop[[1]][[2]][[1]][[1]][[4]][[2]] # NULL 

ich bin in dem Statistikteil nicht interessiert, aber ich mag einen Datenrahmen schaffen, wo die str Ausgang wäre etwas li ke:

# > str(mydata) # returns a summary of the type/ format of each column 
# 'data.frame': n obs. of n variables: 
# $ compound : Factor w/ n levels 
# $ retention_time : 
# $ condition : Factor w/ 4 levels "D1","D3","D6","D9": 
# $ sample_name : Factor w/ 16 levels "ACU_S1_D1","ACU_S2_D1...: 
# $ isotope_mz : num 
# $ isotope_abundance : num 

mein letztes Ziel ist es, Extrakt zu sein die Fülle jeden isotope_mz für jeden der 64 Proben. In der Tat ist es nicht wichtig, die Bedingung zu kennen, da dies aus sample_name ermittelt werden kann.

N.B. Die XML-Datei, mit der ich arbeite, ist 150 mb und hat> 4000 Verbindungen x 64 Proben und jede Verbindung hat zwischen 1 und 4 Isotope, die ich brauche die mz und Fülle von. Zusätzlich zu dem hier angesprochenen "R" -Ansatz habe ich auch zahlreiche XML-Konverter gesucht und ausprobiert, aber keiner von ihnen ist in der Lage, die Struktur dieser XML-Datei zu entschlüsseln.

+2

Können Sie ein Beispiel für die Art von Ergebnis, die Sie benötigen? Sie können auch erläutern, was Sie mit "scheint nicht zu arbeiten" (was tut es nicht?) Und "weiter oben am Baum", Beispiele geben. – LarsH

+0

Ich würde 'XML :: xmlToList()' verwenden und dann die Liste analysieren, wie Sie es für richtig halten. Außerdem fehlt am unteren Ende der Beispiel-XML-Datei '<\compounds>' - sie wird ohne sie nicht geladen. – dayne

+0

Vielen Dank für die Fragen. Ich habe den ursprünglichen Beitrag hinzugefügt, indem ich einige meiner bisherigen Fortschritte und eine bessere Beschreibung meiner Ziele hinzugefügt habe. –

Antwort

1

So etwas sollte funktionieren:

library(XML) 
library(data.table) 

mylist <- xmlToList("isotope information.xml") 
mylist <- c(mylist, mylist, mylist) 

xtract <- function(x) { 
    data.table(compound_id = mylist[x]$compound$.attrs["identifier"], 
      sample_id = mylist[x]$compound$condition$sample$.attrs["name"], 
      mz = mylist[x]$compound$condition$sample$adduct$isotope[1], 
      abundance = mylist[x]$compound$condition$sample$adduct$isotope[2]) 
} 

rbindlist(lapply(seq_along(mylist), xtract)) 
#   compound_id  sample_id    mz   abundance 
# 1: 24.24_355.2087m/z ACU_S1_D1_MSonly 355.131459235488 0.115052197015018 
# 2: 24.24_355.2087m/z ACU_S1_D1_MSonly 355.131459235488 0.115052197015018 
# 3: 24.24_355.2087m/z ACU_S1_D1_MSonly 355.131459235488 0.115052197015018 
0

ich persönlich lieber xml2 so hier ist eine Antwort, die verwendet wird. Ich bin sicher, es könnte verbessert werden, aber es wird Ihnen eine Liste mit der Länge geben, die der Anzahl der Verbindungen entspricht, und jedes Element der Liste wird der zusammengesetzte Bezeichner und ein Datenrahmen von mz und Überflussspalten sein.

library(xml2) 
x = read_xml(conn) # given in question 
#html_structure(x) # If you want to look at the structure 

output = list() 
# Initialize list and collect all compunds first 
a = xml_attrs(xml_find_all(x, "//compound")) 
# Iterate over compounds - I'm sure this could be done in an lapply... 
for(i in 1:length(a)){ 
    y = xml_child(x, i) 
    # Get the child to simplify the xpath to collect all in this one node 
    # Add a new element to the output list 
    output[[i]] = list(
    a[[1]][1], # Extract identifier (assumed you didn't want the retention time) and then a df of mz and abundance 
    data.frame(mz = xml_double(xml_find_all(y, "//isotope/mz")), abundance = xml_double(xml_find_all(x, "//isotope/abundance"))) 
       ) 
} 

OUTPUT:

> output 
[[1]] 
[[1]][[1]] 
     identifier 
"24.24_355.2087m/z" 

[[1]][[2]] 
     mz abundance 
1 355.1315 0.115052197 
2 355.7048 0.000000000 
... 
31 355.2422 1.253918178 
32 355.7048 0.000000000 
Verwandte Themen