将不均匀的分层列表转换为数据帧

时间:2010-08-04 20:31:20

标签: xml list r dataframe plyr

我认为这还没有被问到,但是有没有办法将列表的信息与多个级别和不均匀的结构组合成一个“长”格式的数据框?

具体做法是:

library(XML)
library(plyr)
xml.inning <- "http://gd2.mlb.com/components/game/mlb/year_2009/month_05/day_02/gid_2009_05_02_chamlb_texmlb_1/inning/inning_5.xml"
xml.parse <- xmlInternalTreeParse(xml.inning)
xml.list <- xmlToList(xml.parse)
## $top$atbat
## $top$atbat$pitch
##             des              id            type               x               y 
##          "Ball"           "310"             "B"         "70.39"        "125.20" 

以下是结构:

> llply(xml.list, function(x) llply(x, function(x) table(names(x))))
$top
$top$atbat
.attrs  pitch 
     1      4 
$top$atbat
.attrs  pitch 
     1      4 
$top$atbat
.attrs  pitch 
     1      5 
$bottom
$bottom$action
     b    des  event      o  pitch player      s 
     1      1      1      1      1      1      1 
$bottom$atbat
.attrs  pitch 
     1      5 
$bottom$atbat
.attrs  pitch 
     1      5 
$bottom$atbat
.attrs  pitch runner 
     1      5      1 
$bottom$atbat
.attrs  pitch runner 
     1      7      1 
$.attrs
$.attrs$num
character(0)
$.attrs$away_team
character(0)
$.attrs$

我想要的是来自音高类别的指定向量的数据框,以及正确的(顶部 atbat 底部)。因此,由于列数不同,我需要忽略不适合data.frame的级别。像这样:

   first second third    des     x
1    top  atbat pitch   Ball 70.29
2    top  atbat pitch Strike 69.24
3 bottom  atbat pitch    Out 67.22

有一种优雅的方式吗?谢谢!

2 个答案:

答案 0 :(得分:5)

我不知道优雅,但这有效。那些更熟悉plyr的人可能会提供更通用的解决方案。

cleanFun <- function(x) {
   a <- x[["atbat"]]
   b <- do.call(rbind,a[names(a)=="pitch"])
   c <- as.data.frame(b)
}
ldply(xml.list[c("top","bottom")], cleanFun)[,1:5]
     .id             des  id type      x
1    top            Ball 310    B  70.39
2    top   Called Strike 311    S 118.45
3    top   Called Strike 312    S  86.70
4    top In play, out(s) 313    X  79.83
5 bottom            Ball 335    B  15.45
6 bottom   Called Strike 336    S  77.25
7 bottom Swinging Strike 337    S  99.57
8 bottom            Ball 338    B 106.44
9 bottom In play, out(s) 339    X 134.76

答案 1 :(得分:1)

.id的{​​{1}}功能很不错,但是当您执行另一个ldply()时,它们似乎会重叠。

这是使用ldply()的相当一般的功能:

rbind.fill()

第二个aho <- ldply(llply(xml.list[[1]], function(x) ldply(x, function(x) rbind.fill(data.frame(t(x)))))) > aho[1:5,1:4] .id des id type 1 pitch Ball 310 B 2 pitch Called Strike 311 S 3 pitch Called Strike 312 S 4 pitch In play, out(s) 313 X 5 .attrs Alexei Ramirez lines out to second baseman Ian Kinsler. <NA> <NA> 的{​​{1}}丢失了,因为我们已经有了.id。我们可以通过将第一个ldply()命名为另一个名称来解决此问题,但它似乎并不一致。

.id