Как преобразовать данные XML в data.frame? - PullRequest
33 голосов
/ 14 января 2010

Я пытаюсь изучить пакет R's XML. Я пытаюсь создать файл data.frame из примера файла xml книг books.xml. Вот что я получаю:

library(XML)
books <- "http://www.w3schools.com/XQuery/books.xml"
doc <- xmlTreeParse(books, useInternalNodes = TRUE)
doc
xpathApply(doc, "//book", function(x) do.call(paste, as.list(xmlValue(x))))
xpathSApply(doc, "//book", function(x) strsplit(xmlValue(x), " "))
xpathSApply(doc, "//book/child::*", xmlValue)

Каждый из этих xpathSApply даже близко не подходит к моему намерению. Как двигаться к хорошо сформированному data.frame?

1 Ответ

38 голосов
/ 14 января 2010

Обычно, я бы предложил попробовать функцию xmlToDataFrame(), но я считаю, что это на самом деле будет довольно сложно, потому что с самого начала она не очень хорошо структурирована.

Я бы порекомендовал работать с этой функцией:

xmlToList(books)

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

Как только вы решили, что делать с проблемой нескольких авторов, довольно просто превратить ваш список книг в фрейм данных с функцией ldply() в plyr (или просто использовать lapply и преобразовать возвращаемое значение в data.frame с помощью do.call ("rbind" ...).

Вот полный пример (исключая автора):

library(XML)
books <-  "w3schools.com/xsl/books.xml"
library(plyr)
ldply(xmlToList(books), function(x) { data.frame(x[!names(x)=="author"]) } )

   .id        title.text title..attrs year price   .attrs
 1 book  Everyday Italian           en 2005 30.00  COOKING
 2 book      Harry Potter           en 2005 29.99 CHILDREN
 3 book XQuery Kick Start           en 2003 49.99      WEB
 4 book      Learning XML           en 2003 39.95      WEB

Вот как это выглядит с включенным автором. Вам нужно использовать ldply в этом случае, так как список "зубчатый" ... lapply не может справиться с этим должным образом. [В противном случае вы можете использовать lapply с rbind.fill (также любезно предоставлено Хэдли), но зачем беспокоиться, если plyr автоматически сделает это за вас?]:

ldply(xmlToList(books), data.frame)

   .id        title.text title..attrs              author year price   .attrs
1 book  Everyday Italian           en Giada De Laurentiis 2005 30.00  COOKING
2 book      Harry Potter           en        J K. Rowling 2005 29.99 CHILDREN
3 book XQuery Kick Start           en      James McGovern 2003 49.99      WEB
4 book      Learning XML           en         Erik T. Ray 2003 39.95      WEB
     author.1   author.2   author.3               author.4
1        <NA>       <NA>       <NA>                   <NA>
2        <NA>       <NA>       <NA>                   <NA>
3 Per Bothner Kurt Cagle James Linn Vaidyanathan Nagarajan
4        <NA>       <NA>       <NA>                   <NA>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...