2016-07-28 25 views
0

XML-Daten Parse XML-Datei mit R Kommen Sie in Datenrahmen

<HealthData locale="en_US"> 
<ExportDate value="2016-06-02 14:05:23 -0400"/> 
<Me HKCharacteristicTypeIdentifierDateOfBirth="" HKCharacteristicTypeIdentifierBiologicalSex="HKBiologicalSexNotSet" HKCharacteristicTypeIdentifierBloodType="HKBloodTypeNotSet" HKCharacteristicTypeIdentifierFitzpatrickSkinType="HKFitzpatrickSkinTypeNotSet"/> 
<Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:07:06 -0400" endDate="2014-09-24 15:07:11 -0400" value="7"/> 
<Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:12:13 -0400" endDate="2014-09-24 15:12:18 -0400" value="15"/> 
<Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:17:16 -0400" endDate="2014-09-24 15:17:21 -0400" value="20"/> 
</HealthData> 

R-Code

> library(XML) 
> doc="\\pathtoXMLfile" 
> list <-xpathApply(doc, "//HealthData/Record", xmlAttrs) 
> df <- do.call(rbind.data.frame, list) 
> str(df) 

Ich versuche, die XML-Daten Beispiel oben gezeigt zu nehmen und es in einen Datenrahmen laden in R mit dem Namen jedes Datensatzes, dh Type, sourceName, unit, endDate, value als Spaltenüberschrift und jedem Record Wert, also count, 2014-09-24 15:07:11 -0400, 7 als Werte für jede Zeile in der Datenrahmen.

Wenn df <- do.call(rbind.data.frame, list) dies zu schließen, aber es sieht auch so aus, es bindet alle Werte für die Spaltenüberschriften auch. Wenn Sie View(df) oder str(df) werden Sie sehen, was ich meine. Wie verwende ich die Record-Variablennamen als Spaltenüberschriften?

Danke, Ryan

Antwort

1

xpathSApply() Betrachten Sie die Attribute, abzurufen und dann mit t() die resultierende Liste in Datenrahmen umsetzen:

library(XML) 

xmlstr <- '<?xml version="1.0" encoding="UTF-8"?> 
      <HealthData locale="en_US"> 
       <ExportDate value="2016-06-02 14:05:23 -0400"/> 
       <Me HKCharacteristicTypeIdentifierDateOfBirth="" HKCharacteristicTypeIdentifierBiologicalSex="HKBiologicalSexNotSet" HKCharacteristicTypeIdentifierBloodType="HKBloodTypeNotSet" HKCharacteristicTypeIdentifierFitzpatrickSkinType="HKFitzpatrickSkinTypeNotSet"/> 
       <Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:07:06 -0400" endDate="2014-09-24 15:07:11 -0400" value="7"/> 
       <Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:12:13 -0400" endDate="2014-09-24 15:12:18 -0400" value="15"/> 
       <Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:17:16 -0400" endDate="2014-09-24 15:17:21 -0400" value="20"/> 
      </HealthData>' 

xml <- xmlParse(xmlstr) 

recordAttribs <- xpathSApply(doc=xml, path="//HealthData/Record", xmlAttrs) 
df <- data.frame(t(recordAttribs)) 
df 

#        type    sourceName unit 
# 1 HKQuantityTypeIdentifierStepCount Ryan Praskievicz iPhone count 
# 2 HKQuantityTypeIdentifierStepCount Ryan Praskievicz iPhone count 
# 3 HKQuantityTypeIdentifierStepCount Ryan Praskievicz iPhone count 
#    creationDate     startDate     endDate 
# 1 2014-10-02 08:30:17 -0400 2014-09-24 15:07:06 -0400 2014-09-24 15:07:11 -0400 
# 2 2014-10-02 08:30:17 -0400 2014-09-24 15:12:13 -0400 2014-09-24 15:12:18 -0400 
# 3 2014-10-02 08:30:17 -0400 2014-09-24 15:17:16 -0400 2014-09-24 15:17:21 -0400 
# value 
# 1  7 
# 2 15 
# 3 20 

Bei Attributen, die in einigen erscheinen und nicht andere sollten eine Übereinstimmung mit einer vorgegebenen Liste von Namen in Betracht ziehen und iterativ NAs ausfüllen. Im Folgenden sind zwei Versionen sapply() mit for Schleife und eine zweite Liste Argument:

recordnames <- c("type", "unit", "sourceName", "device", "sourceVersion", 
       "creationDate", "startDate", "endDate", "value") 

# FOR LOOP VERSION 
recordAttribs <- sapply(recordAttribs, function(i) { 
    for (r in recordnames){ 
    i[r] <- ifelse(is.null(i[r]), NA, i[r]) 
    } 
    i <- i[recordnames] # REORDER INNER VECTORS 
    return(i) 
}) 

# TWO LIST ARGUMENT SAPPLY 
recordAttribs <- sapply(recordAttribs, function(i,r) { 
    if (is.null(i[r])) i[r] <- NA 
     else i[r] <- i[r]   
    i <- i[recordnames] # REORDER INNER VECTORS 
    return(i) 
}, recordnames) 


df <- data.frame(t(recordAttribs)) 
+0

Dank es funktionierte perfekt für die Testdaten, die ich zur Verfügung gestellt. Als ich zurückging und versuchte, es auf den gesamten Datensatz anzuwenden, stellte ich fest, dass es Datensätze mit 9 Spalten gibt, die nicht 7 sind. Beispiel: ' es hat nicht funktioniert. Irgendwelche Ideen? –

+0

Wissen Sie wollen die gemeinsamen Attribute oder alle behalten? Weißt du im Voraus, welche Attribute du behalten musst? – Parfait

+0

Ja, ich möchte alle 9 Zeilen aus dem Vektor behalten und habe nur NAs für die Vektoren mit 7 Zeilen. –

1

Eine weitere Option xmlAttrsToDataFrame ist, die fehlenden Attribute behandeln soll. Sie können auch Tags mit einem bestimmten Attribut wie Gerät

bekommen
+0

das funktioniert auch gut. Vielen Dank! –