'一文看懂用R語言讀取Excel、PDF和JSON文件(附代碼)'

"

導讀:本文將討論Excel、PDF等文件的讀取,以及相應函數的參數設置。

作者:劉健 鄔書豪

如需轉載請聯繫華章科技

下圖總結了主要程序包,希望讀者在日常練習和工作中遇到不同格式的文件時,能夠瞬間反應出讀取該格式所需的包及對應的函數。(限於篇幅,本文未包含圖中“平面文檔格式”這部分的內容,如果你有興趣,可以繼續關注大數據後續文章。)


"

導讀:本文將討論Excel、PDF等文件的讀取,以及相應函數的參數設置。

作者:劉健 鄔書豪

如需轉載請聯繫華章科技

下圖總結了主要程序包,希望讀者在日常練習和工作中遇到不同格式的文件時,能夠瞬間反應出讀取該格式所需的包及對應的函數。(限於篇幅,本文未包含圖中“平面文檔格式”這部分的內容,如果你有興趣,可以繼續關注大數據後續文章。)


一文看懂用R語言讀取Excel、PDF和JSON文件(附代碼)

▲不同格式的數據文件讀取所用的R包

01 readxl:Excel文件讀取

readxl是微軟Excel文件讀取的必備R包,是Hadley Wickham、Jennifer Bryan以及其他6名成員合作完成的經典程序包之一。

值得一提的是,該包的開發者之一兼實際維護者Jennifer Bryan(網絡上多稱她為Jenny Bryan),可以稱得上是與Hadley齊名且為數不多的女性R語言神級人物。可能是因為其身為大學教授,因此她總能夠用很生動有趣的方式將複雜的問題簡化成通俗易懂的知識傳遞給“小白”,強烈建議有英文基礎的讀者能夠蒐集一些她的主題演講或者書籍。

更新後的readxl包中雖然也還是隻有5個函數,不過功能卻比以前的版本更強大了。對於起初的版本,數據會被讀取成常見的data.frame格式,而對於現在的版本,讀取後的數據集格式則為tibble,可以理解為提升版的data.frame。

readxl包括兩個探測性函數excel_format和excel_sheets,一個引用例子的函數readxl_example,新加入的讀取特定單元格的函數cell-specification以及最重要的read_excel函數。本節將著重討論read_excel的參數設置及用法技巧。

數據導入函數read_excel主要參數及功能對照:

  • path
  • 數據文件路徑+文件名,也可以是一個url
  • sheet
  • 工作表序號或名稱,默認值為第一個工作表
  • range
  • 讀取指定區間,可以限定函數讀取原始Excel文件的範圍,例如,“A1:D100”會讀取這個區間中的所有單元格,包括空白單元格。“工作表1!A1:D100”會讀取名為“工作表1”中的該區間。這個參數的優先級高於參數 'skip'、'n_max'、'sheet'
  • col_names
  • 該參數具有三個選擇,具體如下。
  • 1)為真(TRUE),原始數據文件的第一行被用作列名,且不在數據集內。
  • 2)為假(FALSE),數據列名被自動賦值成X__1、X__2、X__3等。
  • 3)自定義字符串向量傳給參數。此時字符串向量會被用作列名,而原數據文件的第一列將被保存到數據集的第一列。如果有默認列名的話,則會發出警告,並自動賦值成X1、X2、X3等,但不會影響讀取進程。重複的列名也會發出警告,並且會在重複列名前加數字序號以做區分
  • col_types
  • 列數據類型。可以有兩種傳參形式,具體如下。
  • 1)NULL,默認值。函數會自動解析每一列數據的類型。
  • 2)指定變量類型。字符串參照為:"skip"、"guess"、"logical"、"numeric"、"date"、"text"或"list"。需要注意的是,如果僅指定一個數據類型(例如,"numeric")那麼所有的變量都會被讀成字符型數據。如果指定一列為"skip",那麼這一列就不會被讀取到R中來。新增加的"list"屬性對處理有經緯度的變量列將會有很大幫助
  • na
  • 原始數據文件中是否有一些字符需要用na來代替。空白單元格被默認作為默認值
  • trim_ws
  • 每個數據值前後的空白是否處理掉,取值為真或假
  • skip
  • 是否跳過幾行讀取原始數據文件,默認取值為0,表示不跳過;可以傳參任意數字
  • n_max
  • 最大讀取行數

首先還是需要加載readxl包。儘管Hadley從2017年開始就一直在網絡上宣傳這個包已經屬於tidyverse的一部分,但用戶還是必須手動單獨加載這個包。加載readxl包代碼如下:

> library(readxl)

readxl包自帶示範文件,使用函數readxl_example可以查看文件名字,以及獲取文件路徑,代碼如下:

 > readxl_example()
[1] "clippy.xls" "clippy.xlsx" "datasets.xls" "datasets.xlsx"
[5] "deaths.xls" "deaths.xlsx" "geometry.xls" "geometry.xlsx"
[9] "type-me.xls" "type-me.xlsx"

獲取示例文件的路徑,可以先複製readxl_example函數運行後的結果,然後將其粘貼到read_excel函數的path參數中。

下面的代碼演示函數嵌套的方法,這種嵌套的代碼書寫方式能夠在一定程度上簡化代碼和減少命名中間產物的頻率。不過嵌套過多會使可讀性變差,一般推薦只嵌套兩層。將讀取後的數據保存在iris中,執行str函數之後將會發現除了經典的data.frame之外,數據集還有另外兩種類別,tbl_df和tbl。函數嵌套的示例代碼如下:

 > iris <- read_excel(path = readxl_example(path = "datasets.xlsx"))
> str(iris)
## Classes 'tbl_df', 'tbl' and 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : chr "setosa" "setosa" "setosa" "setosa" ...

之所以命名為iris,是因為這個範例Excel文件中的第一個工作表就是該經典數據集。函數excel_sheets可用於查詢同一個文件中的工作表名稱,其實現代碼具體如下:

> excel_sheets(path = readxl_example(path = "datasets.xlsx"))
## [1] "iris" "mtcars" "chickwts" "quakes"

在datasets.xlsx中一共存在4個工作表,其中包含了4個最經典的R語言練習數據集。在此,希望讀者可以自行瀏覽這幾個數據集,對數據集的格式、變量名稱等情況有一定程度的瞭解。

增加參數sheet或range可以讀取指定工作表中的數據。這裡需要注意的是,上文提到了參數優先級的問題。對於一般常見的練習數據集,sheet參數指定的工作表已足夠勝任。讀者只需要記住range參數可以用來處理特殊情況,也就是說,當設置sheet後依然對讀取到的數據不滿意的情況可以考慮使用range。

下面的代碼演示了sheet的兩種傳參方式:位置序號和名稱。推薦讀者採用後者。因為工作表被意外拖拽導致位置調換的情況常有發生,而位置意外發生調換之後讀取的數據也會不同,這就增加了代碼崩潰的風險。如果使用名稱,則會降低發生錯誤的機率。示例代碼如下:

> mtcars <- read_excel(path = readxl_example(path = "datasets.xlsx"),sheet = 2)
> mtcars <- read_excel(path = readxl_example(path = "datasets.xlsx"),sheet = "mtcars")

對於後面的參數,讀者可以根據上文的解釋,每次增加一個參數,來逐步掌握每一個參數的功能,這裡不再贅述。

02 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則是用來將數據庫中的數據保存到本地。加載代碼具體如下:

> library(DBI)
> library(dplyr)
> library(RPostgreSQL)

不同類型的數據庫可能需要調整dbConnect中的參數,具體調整方法讀者可以參見幫助文檔。數據庫服務器地址、名稱、權限等信息需要輸入到單引號中,請一定留意是否有空格符號不小心被複制或者因誤操作輸入其中。如果擔心密碼洩露的話,則可以使用RStudio中自帶的密碼彈窗功能。

dbListTables函數可以用來查詢數據庫中的詳細內容,並以字符串向量的格式返回,如果數據庫中無內容,則會返回空值。調整dbConnect參數的示例代碼如下:

 > db_connect <- dbConnect(
RPostgreSQL::PostgreSQL(),
dbname = '數據庫名稱',
host = '服務器地址',
user = '用戶名',
password = "密碼")
> dbListTables(db_connect)
## [1] "MetaData" "Table1" "Table2"

優化後的tbl函數可以直接調取已經建立連接的數據庫中的指定數據,並保存為tibble格式的數據集。下面的代碼中,逗號後面的參數也可以用“Table1”或“Table2”來表示:

> tbl(src = db_connect, dbListTables(db_connect)[1])

數據庫交互的有關內容完全可以獨立成書,這裡我們只介紹了最簡單的基本用法,以使大家對如何使用R來查詢數據庫有個最基本的印象。

03 pdftools:PDF文件

學術期刊、網絡雜誌和電子書籍一般都會以PDF格式的文件呈現。一般的計量型數據分析很少會遇到讀取PDF文件的情況,不過在進行文本挖掘(Text Mining)和主題模型(Topic Modelling)預測中,pdftools包絕對是必備R包之一。

該包只有兩個母函數,一個用來從PDF中提取數據(此處的數據包括數字型和文字型數據),另一個則用來將文件渲染成PDF格式。本節我們只討論第一個母函數——pdf_info。

pdf_info函數下面一共包含6個子函數,功能各不相同。但是6個子函數的參數完全一致,分別是pdf、opw和upw。

數據導入函數'pdf_info子函數一覽:

  • pdf_info:讀取PDF文件的基本信息,例如,何時創建、更改,版本信息,是否有密碼,頁數等,詳見代碼演示部分
  • pdf_text:提取文件中的所有文字或非文字信息,包括分頁符、換行符
  • pdf_data:提取數字型數據,這個提取的結果會因PDF文件而異,有時可以直接將期刊中的數據完整地提取出來,有時又會因為PDF文檔在創建時使用了不一致的分隔符而導致數據提取不完整
  • pdf_fonts:提取文檔的字體信息
  • pdf_attachments:提取文檔附件
  • pdf_toc:提取文檔目錄

數據導入函數'pdf_info參數詳解:

  • pdf:PDF文件路徑,可以是網絡鏈接
  • opw:PDF文件所有者的密碼
  • upw:PDF文件用戶的密碼

由於篇幅有限,下面的代碼只截取了部分結果進行解釋。這裡所用的PDF文檔是pdftools包的幫助文檔,讀者可以自行到R官網上搜索下載。幫助文檔是開放PDF文件,無須提供密碼。讀取文檔代碼如下:

 > library(pdftools)
> pdf_info(pdf = "./helpDocs/pdftools.pdf")
## $version
## [1] "1.5"
##
## $pages
## [1] 5
...

當使用pdf_text提取文檔內容時,全部內容都被提取為一個字符串向量,每頁的內容都被單獨放置於一個字符串中。幫助文檔的PDF格式一共包含5頁,所以這裡會得到一個長度為5的字符串向量。

有兩種方式可用於查看提取的文本:可以直接將結果顯示在console中(通過執行print(text)或直接運行text),也可以通過“[ ]”來指定顯示某一頁的內容。空白的位置都會以空格的字符格式顯示,“\\r\\n”代表換行符號。提取文檔內容的代碼如下:

 > text<- pdf_text("./helpDocs/pdftools.pdf")
> length(text)
## [1] 5
> class(text)
## [1] "character"
> text[1]
## [1] " Package ‘pdftools’\\r\\n May 27, 2018\\r\\nType Package\\r\\nTitle Text Extraction, Rendering and Converting of PDF Documents\\r\\nVersion 1.8\\r\\nDescription Utilities based on 'libpoppler' for extracting text, fonts, attachments and\\r\\n

該文檔無附件,所以會顯示一個空列表:

> pdf_attachments(pdf = "./helpDocs/pdftools.pdf")
## list()

文檔中一共包含了6種字體,pdf_fonts會給出字體的名稱、類型、是否嵌入文檔中這三類信息,具體如下:

 > pdf_fonts(pdf = "./helpDocs/pdftools.pdf")
## name type embedded file
## 1 DSHWTW+NimbusRomNo9L-Medi type1 TRUE
## 2 UTHPMJ+NimbusRomNo9L-Regu type1 TRUE
## 3 DSQFGA+Inconsolata-zi4r type1 TRUE
## 4 LVIJIF+NimbusSanL-Regu type1 TRUE
## 5 DQRZJT+NimbusRomNo9L-Regu-Slant_167 type1 TRUE
## 6 YIECHJ+NimbusRomNo9L-ReguItal type1 TRUE

目錄讀取的子函數會將所讀取的內容返回到一個列表中,如果直接將該列表顯示在console中很可能會讓人感覺不知所云,讀者可以自行實踐。最好的辦法是將讀取的內容使用jsonlite包轉換成json列表的格式進行顯示,以幫助理解文檔的架構。jsonlite包轉換成json列表的示例代碼如下:

 > jsonlite::toJSON(x = pdf_toc(pdf = "./helpDocs/pdftools.pdf"), pretty = TRUE)
## {
## "title": "",
## "children": [
## {
## "title": "pdf_info",
## "children": []
## },
## {
## "title": "pdf_render_page",
## "children": []
## },
## {
## "title": "Index",
## "children": []
## }
## ]
## }

04 jsonlite:JSON文件

JavaScript Object Notation(JSON)通常是作為不同語言之間互相交流信息的文件,JSON文件不但節省存儲空間,其簡潔明瞭的形式也很容易理解。

jsonlite包既能夠完整地將JSON格式的文件完整地解析和讀取到R語言中來,也可以將任何常見的R對象(object)輸出成JSON格式。本文03節中,toJSON函數可用來將PDF文檔目錄轉換成JSON格式,以便於理解各層級之間的關係。

讀取JSON文件的fromJSON函數共包含6個參數,通常情況下,除了指定文件路徑之外,其他參數使用默認設置即可。

數據導入函數fromJSON參數詳解:

  • txt:可以是一段JSON格式的字符串,網絡鏈接或者文件路徑加文件名
  • simplifyVector:將有序數組中的原始值強制轉置成原子向量,可以簡單理解為只保留數據,有真假兩種設置,默認為真,如果設置為假,則數據會被讀取為一個列表,列表中會包含子列表,子列表中會列出變量名和相應的數據值。詳見代碼演示部分
  • simplifyDataFrame:將JSON數組中的記錄強制轉換成數據集(data frame)
  • simplifyMatrix:將JSON數組中的向量強制轉換成矩陣或數組
  • flatten:自動將嵌套的數據集轉換成非嵌套的平面數據集
  • …:設置顯示方法

首先以JSON常見的數組形式創建一個字符串向量,保存為example。中括號代表數組的起始,雙引號中代表值,值與值之間以逗號進行分隔,然後再用單引號將這一數組格式保存到字符串向量中。因為example中的數組是按照JSON格式輸入的,所以直接使用fromJSON函數即可。

在默認的參數設置下,可以得到一個包含4個值的R對象—字符串向量。運行fromJSON前後的這兩個字符串向量,雖然名字一樣,但內容完全不同,感興趣的讀者可以單獨運行example來對比其區別所在。formJSON示例代碼如下:

 > example <- '["a", "b", 0, "c"]'
> fromJSON(example)
## [1] "a" "b" "0" "c"

當參數simplifyVector被指定為假時,返回結果為一個包含4個元素的列表。4個元素即代表共有4個值,每一個值都以列表的形式返回。

當JSON格式的原始數據文件有多重嵌套時,可以通過設置參數來查看數據結構和正確讀取數據。不過,一般情況下還是建議讀者使用非嵌套數據來練習和使用R語言與JSON格式數據進行交互,待有一定了解後再提高難度。返回結果如下:

 > fromJSON(example,simplifyVector = F)
## [[1]]
## [1] "a"
##
## [[2]]
## [1] "b"
##
## [[3]]
## [1] 0
##
## [[4]]
## [1] "c"

05 foreign package統計軟件數據

在世界範圍內,開源的數據分析工具正在逐步取代傳統數據分析軟件,例如SAS、SPSS。在這一過程中,foreign包可以讓我們無縫連接以傳統分析軟件格式保存的數據。該包也是集讀取和寫入於一體。

因為開源統計分析軟件在世界範圍內不可逆轉的上升勢頭,傳統分析軟件的使用頻率越來越低,其數據格式也漸漸被邊緣化,本節只列出讀取相應拓展名所需的函數以備讀者不時之需,而不會做進一步的代碼演示。

數據導入程序包foreign中數據讀取函數及對應讀取文件一覽:

  • .xpt:lookup.xport
  • ARFF files:read.arff
  • .dbf:read.dbf
  • Stata Binary Files:read.dta
  • .rec:read.epiinfo
  • .mtp:read.mtp
  • .sav:read.spss
  • .syd:read.systat

關於作者:劉健,資深R語言技術專家,數據科學工程師。在新西蘭皇家植物與食品研究院工作,參與一項國際和兩項國家的級別研究項目,使用R語言開發完成氣象數據自動提取和模型文件自動化工具。獨立開發完成R語言程序包一個。

鄔書豪,資深R語言用戶和數據分析工程師,是數據科學領域10萬粉絲的知名公眾號人工智能愛好者社區的負責人,公眾號文章閱讀量破百萬。喜歡用SQL、R和Python解決工作中的數據科學問題,致力於成為一名有深度行業實踐經驗積累的數據科學家。

本文摘編自《R數據科學實戰:工具詳解與案例分析》,經出版方授權發佈。

"

導讀:本文將討論Excel、PDF等文件的讀取,以及相應函數的參數設置。

作者:劉健 鄔書豪

如需轉載請聯繫華章科技

下圖總結了主要程序包,希望讀者在日常練習和工作中遇到不同格式的文件時,能夠瞬間反應出讀取該格式所需的包及對應的函數。(限於篇幅,本文未包含圖中“平面文檔格式”這部分的內容,如果你有興趣,可以繼續關注大數據後續文章。)


一文看懂用R語言讀取Excel、PDF和JSON文件(附代碼)

▲不同格式的數據文件讀取所用的R包

01 readxl:Excel文件讀取

readxl是微軟Excel文件讀取的必備R包,是Hadley Wickham、Jennifer Bryan以及其他6名成員合作完成的經典程序包之一。

值得一提的是,該包的開發者之一兼實際維護者Jennifer Bryan(網絡上多稱她為Jenny Bryan),可以稱得上是與Hadley齊名且為數不多的女性R語言神級人物。可能是因為其身為大學教授,因此她總能夠用很生動有趣的方式將複雜的問題簡化成通俗易懂的知識傳遞給“小白”,強烈建議有英文基礎的讀者能夠蒐集一些她的主題演講或者書籍。

更新後的readxl包中雖然也還是隻有5個函數,不過功能卻比以前的版本更強大了。對於起初的版本,數據會被讀取成常見的data.frame格式,而對於現在的版本,讀取後的數據集格式則為tibble,可以理解為提升版的data.frame。

readxl包括兩個探測性函數excel_format和excel_sheets,一個引用例子的函數readxl_example,新加入的讀取特定單元格的函數cell-specification以及最重要的read_excel函數。本節將著重討論read_excel的參數設置及用法技巧。

數據導入函數read_excel主要參數及功能對照:

  • path
  • 數據文件路徑+文件名,也可以是一個url
  • sheet
  • 工作表序號或名稱,默認值為第一個工作表
  • range
  • 讀取指定區間,可以限定函數讀取原始Excel文件的範圍,例如,“A1:D100”會讀取這個區間中的所有單元格,包括空白單元格。“工作表1!A1:D100”會讀取名為“工作表1”中的該區間。這個參數的優先級高於參數 'skip'、'n_max'、'sheet'
  • col_names
  • 該參數具有三個選擇,具體如下。
  • 1)為真(TRUE),原始數據文件的第一行被用作列名,且不在數據集內。
  • 2)為假(FALSE),數據列名被自動賦值成X__1、X__2、X__3等。
  • 3)自定義字符串向量傳給參數。此時字符串向量會被用作列名,而原數據文件的第一列將被保存到數據集的第一列。如果有默認列名的話,則會發出警告,並自動賦值成X1、X2、X3等,但不會影響讀取進程。重複的列名也會發出警告,並且會在重複列名前加數字序號以做區分
  • col_types
  • 列數據類型。可以有兩種傳參形式,具體如下。
  • 1)NULL,默認值。函數會自動解析每一列數據的類型。
  • 2)指定變量類型。字符串參照為:"skip"、"guess"、"logical"、"numeric"、"date"、"text"或"list"。需要注意的是,如果僅指定一個數據類型(例如,"numeric")那麼所有的變量都會被讀成字符型數據。如果指定一列為"skip",那麼這一列就不會被讀取到R中來。新增加的"list"屬性對處理有經緯度的變量列將會有很大幫助
  • na
  • 原始數據文件中是否有一些字符需要用na來代替。空白單元格被默認作為默認值
  • trim_ws
  • 每個數據值前後的空白是否處理掉,取值為真或假
  • skip
  • 是否跳過幾行讀取原始數據文件,默認取值為0,表示不跳過;可以傳參任意數字
  • n_max
  • 最大讀取行數

首先還是需要加載readxl包。儘管Hadley從2017年開始就一直在網絡上宣傳這個包已經屬於tidyverse的一部分,但用戶還是必須手動單獨加載這個包。加載readxl包代碼如下:

> library(readxl)

readxl包自帶示範文件,使用函數readxl_example可以查看文件名字,以及獲取文件路徑,代碼如下:

 > readxl_example()
[1] "clippy.xls" "clippy.xlsx" "datasets.xls" "datasets.xlsx"
[5] "deaths.xls" "deaths.xlsx" "geometry.xls" "geometry.xlsx"
[9] "type-me.xls" "type-me.xlsx"

獲取示例文件的路徑,可以先複製readxl_example函數運行後的結果,然後將其粘貼到read_excel函數的path參數中。

下面的代碼演示函數嵌套的方法,這種嵌套的代碼書寫方式能夠在一定程度上簡化代碼和減少命名中間產物的頻率。不過嵌套過多會使可讀性變差,一般推薦只嵌套兩層。將讀取後的數據保存在iris中,執行str函數之後將會發現除了經典的data.frame之外,數據集還有另外兩種類別,tbl_df和tbl。函數嵌套的示例代碼如下:

 > iris <- read_excel(path = readxl_example(path = "datasets.xlsx"))
> str(iris)
## Classes 'tbl_df', 'tbl' and 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : chr "setosa" "setosa" "setosa" "setosa" ...

之所以命名為iris,是因為這個範例Excel文件中的第一個工作表就是該經典數據集。函數excel_sheets可用於查詢同一個文件中的工作表名稱,其實現代碼具體如下:

> excel_sheets(path = readxl_example(path = "datasets.xlsx"))
## [1] "iris" "mtcars" "chickwts" "quakes"

在datasets.xlsx中一共存在4個工作表,其中包含了4個最經典的R語言練習數據集。在此,希望讀者可以自行瀏覽這幾個數據集,對數據集的格式、變量名稱等情況有一定程度的瞭解。

增加參數sheet或range可以讀取指定工作表中的數據。這裡需要注意的是,上文提到了參數優先級的問題。對於一般常見的練習數據集,sheet參數指定的工作表已足夠勝任。讀者只需要記住range參數可以用來處理特殊情況,也就是說,當設置sheet後依然對讀取到的數據不滿意的情況可以考慮使用range。

下面的代碼演示了sheet的兩種傳參方式:位置序號和名稱。推薦讀者採用後者。因為工作表被意外拖拽導致位置調換的情況常有發生,而位置意外發生調換之後讀取的數據也會不同,這就增加了代碼崩潰的風險。如果使用名稱,則會降低發生錯誤的機率。示例代碼如下:

> mtcars <- read_excel(path = readxl_example(path = "datasets.xlsx"),sheet = 2)
> mtcars <- read_excel(path = readxl_example(path = "datasets.xlsx"),sheet = "mtcars")

對於後面的參數,讀者可以根據上文的解釋,每次增加一個參數,來逐步掌握每一個參數的功能,這裡不再贅述。

02 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則是用來將數據庫中的數據保存到本地。加載代碼具體如下:

> library(DBI)
> library(dplyr)
> library(RPostgreSQL)

不同類型的數據庫可能需要調整dbConnect中的參數,具體調整方法讀者可以參見幫助文檔。數據庫服務器地址、名稱、權限等信息需要輸入到單引號中,請一定留意是否有空格符號不小心被複制或者因誤操作輸入其中。如果擔心密碼洩露的話,則可以使用RStudio中自帶的密碼彈窗功能。

dbListTables函數可以用來查詢數據庫中的詳細內容,並以字符串向量的格式返回,如果數據庫中無內容,則會返回空值。調整dbConnect參數的示例代碼如下:

 > db_connect <- dbConnect(
RPostgreSQL::PostgreSQL(),
dbname = '數據庫名稱',
host = '服務器地址',
user = '用戶名',
password = "密碼")
> dbListTables(db_connect)
## [1] "MetaData" "Table1" "Table2"

優化後的tbl函數可以直接調取已經建立連接的數據庫中的指定數據,並保存為tibble格式的數據集。下面的代碼中,逗號後面的參數也可以用“Table1”或“Table2”來表示:

> tbl(src = db_connect, dbListTables(db_connect)[1])

數據庫交互的有關內容完全可以獨立成書,這裡我們只介紹了最簡單的基本用法,以使大家對如何使用R來查詢數據庫有個最基本的印象。

03 pdftools:PDF文件

學術期刊、網絡雜誌和電子書籍一般都會以PDF格式的文件呈現。一般的計量型數據分析很少會遇到讀取PDF文件的情況,不過在進行文本挖掘(Text Mining)和主題模型(Topic Modelling)預測中,pdftools包絕對是必備R包之一。

該包只有兩個母函數,一個用來從PDF中提取數據(此處的數據包括數字型和文字型數據),另一個則用來將文件渲染成PDF格式。本節我們只討論第一個母函數——pdf_info。

pdf_info函數下面一共包含6個子函數,功能各不相同。但是6個子函數的參數完全一致,分別是pdf、opw和upw。

數據導入函數'pdf_info子函數一覽:

  • pdf_info:讀取PDF文件的基本信息,例如,何時創建、更改,版本信息,是否有密碼,頁數等,詳見代碼演示部分
  • pdf_text:提取文件中的所有文字或非文字信息,包括分頁符、換行符
  • pdf_data:提取數字型數據,這個提取的結果會因PDF文件而異,有時可以直接將期刊中的數據完整地提取出來,有時又會因為PDF文檔在創建時使用了不一致的分隔符而導致數據提取不完整
  • pdf_fonts:提取文檔的字體信息
  • pdf_attachments:提取文檔附件
  • pdf_toc:提取文檔目錄

數據導入函數'pdf_info參數詳解:

  • pdf:PDF文件路徑,可以是網絡鏈接
  • opw:PDF文件所有者的密碼
  • upw:PDF文件用戶的密碼

由於篇幅有限,下面的代碼只截取了部分結果進行解釋。這裡所用的PDF文檔是pdftools包的幫助文檔,讀者可以自行到R官網上搜索下載。幫助文檔是開放PDF文件,無須提供密碼。讀取文檔代碼如下:

 > library(pdftools)
> pdf_info(pdf = "./helpDocs/pdftools.pdf")
## $version
## [1] "1.5"
##
## $pages
## [1] 5
...

當使用pdf_text提取文檔內容時,全部內容都被提取為一個字符串向量,每頁的內容都被單獨放置於一個字符串中。幫助文檔的PDF格式一共包含5頁,所以這裡會得到一個長度為5的字符串向量。

有兩種方式可用於查看提取的文本:可以直接將結果顯示在console中(通過執行print(text)或直接運行text),也可以通過“[ ]”來指定顯示某一頁的內容。空白的位置都會以空格的字符格式顯示,“\\r\\n”代表換行符號。提取文檔內容的代碼如下:

 > text<- pdf_text("./helpDocs/pdftools.pdf")
> length(text)
## [1] 5
> class(text)
## [1] "character"
> text[1]
## [1] " Package ‘pdftools’\\r\\n May 27, 2018\\r\\nType Package\\r\\nTitle Text Extraction, Rendering and Converting of PDF Documents\\r\\nVersion 1.8\\r\\nDescription Utilities based on 'libpoppler' for extracting text, fonts, attachments and\\r\\n

該文檔無附件,所以會顯示一個空列表:

> pdf_attachments(pdf = "./helpDocs/pdftools.pdf")
## list()

文檔中一共包含了6種字體,pdf_fonts會給出字體的名稱、類型、是否嵌入文檔中這三類信息,具體如下:

 > pdf_fonts(pdf = "./helpDocs/pdftools.pdf")
## name type embedded file
## 1 DSHWTW+NimbusRomNo9L-Medi type1 TRUE
## 2 UTHPMJ+NimbusRomNo9L-Regu type1 TRUE
## 3 DSQFGA+Inconsolata-zi4r type1 TRUE
## 4 LVIJIF+NimbusSanL-Regu type1 TRUE
## 5 DQRZJT+NimbusRomNo9L-Regu-Slant_167 type1 TRUE
## 6 YIECHJ+NimbusRomNo9L-ReguItal type1 TRUE

目錄讀取的子函數會將所讀取的內容返回到一個列表中,如果直接將該列表顯示在console中很可能會讓人感覺不知所云,讀者可以自行實踐。最好的辦法是將讀取的內容使用jsonlite包轉換成json列表的格式進行顯示,以幫助理解文檔的架構。jsonlite包轉換成json列表的示例代碼如下:

 > jsonlite::toJSON(x = pdf_toc(pdf = "./helpDocs/pdftools.pdf"), pretty = TRUE)
## {
## "title": "",
## "children": [
## {
## "title": "pdf_info",
## "children": []
## },
## {
## "title": "pdf_render_page",
## "children": []
## },
## {
## "title": "Index",
## "children": []
## }
## ]
## }

04 jsonlite:JSON文件

JavaScript Object Notation(JSON)通常是作為不同語言之間互相交流信息的文件,JSON文件不但節省存儲空間,其簡潔明瞭的形式也很容易理解。

jsonlite包既能夠完整地將JSON格式的文件完整地解析和讀取到R語言中來,也可以將任何常見的R對象(object)輸出成JSON格式。本文03節中,toJSON函數可用來將PDF文檔目錄轉換成JSON格式,以便於理解各層級之間的關係。

讀取JSON文件的fromJSON函數共包含6個參數,通常情況下,除了指定文件路徑之外,其他參數使用默認設置即可。

數據導入函數fromJSON參數詳解:

  • txt:可以是一段JSON格式的字符串,網絡鏈接或者文件路徑加文件名
  • simplifyVector:將有序數組中的原始值強制轉置成原子向量,可以簡單理解為只保留數據,有真假兩種設置,默認為真,如果設置為假,則數據會被讀取為一個列表,列表中會包含子列表,子列表中會列出變量名和相應的數據值。詳見代碼演示部分
  • simplifyDataFrame:將JSON數組中的記錄強制轉換成數據集(data frame)
  • simplifyMatrix:將JSON數組中的向量強制轉換成矩陣或數組
  • flatten:自動將嵌套的數據集轉換成非嵌套的平面數據集
  • …:設置顯示方法

首先以JSON常見的數組形式創建一個字符串向量,保存為example。中括號代表數組的起始,雙引號中代表值,值與值之間以逗號進行分隔,然後再用單引號將這一數組格式保存到字符串向量中。因為example中的數組是按照JSON格式輸入的,所以直接使用fromJSON函數即可。

在默認的參數設置下,可以得到一個包含4個值的R對象—字符串向量。運行fromJSON前後的這兩個字符串向量,雖然名字一樣,但內容完全不同,感興趣的讀者可以單獨運行example來對比其區別所在。formJSON示例代碼如下:

 > example <- '["a", "b", 0, "c"]'
> fromJSON(example)
## [1] "a" "b" "0" "c"

當參數simplifyVector被指定為假時,返回結果為一個包含4個元素的列表。4個元素即代表共有4個值,每一個值都以列表的形式返回。

當JSON格式的原始數據文件有多重嵌套時,可以通過設置參數來查看數據結構和正確讀取數據。不過,一般情況下還是建議讀者使用非嵌套數據來練習和使用R語言與JSON格式數據進行交互,待有一定了解後再提高難度。返回結果如下:

 > fromJSON(example,simplifyVector = F)
## [[1]]
## [1] "a"
##
## [[2]]
## [1] "b"
##
## [[3]]
## [1] 0
##
## [[4]]
## [1] "c"

05 foreign package統計軟件數據

在世界範圍內,開源的數據分析工具正在逐步取代傳統數據分析軟件,例如SAS、SPSS。在這一過程中,foreign包可以讓我們無縫連接以傳統分析軟件格式保存的數據。該包也是集讀取和寫入於一體。

因為開源統計分析軟件在世界範圍內不可逆轉的上升勢頭,傳統分析軟件的使用頻率越來越低,其數據格式也漸漸被邊緣化,本節只列出讀取相應拓展名所需的函數以備讀者不時之需,而不會做進一步的代碼演示。

數據導入程序包foreign中數據讀取函數及對應讀取文件一覽:

  • .xpt:lookup.xport
  • ARFF files:read.arff
  • .dbf:read.dbf
  • Stata Binary Files:read.dta
  • .rec:read.epiinfo
  • .mtp:read.mtp
  • .sav:read.spss
  • .syd:read.systat

關於作者:劉健,資深R語言技術專家,數據科學工程師。在新西蘭皇家植物與食品研究院工作,參與一項國際和兩項國家的級別研究項目,使用R語言開發完成氣象數據自動提取和模型文件自動化工具。獨立開發完成R語言程序包一個。

鄔書豪,資深R語言用戶和數據分析工程師,是數據科學領域10萬粉絲的知名公眾號人工智能愛好者社區的負責人,公眾號文章閱讀量破百萬。喜歡用SQL、R和Python解決工作中的數據科學問題,致力於成為一名有深度行業實踐經驗積累的數據科學家。

本文摘編自《R數據科學實戰:工具詳解與案例分析》,經出版方授權發佈。

一文看懂用R語言讀取Excel、PDF和JSON文件(附代碼)

延伸閱讀《R數據科學實戰:工具詳解與案例分析》

推薦語:這是一部能指導零基礎的讀者快速掌握R語言並利用R語言進入數據科學領域的著作。兩位作者在R語言和數據科學領域有豐富的實踐經驗,首先是非常有針對性地講解了利用R語言進行數據處理需要掌握和使用的6大類17種工具,然後是結合這些工具的使用給出了5個典型的綜合性案例,幫助讀者迅速將理論與實踐融會貫通。

"

相關推薦

推薦中...