当节点只有属性时,如何将XML转换为data.frame?

时间:2014-10-08 14:48:45

标签: xml r dataframe

我正在尝试使用XML包以及xmlToList或xmlToDataFrame函数。 我的输入数据在互联网上(前2行),我只需要处理XML的某些部分(参见第三个节点集命令)

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'

如何最好地提取计数数据?我尝试取消列表,但我可能没有足够的进展。我想避免循环和手动xmlGetAttr。但在最坏的情况下,任何解决方案都被接受。我发现XML包非常密集,有两个版本的XML数据作为列表和NodeSets ......: - (

理想的输出看起来像这样:(所有事件(不仅仅是第3行)

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

(甚至有一个类别栏(心脏病) - 这将是超理想的)

P.S。 我用了这个问题How to transform XML data into a data.frame? 那个问题R list to data frame但没有运气。 : - (

1 个答案:

答案 0 :(得分:4)

您可以通过迭代每个event并通过相对XPath提取counts属性来简化XML提取。通过使用rbindlist包中的data.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和/或重命名列。