天天看點

《R語言資料分析》——2.2 其他流行的線上資料格式

在web上資料通常采用xml或json兩種格式存放,因為這兩類檔案都使用了人類可以了解的資料格式,從程式開發的角度而言也非常容易處理,同時也适合處理任意類型的階層化資料結構,而不像csv檔案一樣僅能處理簡單的表格資料。

《R語言資料分析》——2.2 其他流行的線上資料格式

鑒于json非常容易了解,是以可以在編譯之前簡單地浏覽一下資料格式。下面可以使用rjson包将樹狀清單導入到r會話中:

《R語言資料分析》——2.2 其他流行的線上資料格式
《R語言資料分析》——2.2 其他流行的線上資料格式

這和之前我們曾經看見過的用逗号分隔的檔案略有不同!再仔細分析一下文檔,可以發現api終端傳回的是中繼資料檔案而非我們之前在csv檔案中看到的原始表格資料。現在我們在浏覽器中打開相關url來檢視前5行中id為25ei-6bcr的資料内容:

《R語言資料分析》——2.2 其他流行的線上資料格式

當然在json結果連結清單中的結構已經發生了變化。下面,讓我們将水準連結清單讀入到r中:

《R語言資料分析》——2.2 其他流行的線上資料格式

還可以利用諸如視圖、列等一些更詳細的中繼資料資訊來擷取資料,這裡面可能有一些我們現在不感興趣的内容,因為fromjson傳回的是一個list對象。從現在開始,我們可以直接删掉這些中繼資料,然後僅處理data行:

《R語言資料分析》——2.2 其他流行的線上資料格式

此時結果還是一個list對象,可以将它轉換為data.frame類型。該list對象擁有5個元素,每個元素包括了19個嵌入的子節點。我們首先觀察其中第13個子元素,是一個5-5的向量清單。這意味着樹狀list對象無法直接轉換成表格資料,更不用說我們還發現其中某些向量的值是未經處理的json格式。是以,為了簡單起見,同時也為了證明我們的觀點,現在去掉與位址相關的值,然後将剩下的資料轉換成data.frame格式:

《R語言資料分析》——2.2 其他流行的線上資料格式

我們應用了一個簡單的函數去掉了表中每個元素的位址資訊(移除了每個x的第13個元素),然後自動将其簡化為matrix(通過使用sapply而非lapply對list中每個元素疊代處理),完成調換(通過t),再将結果強制轉換為data.frame。

也可以使用之前介紹的一些方法,通過一些輔助函數而不用手動轉換所有list元素。plyr包(請參考本書第3章和第4章獲得更多細節)就提供了一些非常有用能夠實作資料劃分群組合的函數:

《R語言資料分析》——2.2 其他流行的線上資料格式

現在結果看起來熟悉一些了吧,盡管省略了變量的名字,而且所有值都被轉換為字元向量或因子——盡管日期類型是以unix時間戳類型存放的。借助提供的中繼資料(res$meta),能夠非常容易地解決這些難題。例如,可以通過抽取(通過[operator指令)除了已經被删掉的位址資訊列13列之外的所有列的名字域:

《R語言資料分析》——2.2 其他流行的線上資料格式

也可以借助已經提供的中繼資料來确定對象的類别。例如,可以從域rendertypename着手,然後使用as.numeric處理數值型,使用as.posixct處理所有的calendar_date,就可以解決之前談到的絕大部分問題了。

那麼,你聽過80%的資料分析時間是用在資料預處理過程上這一說法嗎?

對json和xml進行解析和重構到data.frame對象會占用大量的時間,特别是在處理層次表時尤為突出。包jsonlite試圖實作r對象到正常的json資料格式之間的轉換而非原始處理來節約時間。從實際工作的角度來看,這意味着如果可能的話,從jsonlite::fromjson就能夠得到data.frame結果而不是一堆原始list對象,實作了更好的無縫資料轉換。不幸的是,我們并不是總能将list對象轉換為表格式,此時,可以通過rlist包來加速list對象的轉換。更多實作細節請參考本書第14章。

《R語言資料分析》——2.2 其他流行的線上資料格式

如圖所示,api的xml輸出與之前我們看到的json格式不太相同,它的輸出僅包含我們感興趣的行。這樣,就能很簡單地完成xml文檔的分析,并且從中抽取出我們感興趣的行并将其轉換為data.frame:

《R語言資料分析》——2.2 其他流行的線上資料格式

可以通過修改傳遞給xmltodataframe函數中參數colclasses的值來手動确定變量的類型,就像在read.table函數裡那樣做一樣,也可以通過一個快速的helper函數來解決這個問題:

《R語言資料分析》——2.2 其他流行的線上資料格式

當helper函數傳回為true時,就可以驗證我們對某個列僅包含數字的猜想,并将其轉換為數值類型。請注意我們在将因子類型轉換為數字時先要将其轉換為字元類型,因為直接将因子轉換為數值會傳回因子的順序而不是實際的數值。我們還可以通過type.convert函數來解決這個問題,read.table預設會采用這一方法。

現在,我們已經能夠基于各種不同類型的資料下載下傳格式完成資料處理,不過鑒于我們還必須掌握一些其他的資料源操作,我建議讀者們繼續往下接着學習。