我有一些形状像这样的数据:
<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>
我想要一个如下所示的数据框:
first last sex height 1 Mary Jane F NA 2 Susan Smith F 168 3 Joseph Black M NA 4 Jessica Jones F NA
我到目前为止:
library(XML) xpeople <- xmlRoot(xmlParse(xml)) lst <- xmlApply(xpeople,xmlAttrs) names(lst) <- 1:length(lst)
但我不能为我的生活弄清楚如何将列表放入数据框.我可以将列表设置为“正方形”(即填充间隙),然后将其放入数据框中:
lst <- xmlApply(xpeople,function(node) { attrs = xmlAttrs(node) if (!("height" %in% names(attrs))) { attrs[["height"]] <- NA } attrs }) df = as.data.frame(lst)
但是我有以下问题:
>数据框被转置
>第一个和最后一个是因素,而不是chr
> height是一个因子,而不是数字
>为约瑟夫·布莱克交换了名字和姓氏(这不是一个大问题,因为我的数据通常是一致的,但仍然令人讨厌)
如何以正确的形式获取数据框?
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
你需要as.list(xmlAttrs(…))而不仅仅是xmlAttrs(…),因为rbindlist(…)希望每个参数都是一个列表,而不是一个向量.