2017-03-09 21 views
0

我對XML解析相當陌生,並試圖解析一些籃球NBA sportVU數據。我有一個看起來如此(在總結格式)的XML文件:對於每個節點,計算在R中使用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> 

我創建了具有團隊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解決方案)。

謝謝!

回答

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>') 
+0

Thanks Rich。它看起來像使用xpathApply是一種使用XML包解析XML文檔的強大方法。我看起來他們用了很多。 – Canovice

+0

@Canovice - 它有它的起伏:) –

0

像這樣的事情似乎工作,雖然不是在我看來最大的解決方案。它使用XML :: xmlChildren函數:

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

3 2 4 1 
相關問題