初心者也會用的 R 語言讀取 XML 資料分析實戰教學!(一)

隨著 API 經濟遍地開花,應用程式與資料源之間的互動實作成為現代軟體工程師必備的基本能力,其中最常見的中前端資料交換格式有 XML 及 JSON 等等,其中 XML 由於傳統商用等級的服務高度支援,且各程式語言都具備完整成熟的套件體系,讀取 XML 對於資料工程師或資料科學家的日常工作而言可說是不可或缺的一部分。

XML 是一種標記語言,類似網頁 HTML ,透過 < 各種TAG > 的定義統一化規格並豐富化資料意義,配合 Schema 讓資料結構具備高度可程式化能力,再加上容易維護的優勢,在許多資料串接實務中是很流行的通用資料格式(別再說只會 CSV 啦!)。

可惜的是,許多立志朝向資料科學領域的學生很容易忽略 XML 的學習,加上網路上搜尋「 R XML」的熱門網頁例如這篇教學《使用 R 讀取開放資料 (CSV, XML, JSON)》通常比較簡略,因此有了這篇教學分享文章的誕生,讓我們一起來練習。

準備好了嗎?本文的教學範例採用 R 語言並搭配 XML 套件包以及 w3schools 、政府開放資料的 XML 範例,馬上跟著內文一起邁向資料分析的大祕寶吧!

什麼?還沒看過 XML ?!W3schools 網站中的一個 XML 範例節錄:

r-xml-in-practice-example-1

看懂 XML 就靠它:認識 XML Schema

Schema 也常稱作 XSD (XML Schema Definition),顧名思義就是用來說明關於一份 XML 應該如何使用以及其中所含資料的相關資訊。

現代許多成熟的商用軟體往往都把 XSD 的瀏覽圖形化,但仍然有許多工程師習慣看原始的 XSD 文件,典型的例子如下:

r-xml-in-practice-example-4

一份好的 XSD 當中會預先資料格式定義,包括:

1. 資料(元素)清單 & 資料類型( e.g., 字串 string )

2. 資料(元素) 屬性

3. 資料(元素) 格式限制

許多 XML 程式吞吐前會預先判別針對某個特定的資料元素是否有值可以返回,假如沒有的話實際上並不會安插一個" 0 “或是" NULL “而是直接跳過該元素的 tag ,這時候就非常需要針對 Schema 的定義而非僅採用幾個 XML reply 的實例來撰寫解析程式,以避免出現遺漏或錯誤解析的結果,這在解析大型 XML 檔案時格外重要。

另外每一個 tag 可能具備自己獨有的後設屬性需要被定義。「屬性」,大概是軟工用語中最容易迷惑人的那一類詞了,什麼是屬性?

想像一下你剛剛預購了一部紅火烤漆的 Tesla Model 3 ,和這台車(資料)有關的屬性就有車型( Model 3 )、顏色( 例如紅色 )等等。

屬性在 XSD 中的典型表示方式如下:

r-xml-in-practice-example-3

最後, XSD 中也會紀錄跟限制有關的資訊,例如資料的最大值、最小值的定義等等,範例如下:

r-xml-in-practice-example-2

想知道更多 Schema 細節,除了造訪 w3schools 網站之外, SlidesShare 上也有一些教學,像是這份簡報:

R 解析/讀取/操作 XML 的超級幫手: XML 套件包

出身於貝爾實驗室、 R 套件創作名人 Duncan Temple Lang 教授開發的 XML 套件包應該是目前在 R 使用者中比較受歡迎的工具,而且此專案也持續在更新(截稿前的最近一版是 3 月份),是一個理想的 XML 解析工具。

XML 包的文件長達 170 頁,其實不必全看,因為當中還包含了一些處理 HTML 用的功能,對於專寫網路爬蟲的人來說比較有用,這又是另外一個故事了。

我把比較常用的基本功能及說明羅列如下,讀者可搭配下集的實例演練對照學習:

getEncoding

在資料 I/O 的過程中,編碼經常造成資料處理上種種麻煩,因此了解輸入資料的編碼是否正確是很有必要的。

xmlParse or xmlTreeParse

解析 XML 檔案的第一步,爬取 XML 檔案結構並轉為 R 物件,讀檔成功後的 XML 文件以 Value 形式存在(你以為是 DataFrame 啊?想得美哦 😛 )。

xmlToDataFrame

美夢成真的一步,將已經讀進 R 中的 XML 文件轉為 R 分析資料常用的 DataFrame 格式。不過別抱太大期望,在大多數案例中這個功能一發命中的效果很差,因此通常需要重複多次 xmlToDataFrame 作業或是採用接著要提到的 xmlToList 。

xmlToList

將 XML 文件解析為 List 格式,典型的處理手法是再將該 List 透過 R 的基本功能 Unlist 簡化為基本向量後,再透過適當的資料轉換、重組手法合併為想要的 DataFrame 格式。

r-xml-in-practice-example-5

xmlRoot & xmlChildren & xmlParent

仔細觀察不難發現其實 XML 就是一個樹狀結構/巢狀結構(如上圖),其中每一個節點就稱為 Node , XML 的取值和操作和 Nodes 有很緊密的關係。

xmlRoot 可以幫我們抓取最上層的節點(Node A); xmlChildren 用來抓取下一層的節點,例如對於 Node B 執行這個指令就會參照到 Node E/F/G ;反之,對於 Node B/C/D 而言, xmlParent 將找到的是 Node A。

getNodeSet

這個威力強大的功能可以透過 Xpath 語法幫我們抓取特定路徑位置的 Nodes ,對於複雜的 XML 來說,採用這個功能配合 Schema 定義可以省下很多辨識資料的功夫。

什麼是 Xpath ?別急,很快告訴你。

xmlAttrs & xmlGetAttr

還記得你的 Tesla Model 3 (屬性)嗎?

xmlAttrs 用來抓取特定 Node 的屬性列表; xmlGetAttr 則可以取得 Node 中的屬性數值,另外 xmlGetAttr 比較特別的就是還允許指定一個當沒有屬性值可以返回時要使用的預設值。

xmlValue

這個功能可以讓你快速取得某一個 Node 底下所有分支的資料,以上面的樹狀圖來說,如果指定的對象是 Node A ,那麼使用 xmlValue 將一口氣得到 Node B/C/D 再加上 Node B 的分支 Node E/F/G 的資料並轉為字串,假如不想要連子孫分支的資料也回傳的話,可以試試將 recursive 這個參數設為 FALSE 。

什麼樣的資料會需要這個功能?一個可能出乎你意外的應用案例:部落格匯出的文章備份 XML 就很適合用這個功能來處理。

xmlApply

APPLY 函數在許多套件包中都有對應的 wrapper ,到底它有什麼魅力讓許多作者把它設為必要的功能?

其實 APPLY 做的事情非常簡單,它充分運用了 R 向量運算的優點,用簡單的函數表達就能完成原本需要寫 for 迴圈才能執行的工作。

例如這個例子:

xmlApply(你指定的 node , xmlAttrs)

上式會根據指定好的 node 及底下的分支,自動計算個別的 xmlAttrs 並返回結果。是不是很有效率呢?

系列文章:

初心者也會用的 R 語言讀取 XML 資料分析實戰教學!(二)

初心者也會用的 R 語言讀取 XML 資料分析實戰教學!(三)

更多 R 資料科學實戰:

* 統計R語言實作筆記系列 – 2D視覺化進階 GGPLOT()的基本架構(一)

* 統計R語言實作筆記系列 – 用 SHINY 套件極速打造你的商業智慧分析網站!

* 統計R語言實作筆記系列- 直線ABLINE()、曲線CURVE()與多邊形POLYGON()

* 統計R語言實作筆記系列 – 2D視覺化入門

* 統計R語言實作筆記系列 – R的字串處理:GREP套件包(GREP、GREPL、REGEXPR、GREGEXPR、REGEXEC)

(Visited 2,334 times, 17 visits today)

Wendell.Huang

科技公司嫌棄太活潑,消費品牌挑剔太沉悶..., 經常必須解釋自己在學什麼, 不小心就摔破對方眼鏡的跨領域玩家。

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *