2016-07-28 61 views
0

XML數據 其中R解析XML文件獲取到的數據幀

<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> 

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

我試圖採取上面所示的XML數據樣本並將其加載到一個數據幀R代碼R與每個記錄的名稱即類型,sourceName,單位,endDate,值作爲列標題和每個記錄值即計數,2014-09-24 15:07:11 -0400,7作爲每行的值在數據幀。

df <- do.call(rbind.data.frame, list)這個關閉,但它也看起來像它綁定列標題的所有值也。如果你View(df)str(df)你會明白我的意思。如何使用Record變量名稱作爲列標題名稱?

感謝, 瑞安

回答

1

考慮xpathSApply()檢索屬性,然後用t()調換結果列表到數據幀:

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環和第二list參數兩個版本:

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,即'不起作用。有任何想法嗎? –

+0

你知不知道要保持共同的屬性還是全部?您是否事先知道要保留哪些屬性? – Parfait

+0

是的,我想保留矢量中的所有9行,並只有NAs爲7行的向量。 –

1

另一種選擇是xmlAttrsToDataFrame,這應該處理缺少的屬性。您還可以獲取具有特定屬性的標籤,如設備

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

這個工程也很棒。謝謝! –