2014-10-08 90 views
3

我想使用XML包和xmlToList或xmlToDataFrame函數。 我的輸入數據是互聯網(第2線)上,我只需要與XML的某一部分工作(見第三個節點集命令)當節點只有屬性時,如何將XML轉換爲data.frame?

url<- 'http://ClinicalTrials.gov/show/NCT00191100?resultsxml=true' 
xml = xmlTreeParse(url,useInternalNode=TRUE) 
ns <- getNodeSet(xml, '/clinical_study/clinical_results/reported_events/serious_events/category_list') 

它是類和內部類的列表中「事件」。與事件的計數(和計數是特定的臨牀試驗武器(例如,藥物與安慰劑組)

我只需要在活動,所以最好的上市是在這裏使用xmlToList

xl<-xmlToList(url) 
set2<-xl$clinical_results$reported_events$serious_events$category_list 
set2[[3]] 

> set2[[3]] 
$title 
[1] "Cardiac disorders" 

$event_list 
$event_list$event 
$event_list$event$sub_title 
[1] "Cardio-respiratory arrest" 

$event_list$event$counts 
     group_id   events subjects_affected subjects_at_risk 
      "E1"    "1"    "1"    "260" 

$event_list$event$counts 
     group_id   events subjects_affected subjects_at_risk 
      "E2"    "0"    "0"    "255" 
卡里奧,呼吸驟停

我無法使用xmlToDataFrame由於這個錯誤。(該nodeset2在XMLATTRIBUTES的所有數據,我認爲xmlTODataFrame可能不喜歡這個)

hopefulyDF <- getNodeSet(xml, '/clinical_study/clinical_results/reported_events/serious_events/category_list/category/event_list/event/counts') 
xmlToDataFrame(node = hopefulyDF) 
Error in matrix(vals, length(nfields), byrow = TRUE) : 
    'data' must be of a vector type, was 'NULL' 

如何最好地提取計數數據?我想不公開但是我不夠高級,可能是我ld喜歡避免循環和手動xmlGetAttr。但在最糟糕的情況下,任何解決方案都可以接受。我發現XML封裝非常密集與第2版XML數據列表和節點集的... :-(

理想的輸出應該是這樣的:(所有事件(而不只是第3行)

event group_ID numerator denumerator 
Cardio-respiratory arrest E1 1 260 
Cardio-respiratory arrest E2 0 250 

(甚至有一個類別列(心臟疾病) - 這將是超理想)。

PS 我用這個問題How to transform XML data into a data.frame? 和問題R list to data frame,但沒有運氣:-(

回答

4

通過遍歷每個event並通過相對XPath提取counts屬性,可以簡化XML提取。通過使用rbindlistdata.table包,可以處理缺少的屬性沒有條件代碼添加:

library(XML) 
library(data.table) 

url <- 'http://ClinicalTrials.gov/show/NCT00191100?resultsxml=true' 
xml <- xmlTreeParse(url,useInternalNode=TRUE) 

ns <- getNodeSet(xml, '//event') 

rbindlist(lapply(ns, function(x) { 
    event <- xmlValue(x) 
    data.frame(event, t(xpathSApply(x, ".//counts", xmlAttrs))) 
}), fill=TRUE) 

##        event group_id subjects_affected events subjects_at_risk 
## 1: Total, serious adverse events  E1    44  NA    NA 
## 2: Total, serious adverse events  E2    17  NA    NA 
## 3:      Anaemia  E1     6  6    260 
## 4:      Anaemia  E2     0  0    255 
## 5:   Febrile neutropenia  E1     6  6    260 
## ---                     
## 174:       Cough  E2    15  16    255 
## 175:      Pruritus  E1    14  16    260 
## 176:      Pruritus  E2     9  9    255 
## 177:     Hypertension  E1    19  19    260 
## 178:     Hypertension  E2    21  21    255 

您可以隨時將其轉換回一個data.frame和/或如果需要重命名列。

+0

這是很好的方法。出於某種原因,fill = TRUE會給我錯誤。沒有它,我可以看到漂亮的data.frames(帶有填充問題)。我的data.table(v1.9.2)沒有定義填充參數。我重寫了do.call(「rbind」),但沒有運氣 – userJT 2014-10-08 16:39:11

+1

您需要data.table> = 1.9.3 – hrbrmstr 2014-10-08 16:41:15

相關問題