2015-09-30 19 views
5

mam pewne dane ukształtowane tak:obciążenia xml „wiersze” do tabeli danych R

<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> 

Chciałbym ramki danych, który wygląda tak:

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

stałam to daleko:

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

Ale nie mogę do końca życia wymyślić, jak uzyskać listę w ramce danych. Mogę dostać listę jako „kwadrat” (czyli wypełnić luki), a następnie umieścić je w ramce danych:

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

Ale mam następujące problemy:

  1. Rama dane są transponowane
  2. pierwszy i ostatni są czynnikami, nie CHR
  3. wysokość jest czynnikiem, nie numeryczny
  4. z imion i nazwisk, ale zamieniłem się za Joseph Black (nie jest to duży problem, ponieważ moje dane są zwykle spójne, lecz denerwujące jednak)

Jak mogę uzyskać ramkę danych we właściwej formie?

+0

'plyr :: rbind.fill (lapply (xmlToList (txt), funkcja (x) as.data.frame (t (x), stringiAsFactors = FALSE)))) jest prawdopodobnie trochę łatwiejsze, chociaż nie Rozwiązanie xml. Następnie można przekonwertować wysokość czynnika na wartość numeryczną za pomocą polecenia 'as.numeric (' – user20650

+0

Właściwie http://stackoverflow.com/questions/2067098/how-to-transform-xml-data-into-a-data-frame?answertab=votes # tab-top może być przydatne – user20650

+1

Istnieje funkcja uzyskiwania atrybutów w data.frame 'XML ::: xmlAttrsToDataFrame (xml [" // person "])' –

Odpowiedz

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 

Trzeba as.list(xmlAttrs(...)) zamiast tylko xmlAttrs(...) ponieważ rbindlist(...) chce każdy argument być lista, a nie wektorowych.

Powiązane problemy