2015-09-30 14 views
5

Ich habe einige wie diese geformt Daten:laden xml „Zeilen“ in R Datentabelle

<people> 
    <person first="Mary" last="Jane" sex="F" /> 
    <person first="Susan" last="Smith" sex="F" height="168" /> 
    <person last="Black" first="Joseph" sex="M" /> 
    <person first="Jessica" last="Jones" sex="F" /> 
</people> 

Ich würde einen Datenrahmen wie die wie folgt aussieht:

first last sex height 
1 Mary Jane F  NA 
2 Susan Smith F 168 
3 Joseph Black M  NA 
4 Jessica Jones F  NA 

ich das bekommen habe weit:

library(XML) 
xpeople <- xmlRoot(xmlParse(xml)) 
lst <- xmlApply(xpeople, xmlAttrs) 
names(lst) <- 1:length(lst) 

Aber ich kann nicht für das Leben von mir herauszufinden, wie die Liste in den Datenrahmen zu erhalten. Ich kann die Liste bekommen „square“ (dh füllen die Lücken) zu sein, und es dann in einen Datenrahmen setzen:

lst <- xmlApply(xpeople, function(node) { 
    attrs = xmlAttrs(node) 
    if (!("height" %in% names(attrs))) { 
    attrs[["height"]] <- NA 
    } 
    attrs 
}) 
df = as.data.frame(lst) 

Aber ich habe folgende Probleme auf:

  1. Der Datenrahmen ist transponiert
  2. ersten und letzten Faktoren sind, chr nicht
  3. Höhe ein Faktor ist, nicht numerisch
  4. den Vor- und Nachnamen bekam tauschte um für Joseph Black (kein großes Problem, da meine Daten normalerweise konsistent ist, aber nervig aber)

Wie kann ich den Datenrahmen in der richtigen Form bekommen?

+0

'plyr :: rbind.fill (lapply (xmlToList (txt), Funktion (x) as.data.frame (t (x), StringsAsFactors = FALSE))) ist vielleicht ein kleines bisschen einfacher, obwohl nicht ein XML-Lösung. Sie können die Faktorhöhe dann mit 'as.numeric (' – user20650

+0

Actually http://stackoverflow.com/questions/2067098/how-to-transform-xml-data-into-a-data-frame?answertab=votes # tab-top könnte nützlich sein – user20650

+1

Es gibt eine Funktion, um Attribute in ein data.frame 'XML ::: xmlAttrsToDataFrame (xml [" // person "])' zu bekommen –

Antwort

3
txt <- '<people> 
      <person first="Mary" last="Jane" sex="F" /> 
      <person first="Susan" last="Smith" sex="F" height="168" /> 
      <person last="Black" first="Joseph" sex="M" /> 
      <person first="Jessica" last="Jones" sex="F" /> 
     </people>' 
library(XML)   # for xmlTreeParse 
library(data.table) # for rbindlist(...) 
xml <- xmlTreeParse(txt, asText=TRUE, useInternalNodes = TRUE) 
rbindlist(lapply(xml["//person"],function(x)as.list(xmlAttrs(x))),fill=TRUE) 
#  first last sex height 
# 1: Mary Jane F  NA 
# 2: Susan Smith F 168 
# 3: Joseph Black M  NA 
# 4: Jessica Jones F  NA 

Sie benötigen as.list(xmlAttrs(...)) statt nur xmlAttrs(...) weil rbindlist(...) jedes Argument will eine Liste, kein Vektor sein.

Verwandte Themen