2016-07-28 8 views
0

XML Data Анализировать XML-файл с R Получить в кадр данных

<HealthData locale="en_US"> 
<ExportDate value="2016-06-02 14:05:23 -0400"/> 
<Me HKCharacteristicTypeIdentifierDateOfBirth="" HKCharacteristicTypeIdentifierBiologicalSex="HKBiologicalSexNotSet" HKCharacteristicTypeIdentifierBloodType="HKBloodTypeNotSet" HKCharacteristicTypeIdentifierFitzpatrickSkinType="HKFitzpatrickSkinTypeNotSet"/> 
<Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:07:06 -0400" endDate="2014-09-24 15:07:11 -0400" value="7"/> 
<Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:12:13 -0400" endDate="2014-09-24 15:12:18 -0400" value="15"/> 
<Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:17:16 -0400" endDate="2014-09-24 15:17:21 -0400" value="20"/> 
</HealthData> 

R Код

> library(XML) 
> doc="\\pathtoXMLfile" 
> list <-xpathApply(doc, "//HealthData/Record", xmlAttrs) 
> df <- do.call(rbind.data.frame, list) 
> str(df) 

Я пытаюсь взять выборку данных XML, показанный выше, и загрузить его в кадр данных в R с именем каждой записи, то есть Type, sourceName, unit, endDate, значением в качестве заголовка столбца и каждым значением записи, т.е. count, 2014-09-24 15:07:11 -0400, 7 как значения для каждой строки в кадр данных.

Когда df <- do.call(rbind.data.frame, list) закрывается, но он также выглядит так, что он связывает все значения для заголовков столбцов. Если вы View(df) или str(df), вы увидите, что я имею в виду. Как использовать имена записей Record в качестве имен заголовков столбцов?

Спасибо, Райан

ответ

1

Рассмотрим xpathSApply() для извлечения атрибутов, а затем перенести с t() полученный список в dataframe:

library(XML) 

xmlstr <- '<?xml version="1.0" encoding="UTF-8"?> 
      <HealthData locale="en_US"> 
       <ExportDate value="2016-06-02 14:05:23 -0400"/> 
       <Me HKCharacteristicTypeIdentifierDateOfBirth="" HKCharacteristicTypeIdentifierBiologicalSex="HKBiologicalSexNotSet" HKCharacteristicTypeIdentifierBloodType="HKBloodTypeNotSet" HKCharacteristicTypeIdentifierFitzpatrickSkinType="HKFitzpatrickSkinTypeNotSet"/> 
       <Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:07:06 -0400" endDate="2014-09-24 15:07:11 -0400" value="7"/> 
       <Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:12:13 -0400" endDate="2014-09-24 15:12:18 -0400" value="15"/> 
       <Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:17:16 -0400" endDate="2014-09-24 15:17:21 -0400" value="20"/> 
      </HealthData>' 

xml <- xmlParse(xmlstr) 

recordAttribs <- xpathSApply(doc=xml, path="//HealthData/Record", xmlAttrs) 
df <- data.frame(t(recordAttribs)) 
df 

#        type    sourceName unit 
# 1 HKQuantityTypeIdentifierStepCount Ryan Praskievicz iPhone count 
# 2 HKQuantityTypeIdentifierStepCount Ryan Praskievicz iPhone count 
# 3 HKQuantityTypeIdentifierStepCount Ryan Praskievicz iPhone count 
#    creationDate     startDate     endDate 
# 1 2014-10-02 08:30:17 -0400 2014-09-24 15:07:06 -0400 2014-09-24 15:07:11 -0400 
# 2 2014-10-02 08:30:17 -0400 2014-09-24 15:12:13 -0400 2014-09-24 15:12:18 -0400 
# 3 2014-10-02 08:30:17 -0400 2014-09-24 15:17:16 -0400 2014-09-24 15:17:21 -0400 
# value 
# 1  7 
# 2 15 
# 3 20 

В случае атрибутов, которые появляются в некоторых и не другие, рассмотрите сопоставление с заранее определенным списком имен и итеративно заполните NAs. Ниже приведены два варианта с использованием sapply() с for петли и вторым аргумента-списка:

recordnames <- c("type", "unit", "sourceName", "device", "sourceVersion", 
       "creationDate", "startDate", "endDate", "value") 

# FOR LOOP VERSION 
recordAttribs <- sapply(recordAttribs, function(i) { 
    for (r in recordnames){ 
    i[r] <- ifelse(is.null(i[r]), NA, i[r]) 
    } 
    i <- i[recordnames] # REORDER INNER VECTORS 
    return(i) 
}) 

# TWO LIST ARGUMENT SAPPLY 
recordAttribs <- sapply(recordAttribs, function(i,r) { 
    if (is.null(i[r])) i[r] <- NA 
     else i[r] <- i[r]   
    i <- i[recordnames] # REORDER INNER VECTORS 
    return(i) 
}, recordnames) 


df <- data.frame(t(recordAttribs)) 
+0

спасибо, что он отлично работал для данных испытаний, которые я предоставил. Когда я вернулся и попытался применить его к полному набору данных, я понял, что есть некоторые записи с 9 столбцами, а не 7, т.е. '<Тип записи =" HKQuantityTypeIdentifierFlightsClimbed "sourceName =" Ryan Praskievicz iPhone "sourceVersion =" 9.3.2 "устройство = "< < HKDevice: 0x15a4af3f0 >, имя: iPhone, производитель: Apple, модель: iPhone, аппаратное обеспечение: iPhone8,1, программное обеспечение: 9.3.2 >" unit = "count" creationDate = "2016-06-02 12:27 : 46 -0400 "startDate =" 2016-06-02 12:09:29 -0400 "endDate =" 2016-06-02 12:09:29 -0400 "value =" 1 "/>' это не сработало. Есть идеи? –

+0

Знаете ли вы, что хотите сохранить общие атрибуты или все? Знаете ли вы заранее, какие атрибуты сохранить? – Parfait

+0

Да, я хотел бы сохранить все 9 строк из вектора и просто иметь NA для векторов с 7 строками. –

1

Другим вариантом является xmlAttrsToDataFrame, который должен обрабатывать недостающие атрибуты. Вы также можете получить теги с определенным атрибутом, таким как устройство

XML:::xmlAttrsToDataFrame(xml["//Record"]) 
XML:::xmlAttrsToDataFrame(xml["//Record[@device]"]) 
+0

это отлично работает. Благодаря! –