对于每个节点,使用R中的XML包计算子节点数

时间:2017-03-09 01:09:06

标签: r xml

我对XML解析相当新,并且正在尝试解析一些篮球NBA sportVU数据。我有一个看起来像这样的XML文件(以汇总格式):

<quarter number="1">
  <possession team-id="30" points="3"/>
  <possession team-id="23" points="1"/>
  <possession team-id="30" points="2"/>
</quarter>
<quarter number="2">
  <possession team-id="23" points="3"/>
  <possession team-id="30" points="2"/>
</quarter>
<quarter number="3">
  <possession team-id="30" points="1"/>
  <possession team-id="30" points="1"/>
  <possession team-id="30" points="1"/>
  <possession team-id="23" points="2"/>
</quarter>
<quarter number="4">
  <possession team-id="23" points="2"/>
</quarter>

我创建了一个数据框,其team-id为1列,而点数为另一列,如下所示:

library(XML)
data = xmlParse("myXMLfile.XML")

my_df <- data.frame(
  team.id = sapply(data["//quarter/possession/@team-id"], as, "integer"),
  points = sapply(data["//quarter/possession/@points"], as, "integer")
)

my_df
   team.id  points 
1       30       3
2       23       1
3       30       2
4       23       3
5       30       2 
6       30       1
7       30       1
8       30       1
9       23       2
10      23       2

我想在此添加第3列,标记为季度,将更新数据框,如下所示:

my_new_df
   team.id  points  quarter
1       30       3        1
2       23       1        1      
3       30       2        1
4       23       3        2
5       30       2        2
6       30       1        3
7       30       1        3
8       30       1        3
9       23       2        3
10      23       2        4

我认为能够做到这一点的最简单方法是获取向量中唯一的四分之一数字,然后按每个四分之一节点下面的子节点数重复该向量。有谁知道我怎么能做到这一点?我对一般不同的方法持开放态度,不涉及XML包(例如,如果有xml2解决方案)。

谢谢!

2 个答案:

答案 0 :(得分:1)

从原始文档data(我称之为doc)开始,看起来这样可行。首先是一个小帮助函数,以将所需信息转换为所需的形式。

helper <- function(x) {
    as.data.frame.list(c(xmlAttrs(x), quarter = unname(xmlAttrs(xmlParent(x)))))
}

现在,我们可以使用lapply()在节点之间运行辅助函数,并将结果列表放入rbind()的数据框中。

do.call(rbind, lapply(doc["//quarter/*"], helper))
#    team.id points quarter
# 1       30      3       1
# 2       23      1       1
# 3       30      2       1
# 4       23      3       2
# 5       30      2       2
# 6       30      1       3
# 7       30      1       3
# 8       30      1       3
# 9       23      2       3
# 10      23      2       4

数据:

library(XML)
doc <- htmlParse('<quarter number="1">
  <possession team-id="30" points="3"/>
  <possession team-id="23" points="1"/>
  <possession team-id="30" points="2"/>
</quarter>
<quarter number="2">
  <possession team-id="23" points="3"/>
  <possession team-id="30" points="2"/>
</quarter>
<quarter number="3">
  <possession team-id="30" points="1"/>
  <possession team-id="30" points="1"/>
  <possession team-id="30" points="1"/>
  <possession team-id="23" points="2"/>
</quarter>
<quarter number="4">
  <possession team-id="23" points="2"/>
</quarter>')

答案 1 :(得分:0)

这样的事情似乎有效,尽管不是我认为最好的解决方案。它使用XML :: xmlChildren函数:

zed = possessions["//quarter"]
unlist(lapply(zed, FUN = function(x) length(XML::xmlChildren(x))))

3 2 4 1