資料科學與工程技術叢書 點選檢視第二章 R資料科學實戰:工具詳解與案例分析

第1章
資料導入工具
無論資料分析的目的是什麼,将資料導入R中的過程都是不可或缺的。畢竟巧婦難為無米之炊。是以本章主要介紹如何選擇合适的包,将不同類型的資料檔案導入R中。學習完本章的内容之後,讀者将會獲得以下技能。
1)掌握與資料檔案類型相對應的R語言資料讀取函數。
2)了解常用資料類型讀取所需的R程式包。
3)了解不同R包中相似函數的優缺點。
4)清楚常用資料讀取函數的參數設定。
5)能夠處理規則及不規則原始資料檔案的讀取和初步檢視。
在描述和講解如何使用R語言各個包的基本方法的同時,本章還會介紹一些筆者曾經踩過的“坑”,以及從中學到的一些小知識點或技巧,希望能讓讀者在學習過程中避免重蹈覆轍。
1.1 utils—資料讀取基本功
utils包是R語言的基礎包之一。這個包最重要的任務其實并不是進行資料導入,而是為程式設計和開發R包提供非常實用的工具函數。使用utils包來進行資料導入和初步的資料探索也許僅僅隻是利用了utils包不到1%的功能,但這1%卻足以讓你在學習R語言時事半功倍。
1.1.1 read.csv/csv2—逗号分隔資料讀取
.csv可能是目前最常見的平面檔案類型了。它代表的是comma-separated values,簡單來講就是,檔案裡每一個單獨的資料值都是用逗号進行分隔的。.csv隻是text file(文本檔案)的一種,文本檔案在微軟的Windows作業系統中常以拓展名為.txt的形式呈現。文本檔案可以使用各種符号來分隔資料值,例如常見的tab和“;”(分号),或者其他任意符号。即便是以.csv為拓展名的檔案也并非一定是以逗号進行分隔的,相關内容在本章後面的函數示範部分會有介紹。檔案的拓展名并非必須,熟悉Linux系統的讀者可能接觸過很多無拓展名的檔案。處理無拓展名的文本檔案資料時,最簡單的辦法就是使用data.table包中的fread函數(相關内容請參見第6章)。
utils裡的read.csv/csv2是專門用于設定快速讀取逗号分隔(read.csv)或是分号分隔(read.csv2)。也就是說,在事先了解資料值分隔符号的情況下,這兩個函數對分隔符和其他一些參數的預設設定會使資料導入的部分更加簡單和快捷。有一點需要特别注意,即這兩個函數對小數點的處理:前者預設的小數點是“.”,後者預設的小數點是“,”。這隻是因為不同國家技術人員對資料值分隔符的見解或者好惡不同而造成的。
萬裡長征第一步,我們先來看read.csv最簡單的使用方式,代碼如下:
此行代碼可以解讀為使用read.csv從工作空間讀取檔案flights.csv,然後将資料集儲存到flights中,其他所有參數都使用預設值。因為flights.csv檔案已經在R的工作路徑裡,是以此處免去了設定work directory。這裡希望讀者能夠自行探索使用.rproj(R項目—将每一次資料分析的過程都看作一個獨立的項目)來對每一個獨立的資料分析工作進行分類和歸集。該方法不僅免去了設定路徑的麻煩,也減少了因原始資料檔案太多而可能導緻的各種隐患。
小知識
函數在執行的時候可以依照其預設設定的參數位置來執行,也就是說,使用者無須指定每一個參數的名稱,隻需按照位置順序來設定參數值即可。比如,read.csv中的file參數名就可以省略,隻要第一位是讀取文檔的目标路徑和檔案名就可以。
資料檔案被讀取到R工作環境中的第一步通常為調用str函數來對該資料對象進行初步檢視,下面的代碼列出了該函數最簡單的使用方式。
str函數可用于檢視讀取資料結構、變量名稱等。這裡同樣也隻指定了一個非預設參數,其他參數全部都為預設值。str的輸出結果由5個主要部分組成,具體說明如下。
1)data.frame代表資料集在R中的呈現格式,這裡指的是資料框格式,讀者可以将其設想為常見的Excel格式。
2)6 obs. of 6 variables代表這個資料集有6個變量,每個變量分别有6個觀測值。
3)$ carrier與其餘帶有“$”符号的函數均指變量名稱。
4)變量名稱冒号後面的Factor和int代表的是變量類型。這裡分别是指因子型Factor和整數型int資料。另外還有字元型chr、邏輯型logi、浮點型dbl(帶有小數點的數字)、複雜型complex等。因子型變量的後面還列出了各個變量的因子水準,也就是擁有多少個不同的因子。比如,出發地origin後的3 levels就是表示其有3個因子水準。隻是出發地是否屬于因子類型的資料還有待商榷,而read.csv預設将所有的字元型資料都讀成了因子型。
5)資料中的實際觀測值。str函數在預設情況下會顯示10行資料。使用str函數浏覽導入的資料集可以讓使用者确定讀取的資料是否正确、資料中是否有預設的部分、變量的種類等資訊,進而确定下一步進行資料處理的方向。其他用來檢視資料集的函數還有head、tail、view等,另外,Rstudio中的Environment部分也可以用于檢視目前工作環境中的資料框或其他類型的資料集。
前文提到過,.csv并非一定是以逗号進行分隔。如果遇到以非逗号分隔資料值的情況,加之未指定分隔符(例如,運作read.csv讀取以Tab分隔的檔案),就會出現下面的情況:
小技巧
指定(assgin)符号“<-”的快捷鍵是“alt”加“-”(短劃線)。Rstudio快捷鍵參照表可以通過“alt+K”來檢視詳細内容。
由代碼可知,read.csv函數将所有資料都讀取到了一列中。因為按照預設的參數設定,函數會尋找逗号作為分隔列的标準,若找不到逗号,則隻好将所有變量都放在一列中。指定分隔符參數可以解決這個問題。将t(tab在R中的表達方式)指定給sep參數後再次運作read.csv讀取以Tab分隔的csv檔案,代碼如下:
根據實際情況不同,字元型資料有時會是因子,有時不會。如果使用read.csv預設的讀取方式,那麼字元型全因子化會對後續的處理分析帶來很多麻煩。是以最好是将字元因子化關掉。stringsAsFactors參數就是這個開關,示例代碼如下:
1.1.2 read.delim/delim2—特定分隔符資料讀取
read.delim/delim2這兩個函數是專門用來處理以tab分隔資料的檔案的,delim可用來讀取小數點是“.”的資料,delim2則用來處理小數點是“,”的資料,是以這兩個函數與read.csv/csv2唯一不同的就隻是參數sep = "t"。聰明的你很可能已經想到了如果使用這兩個函數的預設設定來讀取以逗号分隔的資料會發生什麼。函數的預設參數會在原始資料中不斷地尋找tab分隔符,找不到的話就會如同1.1.1節裡面示範的那樣,将所有變量都擠在一列裡。read.delim/delim2的示例代碼如下:
無論是read.csv還是read.delim,幫助文檔中的參數格式都是相同的。從上面的代碼結果中可以看出,read.delim執行的其實,是函數read.table。其實,這4個函數(read.csv/read.csv2/read.delim/read.delim2)都隻是它們的母函數read.table的變形罷了。這樣做的原因有可能是因為在RStudio出生之前,read.csv/delim比read.table更容易記住,也有可能隻是Henrik Bengtsson(utils包的筆者)覺得這樣做很酷。具體是什麼原因已經不再重要,會用這些函數才是第一要務。
1.1.3 read.table—任意分隔符資料讀取
read.table函數會将檔案讀成資料框的格式,将分隔符作為區分變量的依據,把不同的變量放置在不同的列中,每一行的資料都會對應相應的變量名稱進行排放。表1-1簡要列出了read.table函數中主要參數的中英文對照。
以上這些參數已足以應付讀取日常練習所用的規整的資料檔案,例如,教授布置的統計作業中的原始資料集,各種傳感器輸出的.csv檔案等。下面的代碼及運作結果示範非常簡單,使用read.table讀取1.1.1節中的第一個資料集,實作思路是每次隻增加一個read.table函數中的參數。代碼如下:
表1-2展示了所有參數均為預設設定的部分結果。
小提示
上面的示範代碼中使用了head函數,該函數可以按照人們習慣的方式将資料框按照自上而下的方式顯示出來,而不是像str函數那樣從左向右展示。一般在做初步資料檢視的時候,推薦兩個函數都運作,作為互補。head友善與原始資料文檔進行比對,而str則可以顯示所儲存的資料框屬性、變量類型等資訊。
因為函數預設的分隔符是空白(注意不是空格),是以應有的6個變量都被讀在一列中。且預設的header參數是假,是以資料變量被預設配置設定了一個新的變量名V1,并且應為變量名稱的這一行變成了觀測值的第一行。将header設定為TRUE後的代碼如下:
表1-3中顯示的是部分結果。
指定header參數為真,分隔符sep參數為“,”後,變量名稱才得以讀取成應有的樣子(如表1-4所示)。
表1-4所示的資料框終于呈現了該有的樣子。需要注意的,是因為字元資料因子化的參數還是預設設定,是以變量carrier、tailnum、origin、dest還是因子型。在實際練習或使用時,建議指定stringAsFactors = FALSE。
以上讀取的資料集都是規整的資料集,即每一行資料都有相同的觀測值。不過在實際生活中,原始資料難免會存在空白行、空白值、預設值,或者某一行資料存在多餘觀測值卻沒有與之對應的變量名稱,抑或中繼資料和原始資料在同一個檔案中等各種問題。這裡暫且稱這些問題資料集為不規則資料集,簡單說就是,實際列的個數多于列名的個數。read.table函數為這些問題準備了相應的參數。
1.空白行
表1-1中介紹過read.table對于空白行的預設處理是跳過,這可以滿足大部分常見資料的情況。不過在某些特殊情況下,例如,一個資料檔案中同時存在兩個或兩個以上的資料集,那麼保留白白行可能會有助于後續的資料處理。表1-5示範的就是一個比較特殊的例子。空白行的上部是中繼資料,也即解釋資料的資料,這裡示範的是航空公司的縮寫和全名的對照。空白行的下部是資料的主體部分,航班号、起始地縮寫、起飛時間。這裡保留白白行可有助于區分資料的不同部分。
保留白白行的代碼如下所示:
指定空白行保留的參數後,資料被成功讀進R(表1-6)。
如此一來,不同的資料集就可以很容易地進行切割并歸集到新的資料集中。可是,另外一個問題又出現了,函數按照第一部分的兩列變量将後續的所有資料也都寫入了兩列。這是因為read.table會掃描檔案中前五行的資料(包括變量名稱)并以此為标準來确定變量數,airlines.csv中開始的五行資料都隻有兩列,是以後續的資料也都強制讀取成兩列。如果資料的第2~5行中存在任何一行擁有多于前面一行或幾行的資料值,那麼函數就會報錯提示第一行沒有相應數量的值。這種情況可以根據實際資料檔案内容,用兩種方式來處理,具體如下。
1)如果檔案中開始的部分是暫時不需要的中繼資料,那麼可以使用skip函數跳過相應的行數,隻讀取感興趣的資料。
2)如果檔案内容是一個整體,隻是若幹行資料具有額外的觀測值。那麼可以通過調整參數col.names或fill和header進行處理。
第一種情況比較容易,讀者可以自行測試,在此略過。第二種情況需要知道資料中觀測值個數的最大值,以用來補齊變量個數。因為已經知道airlines檔案的第二部分擁有6個變量,是以下面就來示範如何将6個變量名稱指定成新的變量名(表1-7),代碼如下:
示範結果如表1-7所示。
小技巧:
另外一個擷取不規則資料集中所需變量個數的方法是利用報錯資訊。當不指定col.names參數,且原始資料的第2~5行中任一行有多于第一行的資料時,read.table會報錯提示Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec, : line 1 did not have X elements, X即所需要的手動指定的變量個數。
這裡使用paste0來建立新的變量名稱。paste0可以了解為膠水函數,用于将需要的字元串粘合在一起。這裡示範的意思是建立6個以V開頭,從V1到V6的字元串作為變量名。這種處理方式足以應付平時練習用的小型資料集(比如,隻有幾行到幾十行資料的資料集)。但是在處理實際工作中成百上千行的資料時,這種手動指定變量個數的方法就顯得笨拙而低效了。下面的代碼示範了如何實作自動檢測資料集所需的變量數:
部分結果展示如表1-8所示。
count.fields/max/seq_len這三個函數的配合使用實作了如下功能。
count.fields用于自動檢測資料集中每一行資料的觀測值個數,max用于找出count.fields輸入結果中的最大值,seq_len用于以最大值為參照生成1到最大值的整數序列,膠水函數paste0用于定義變量名稱。
因為R基于向量計算的特性,是以這種函數之間簡單的配合使用很常見也很有效。是以希望小夥伴們在以後的練習或實際工作中,多思考,盡量使用這樣的組合來提高代碼的效率、簡潔性和可重複性。
使用參數fill和header也可以讀取不規則資料集。需要注意的是,采用這種方法是有前提條件的,即原始資料第2~5行實際列的個數應大于列名。代碼如下:
上述代碼的示範結果如表1-9所示。
2.預設值、空白
一個資料集裡出現預設值(NA)或空白(“”)的情況十分常見,兩者之間的差別需要根據不同的實際情況來确定。理論上來講,預設值仍是資料觀測值的一種,雖然在原始資料中其可能與空白一樣沒有顯示,但是它可以通過其他手段來進行補齊。而空白有可能并不是資料,比如在上面的示範中,V3至V6列,1~5行都是空白,這些空白不屬于任何實際資料變量,是真正的空白,因而不能說這些空白是預設值。預設值和空白的處理完全可以獨立成書,因為相關内容已經超出了本書的範圍,是以這裡不再過多讨論。下面隻示範在導入資料的過程中,如何進行簡單的預設值、空白預處理,代碼如下:
表1-10中展示了處理後的部分資料值。
第七列中的資料在指定将空白替換成“NA”之後,原有的空白位置被寫入了“NA”,也就是說第七列的空白屬于資料的一部分。根據實際情況,也可以将多餘的資料部分或全部替換成“NA”(如表1-11所示),以友善後續的處理及分析,代碼如下:
替換結果如表1-11所示。
當資料集行數較多,無法輕易地鑒别出某一列到底有多少個觀測值需要指派為“NA”的時候,可以配合unique函數進行處理。處理的思路是先将資料讀取到R中,然後使用unique函數找到指定列中的非重複觀測值,選取指定觀測值并儲存到一個向量内,然後将向量指定給na.strings參數來進行替換,代碼如下:
替換結果如表1-12所示。
第一次讀取資料是為了獲得需要替換的觀測值,第二次讀取則是将需要替換成“NA”的觀測值指定給相應參數。因為replace是一個字元串向量,是以可以使用“[”按位置選擇其中的值,當然也可以不選擇任何值,直接全部替換。
“[”是baseR中Extract的一種,在R的使用過程中,這是必須掌握和了解的函數之一。
1.2 readr—進階資料讀取
'readr'包是R語言世界級大神之一Hadley Wickham 主導開發的一個資料讀取包。相較于'utils' 包裡的讀取函數,'readr'包主要擁有3點優勢,具體如下。
1)更快。就平均讀取速度而言,'readr'包裡的'read_csv'一般要比'read.csv'快三到十倍不等。
2)預設設定更簡潔。預設情況下,'readr'包會自動解析每列的資料類型,并顯示解析結果,這樣可以更加直覺地看到讀取後的資料類型是否符合預期,而且無須設定'stringAsFactors'。
3)對資料類型的解析更準确。'utils'包中提供的'read.table'函數在甄别一列資料的屬性時,隻會對起始5行的觀測值類型進行評估,并以此決定該列全部資料的類型。而'readr'中的函數預設評估1000行的觀測值後再決定資料的類型。
'readr'包中常用的資料讀取函數包括'read_delim'、'read_fwf'、'read_lines'、'read_log'和'read_table'。其中'read_delim'屬于常見資料讀取'read_csv/read_csv2/read_tsv'的母函數,是以也可以直接調用子函數。
read_delim
常用分隔符檔案的讀取函數'read_csv/read_csv2/read_tsv'分别對應于'utils'中的'read.csv/read.csv2/read.delim'。Hadley與其他成員開發的這個包更像是對'baseR'中與資料讀取有關函數的一個優化,使其更加規範、穩定和可再現。表1-13中列出了read_delim參數的英文名稱、功能的中文描述及部分傳參注釋。其中,比較重要的幾個參數依次為'file''delim'(如使用'read_csv'等則無須設定)、'skip'、'col_name'和'col_types'。之是以說它們比較重要,是因為筆者發現适當調整參數設定可以讓後續的資料處理事半功倍。
參數'file'的重要性不言而喻,無預設值,必須設定。第二位參數'delim'視情況可有可無,在使用具體的子函數'read_csv/read_csv2/read_tsv'時就無須設定。不過,使用母函數'read_delim'時是沒有預設值的。
當一個.csv資料中前面有很多空白行時,skip參數可以直接跳過空白行來讀取資料。具體設定非常簡單,skip = 3即表示跳過前三行資料,從第四行開始讀取。這個參數并非隻用于跳過空白行,也可以用來讀取原始資料的一部分,配合n_max使用可以做到随心所欲地讀取任一部分資料。
另外一個重要的參數是col_names。對原始資料中的變量名稱不滿意,可以使用該參數自定義變量名稱。這個參數可以了解為将read.table 中的參數header和col.names 的功能融合在一起,相關内容請參見1.1.3節。
變量屬性對後續計算會有很大影響,是以col_types參數的重要性也不容忽視。雖然Hadley等已經将這個參數的功能優化得非常智能了,但他還是會建議使用者應盡量依據個人需求來定義變量屬性,因為意外總是存在的。
下面的代碼展示了read_csv解析變量屬性正常、讀取正常的情況。運作函數之後,報告會在console中顯示每一列資料都被解析成了何種屬性,是以非常容易甄别哪一列資料類型不是期望的類型。在某些特殊情況下,比如原始檔案分隔符号不統一的情況,這時自動解析功能會無法識别某一列或多列變量的屬性,進而顯示parsing failures(剖析失敗)的報告。使用者可以通過problems函數來檢視具體的資訊,進而确定原始資料中的哪一部分資料出現了問題。
1.3 utils vs readr—你喜歡哪個?
就實際應用而言,筆者建議讀者在考慮原始資料檔案格式的前提下,根據個人需求或喜好來選擇使用utils或readr這兩個包中的資料讀取函數。在R語言的世界裡,沒有最好的函數,隻有最适合的函數。在處理單一或個位數資料檔案的情況下,read.csv和read_csv都可以很好地完成任務。流程圖1-1也許可以幫到有函數選擇困難症的讀者。
之是以設定檔案個數和檔案大小的前提,是因為在面對批量、大容量平面文檔格式的資料時,這兩個函數并非最合适的選擇。data.table包中的fread函數更能滿足在讀取資料時對速度和準确度都有要求的讀者,具體請參見第6章。
1.4 readxl—Excel檔案讀取
readxl是微軟Excel檔案讀取的必備R包,是Hadley Wickham、Jennifer Bryan以及其他6名成員合作完成的經典程式包之一。值得一提的是,該包的開發者之一兼實際維護者Jennifer Bryan(網絡上多稱她為Jenny Bryan),可以稱得上是與Hadley齊名且為數不多的女性R語言神級人物。可能是因為其身為大學教授,是以她總能夠用很生動有趣的方式将複雜的問題簡化成通俗易懂的知識傳遞給“小白”,強烈建議有英文基礎的讀者能夠搜集一些她的主題演講或者書籍。在後續第5章 purrr包的讨論中,筆者也會引用她的經典例子。
更新後的readxl包中雖然也還是隻有5個函數,不過功能卻比以前的版本更強大了。對于起初的版本,資料會被讀取成常見的data.frame格式,而對于現在的版本,讀取後的資料集格式則為tibble,可以了解為提升版的data.frame(具體詳見2.1節)。readxl包括兩個探測性函數excel_format和excel_sheets,一個引用例子的函數readxl_example,新加入的讀取特定單元格的函數cell-specification以及最重要的read_excel函數。本節将着重讨論read_excel的參數設定及用法技巧(見表1-14)。
首先還是需要加載readxl包。盡管Hadley從2017年開始就一直在網絡上宣傳這個包已經屬于tidyverse的一部分,但使用者還是必須手動單獨加載這個包。加載readxl包代碼如下:
readxl包自帶示範檔案,使用函數readxl_example可以檢視檔案名字,以及擷取檔案路徑,代碼如下:
擷取示例檔案的路徑,可以先複制readxl_example函數運作後的結果,然後将其粘貼到read_excel函數的path參數中。下面的代碼示範函數嵌套的方法,這種嵌套的代碼書寫方式能夠在一定程度上簡化代碼和減少命名中間産物的頻率。不過嵌套過多會使可讀性變差,一般推薦隻嵌套兩層。将讀取後的資料儲存在iris中,執行str函數之後将會發現除了經典的data.frame之外,資料集還有另外兩種類别,tbl_df和tbl,這兩種類别的具體含義會在2.1 節中詳細介紹。函數嵌套的示例代碼如下:
之是以命名為iris,是因為這個範例Excel檔案中的第一個工作表就是該經典資料集。函數excel_sheets可用于查詢同一個檔案中的工作表名稱,其實作代碼具體如下:
在datasets.xlsx中一共存在4個工作表,其中包含了4個最經典的R語言練習資料集。在此,希望讀者可以自行浏覽這幾個資料集,對資料集的格式、變量名稱等情況有一定程度的了解,在後續的章節中,筆者還會引用這幾個資料集。
增加參數sheet或range可以讀取指定工作表中的資料。這裡需要注意的是,表1-14中提到了參數優先級的問題。對于一般常見的練習資料集,sheet參數指定的工作表已足夠勝任。讀者隻需要記住range參數可以用來處理特殊情況,也就是說,當設定sheet後依然對讀取到的資料不滿意的情況可以考慮使用range。
下面的代碼示範了sheet的兩種傳參方式:位置序号和名稱。推薦讀者采用後者。因為工作表被意外拖拽導緻位置調換的情況常有發生,而位置意外發生調換之後讀取的資料也會不同,這就增加了代碼崩潰的風險。如果使用名稱,則會降低發生錯誤的幾率。示例代碼如下:
對于後面的參數,讀者可以根據表1-14中的解釋,按照1.1節中的方法,每次增加一個參數,來逐漸掌握每一個參數的功能,這裡不再贅述。
1.5 DBI—資料庫資料查詢、下載下傳
在使用R語言和資料庫進行互動之前,讀者們需要明确一個問題—是否有必要使用R來處理資料。簡單的資料處理任務,比如資料查詢、篩選和簡單運算,相應的資料庫語言應該是比R語言更好的選擇。不過當你對資料庫語言并不熟悉,而且需要R語言強大的統計分析和繪圖環境來處理資料庫中的資料時,DBI包絕對是一條捷徑。因為Hadley大神再一次拯救了“小白”。有了DBI包,不需要了解資料庫互動中各個環節繁瑣的理論知識和技巧,隻需要明白如何通過DBI包來建立資料庫連接配接、查詢和讀取資料即可。不過,這個包也并非萬能鑰匙,想要無障礙地與資料庫進行互動,以下6點是必備的前提。
1)已知資料庫的類型,例如,MySQL、PostgreSQL。
2)已經安裝了相應資料庫類型的R包。
3)資料庫伺服器位址。
4)資料庫名稱。
5)接入資料庫的權限、賬号和密碼。
6)已安裝dplyr包用來本地化資料庫中的資料。
使用R與資料庫進行互動的一般流程為:建立連接配接→發送查詢請求→擷取相關資料。下面,我們用PostgreSQL的資料庫作為代碼示例。首先加載三個必備程式包,其中,DBI和PostgreSQL将用來建立與資料庫的連接配接以及發送請求。dplyr則是用來将資料庫中的資料儲存到本地。加載代碼具體如下:
不同類型的資料庫可能需要調整dbConnect中的參數,具體調整方法讀者可以參見幫助文檔。資料庫伺服器位址、名稱、權限等資訊需要輸入到單引号中,請一定留意是否有空格符号不小心被複制或者因誤操作輸入其中。如果擔心密碼洩露的話,則可以使用RStudio中自帶的密碼彈窗功能。dbListTables函數可以用來查詢資料庫中的詳細内容,并以字元串向量的格式傳回,如果資料庫中無内容,則會傳回空值。調整dbConnect參數的示例代碼如下:
優化後的tbl函數可以直接調取已經建立連接配接的資料庫中的指定資料,并儲存為tibble格式的資料集(參見第2章)。下面的代碼中,逗号後面的參數也可以用“Table1”或“Table2”來表示:
資料庫互動的有關内容完全可以獨立成書,這裡我們隻介紹了最簡單的基本用法,以使大家對如何使用R來查詢資料庫有個最基本的印象。
1.6 pdftools—PDF檔案
學術期刊、網絡雜志和電子書籍一般都會以PDF格式的檔案呈現。一般的計量型資料分析很少會遇到讀取PDF檔案的情況,不過在進行文本挖掘(Text Mining)和主題模型(Topic Modelling)預測中,pdftools包絕對是必備R包之一。該包隻有兩個母函數,一個用來從PDF中提取資料(此處的資料包括數字型和文字型資料),另一個則用來将檔案渲染成PDF格式。本節我們隻讨論第一個母函數—pdf_info。
pdf_info函數下面一共包含6個子函數,功能各不相同,詳見表1-15。但是6個子函數的參數完全一緻,分别是pdf、opw和upw,詳見表1-16。
由于篇幅有限,下面的代碼隻截取了部分結果進行解釋。這裡所用的PDF文檔是pdftools包的幫助文檔,讀者可以自行到R官網上搜尋下載下傳。幫助文檔是開放PDF檔案,無須提供密碼。讀取文檔代碼如下:
當使用pdf_text提取文檔内容時,全部内容都被提取為一個字元串向量,每頁的内容都被單獨放置于一個字元串中。幫助文檔的PDF格式一共包含5頁,是以這裡會得到一個長度為5的字元串向量。有兩種方式可用于檢視提取的文本:可以直接将結果顯示在console中(通過執行print(text)或直接運作text),也可以通過“[ ]”來指定顯示某一頁的内容。空白的位置都會以空格的字元格式顯示,“rn”代表換行符号。提取文檔内容的代碼如下:
該文檔無附件,是以會顯示一個空清單:
文檔中一共包含了6種字型,pdf_fonts會給出字型的名稱、類型、是否嵌入文檔中這三類資訊,具體如下:
目錄讀取的子函數會将所讀取的内容傳回到一個清單中,如果直接将該清單顯示在console中很可能會讓人感覺不知所雲,讀者可以自行實踐。最好的辦法是将讀取的内容使用jsonlite包轉換成json清單的格式進行顯示,以幫助了解文檔的架構。jsonlite包的相關内容詳見1.7節。jsonlite包轉換成json清單的示例代碼如下:
1.7 jsonlite—JSON檔案
JavaScript Object Notation(JSON)通常是作為不同語言之間互相交流資訊的檔案,JSON檔案不但節省存儲空間,其簡潔明了的形式也很容易了解。jsonlite包既能夠完整地将JSON格式的檔案完整地解析和讀取到R語言中來,也可以将任何常見的R對象(object)輸出成JSON格式。在1.6節中,toJSON函數可用來将PDF文檔目錄轉換成JSON格式,以便于了解各層級之間的關系。
讀取JSON檔案的fromJSON函數共包含6個參數,通常情況下,除了指定檔案路徑之外,其他參數使用預設設定即可。表1-17中列出了該函數的參數及功能描述。
首先以JSON常見的數組形式建立一個字元串向量,儲存為example。中括号代表數組的起始,雙引号中代表值,值與值之間以逗号進行分隔,然後再用單引号将這一數組格式儲存到字元串向量中。因為example中的數組是按照JSON格式輸入的,是以直接使用fromJSON函數即可。在預設的參數設定下,可以得到一個包含4個值的R對象—字元串向量。運作fromJSON前後的這兩個字元串向量,雖然名字一樣,但内容完全不同,感興趣的讀者可以單獨運作example來對比其差別所在。formJSON示例代碼如下:
當參數simplifyVector被指定為假時,傳回結果為一個包含4個元素的清單。4個元素即代表共有4個值,每一個值都以清單的形式傳回。當JSON格式的原始資料檔案有多重嵌套時,可以通過設定參數來檢視資料結構和正确讀取資料。不過,一般情況下還是建議讀者使用非嵌套資料來練習和使用R語言與JSON格式資料進行互動,待有一定了解後再提高難度。傳回結果如下:
1.8 foreign package統計軟體資料
在世界範圍内,開源的資料分析工具正在逐漸取代傳統資料分析軟體,例如SAS、SPSS。在這一過程中,foreign包可以讓我們無縫連接配接以傳統分析軟體格式儲存的資料。該包也是集讀取和寫入于一體。因為開源統計分析軟體在世界範圍内不可逆轉的上升勢頭,傳統分析軟體的使用頻率越來越低,其資料格式也漸漸被邊緣化,本節隻列出讀取相應拓展名所需的函數(表1-18)以備讀者不時之需,而不會做進一步的代碼示範。
1.9 本章小結
本章我們着重讨論了常見的平面檔案和Excel檔案的讀取,包括在處理規則資料及不規則資料時函數和參數的選擇。同時,本章還介紹了其他檔案格式的讀取,以及相應函數的參數設定。圖1-2總結了本章讨論過的主要程式包,希望讀者在日常練習和工作中遇到不同格式的檔案時,能夠瞬間反應出讀取該格式所需的包及對應的函數。
第2章将會幫助讀者點亮資料分析中的第二個關鍵步驟—資料清理。