1. 程式人生 > >R語言讀取Excel

R語言讀取Excel

因為一個專案需要,原始資料全部是Excel檔案,包括.xls和.xlsx格式,並且很多excel資料的格式並不規範,一個個轉為csv格式不太現實,所以把所有能瞭解到的讀取excel的方法都試了一遍,做個簡單彙總。

相關的包:RODBC、xlsx、openxlsx、gdata、readxl,測試平臺win7。

RODBC包-相關方法

RODBC-odbcConnectExcel2007()、odbcConnectExcel()、sqlFech()、sqlTables()

安裝

[plain] view plain copy print?
  1. install.packages(“RODBC”, dependencies=TRUE) #可能需要安裝一些依賴包  
install.packages(“RODBC”, dependencies=TRUE) #可能需要安裝一些依賴包

使用方法

[plain] view plain copy print?
  1. #64位機下,.xls和.xlsx檔案用相同方法  
  2. library(RODBC)  
  3. con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法  
  4. sqlTables(con) #檢視該xlsx檔案中有哪些表  
  5. #           TABLE_CAT TABLE_SCHEM TABLE_NAME   TABLE_TYPE REMARKS  
  6. # 1 D:\\R\\RODBC.xlsx        <NA>  商品資訊$ SYSTEM TABLE    <NA>  
  7. # 2 D:\\R\\RODBC.xlsx        <NA>  補充說明$ SYSTEM TABLE    <NA>  
  8. # 3 D:\\R\\RODBC.xlsx        <NA>  銷售資訊$ SYSTEM TABLE    <NA>  
  9. table_test <- sqlFetch(con,"銷售資訊")  
  10. table_test  
  11. odbcClose(con)  
#64位機下,.xls和.xlsx檔案用相同方法
library(RODBC)
con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法
sqlTables(con) #檢視該xlsx檔案中有哪些表
#           TABLE_CAT TABLE_SCHEM TABLE_NAME   TABLE_TYPE REMARKS
# 1 D:\\R\\RODBC.xlsx        <NA>  商品資訊$ SYSTEM TABLE    <NA>
# 2 D:\\R\\RODBC.xlsx        <NA>  補充說明$ SYSTEM TABLE    <NA>
# 3 D:\\R\\RODBC.xlsx        <NA>  銷售資訊$ SYSTEM TABLE    <NA>
table_test <- sqlFetch(con,"銷售資訊")
table_test
odbcClose(con)

[plain] view plain copy print?
  1. #32位機下,.xls和.xlsx檔案主要在方法odbcConnectExcel2007()和odbcConnectExcel()的差異,其餘方法相同  
  2. con <- odbcConnectExcel ("D:/R/RODBC.xlsx") #  
  3. sqlTables(con) #檢視該xlsx檔案中有哪些表  
  4. table_test <- sqlFetch(con,"銷售資訊")  
  5. odbcClose(con)  
#32位機下,.xls和.xlsx檔案主要在方法odbcConnectExcel2007()和odbcConnectExcel()的差異,其餘方法相同
con <- odbcConnectExcel ("D:/R/RODBC.xlsx") #
sqlTables(con) #檢視該xlsx檔案中有哪些表
table_test <- sqlFetch(con,"銷售資訊")
odbcClose(con)

優缺點說明

RODBC主要是讀取資料庫的包,是我接觸到的讀取Excel中效率最高的。並且還有sqlQuery方法可以寫SQL靈活讀取資料。並且能夠同時讀取.xls和.xlsx檔案。.

在簡單比較了各種方法後,覺得RODBC真是神器,並且沒有各種亂七八糟的限制,於是歡快地選擇了它,事實證明它的確是又快又爽,可是也隱藏了許多潛在的坑爹特性,不深入瞭解根本沒辦法發現。如果你有幸看到,說不定可以提前繞過某些坑,或者無法繞過,只能另擇新歡。

坑No1.

必須通過Sheet名讀取表,一個Excel檔案裡面可能有多個sheet表,所以你要讀取其中某張表,或者所有表,必須提前知道每張表的表名。如下圖中的”銷售資訊”、”商品資訊”、”補充說明”。此坑影響不大,並且用sqlTables可以查到表名,可以解決這個問題。

[plain] view plain copy print?
  1. #在表結構相同的情況下,讀取所有的表內容  
  2. con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法  
  3. tbls <- sqlTables(con)  
  4. table_test <- sqlFetch(con, tbls$TABLE_NAME[3])  
  5. odbcClose(con)  
#在表結構相同的情況下,讀取所有的表內容
con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法
tbls <- sqlTables(con)
table_test <- sqlFetch(con, tbls$TABLE_NAME[3])
odbcClose(con)

坑No2.

當某一列有不同型別的數值時,就悲劇了,如下例子中,用RODBC讀入不能指定讀入資料的格式,所以按照Excel預設格式讀取資料時,就會出現一列中型別不統一的值為NA。此坑用RODBC無解,只能另擇其他。

如下,測試資料中,區域專案是字元,其餘欄位為數值或日期。下圖左邊是excel檔案中的內容,右邊是讀入結果。

[plain] view plain copy print?
  1. library(RODBC)  
  2. con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法  
  3. table_test3 <- sqlFetch(con,"補充說明")  
  4. table_test3  
  5. odbcClose(con)  
library(RODBC)
con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法
table_test3 <- sqlFetch(con,"補充說明")
table_test3
odbcClose(con)


坑No3.

這也是一個不用不知道的坑,RODBC讀取Excel檔案在資料列較多時,多出的列可能被忽略,RODBC讀取極限是255列(沒有找到官方的說明,只是我的測試結果)。此坑用RODBC同樣無解,只能另擇其他。

如下,使用測試資料有380行280列,RODBC讀入後,是380行255列。

[plain] view plain copy print?
  1. library(RODBC)  
  2. con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法  
  3. table_test2 <- sqlFetch(con,"商品資訊")  
  4. odbcClose(con)  
library(RODBC)
con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法
table_test2 <- sqlFetch(con,"商品資訊")
odbcClose(con)

xlsx包-相關方法

xlsx-read.xlsx()、read.xlsx2()

安裝

install.packages(“xlsx”) #需要已經安裝rJava包

使用方法

[plain] view plain copy print?
  1. library(xlsx)  
  2. table_test <- read.xlsx("D:/R/xlsx.xlsx",1, encoding="UTF-8")  
  3. table_test1 <- read.xlsx("D:/R/xlsx.xls",1, encoding="UTF-8")  
  4. table_test2 <- read.xlsx2("D:/R/xlsx.xlsx",1, test="UTF-8") #預設讀入列為character,可自定義新的列。  
library(xlsx)
table_test <- read.xlsx("D:/R/xlsx.xlsx",1, encoding="UTF-8")
table_test1 <- read.xlsx("D:/R/xlsx.xls",1, encoding="UTF-8")
table_test2 <- read.xlsx2("D:/R/xlsx.xlsx",1, test="UTF-8") #預設讀入列為character,可自定義新的列。

優缺點說明

優點很明顯,上面的例子很完美解決了上面RODBC的坑No2.,同時可以讀取.xls檔案。此外,xlsx還有write.xlsx()系列方法,讀寫兼具,有需要的可以檢視說明文件。
坑No1.
缺點也非常明顯,就是效率極低,讀取資料時間長並且稍大的資料集就可能出現記憶體不夠用的問題。下面的例子就是用RODBC和xlsx的方法分別讀取同一個excel檔案所用時間,RODBC的優勢很明顯,測試資料1340行3列。

[plain] view plain copy print?
  1. library(RODBC)  
  2. con <- odbcConnectExcel2007("D:/R/ceshi.xlsx")  
  3. system.time(table_test <- sqlFetch(con,"Sheet1"))  
  4. odbcClose(con)  
  5. library(xlsx)  
  6. system.time(table_test <- read.xlsx("D:/R/ceshi.xlsx",1, encoding="UTF-8"))  
library(RODBC)
con <- odbcConnectExcel2007("D:/R/ceshi.xlsx")
system.time(table_test <- sqlFetch(con,"Sheet1"))
odbcClose(con)
library(xlsx)
system.time(table_test <- read.xlsx("D:/R/ceshi.xlsx",1, encoding="UTF-8"))

坑No2.

容易出現記憶體不夠用的問題。用xlsx的方法讀取前面用到測試RODBC的資料表,結果,錯誤資訊就是OutOfMemory。

openxlsx包-主要方法

openxlsx-read.xlsx()

安裝

install.packages("openxlsx")

使用方法

[plain] view plain copy print?
  1. library(openxlsx)  
  2. table_test <- read.xlsx("D:/R/xlsx.xlsx",1)  
  3. table_test1 <- read.xlsx("D:/R/xlsx.xls",1)  
library(openxlsx)
table_test <- read.xlsx("D:/R/xlsx.xlsx",1)
table_test1 <- read.xlsx("D:/R/xlsx.xls",1)


優缺點說明

優點與xlsx包中的方法一樣,不會出現RODBC的坑No2.的問題。此外,讀取ceshi.xlsx所花費時間比RODBC稍長,但相比xlsx快了許多。並且同樣有write.xlsx()方法,讀寫兼具。

[plain] view plain copy print?
  1. system.time(table_test <- read.xlsx("D:/R/ceshi.xlsx",1))  
system.time(table_test <- read.xlsx("D:/R/ceshi.xlsx",1))

坑No1.

缺點很大的一個,見上面的使用方法,不能讀取.xls檔案。

gdata包-相關方法

gdata-read.xls()

安裝

[plain] view plain copy print?
  1. install.packages("gdata")  #電腦已安裝Perl  
install.packages("gdata")  #電腦已安裝Perl

使用方法

[plain] view plain copy print?
  1. library(gdata)  
  2. table_test <- read.xls("D:/R/xlsx.xlsx",1, fileEncoding="UTF-8",sep=",") #xlsx檔案  
  3. table_test1 <- read.xls("D:/R/xlsx.xls",1, fileEncoding="UTF-8",sep=",") #xls檔案  
library(gdata)
table_test <- read.xls("D:/R/xlsx.xlsx",1, fileEncoding="UTF-8",sep=",") #xlsx檔案
table_test1 <- read.xls("D:/R/xlsx.xls",1, fileEncoding="UTF-8",sep=",") #xls檔案

優缺點說明

優點同樣,不會有RODBC的兩個問題。效率用同樣的ceshi.xlsx檔案來做測試,可以看到花費時間優於xlsx。同時可以讀取.xlsx和.xls檔案。

[plain] view plain copy print?
  1. system.time(table_test <- read.xls("D:/R/ceshi.xlsx",1, fileEncoding="UTF-8",sep=","))  
system.time(table_test <- read.xls("D:/R/ceshi.xlsx",1, fileEncoding="UTF-8",sep=","))

坑No1.

gdata是基於Perl的,所以存在因為Perl而可能出現的問題。讀取中文字元時,可能會出現“Wide character in print”的提醒資訊。這是由於perl只能處理兩種編碼:ascii碼和utf-8。ascii碼是很少的,像中文、日文、韓文等字元要想能被perl處理,只能用 utf-8編碼方式。

下面就是我在讀取某個Excel檔案時,輸出的log檔案。log檔案裡面基本上全部是這樣的提醒。

readxl包-相關方法

readxl-read_excel()

安裝

[plain] view plain copy print?
  1. install.packages("readxl")  
install.packages("readxl")

使用方法

[plain] view plain copy print?
  1. library(readxl)  
  2. table_test <- read_excel ("D:/R/xlsx.xlsx",1, col_types =c("text","text")) #xlsx檔案  
  3. table_test1 <- read_excel ("D:/R/xlsx.xls",1, col_types = c("text","text")) #xls檔案  
library(readxl)
table_test <- read_excel ("D:/R/xlsx.xlsx",1, col_types =c("text","text")) #xlsx檔案
table_test1 <- read_excel ("D:/R/xlsx.xls",1, col_types = c("text","text")) #xls檔案

優缺點說明

優點同樣不存在RODBC的坑No1.和坑No2.,讀取效率利用ceshi.xlsx檔案測試,讀取比RODBC更高效。

[plain] view plain copy print?
  1. system.time(table_test <- read_excel("D:/R/xlsx.xlsx",1))  
system.time(table_test <- read_excel("D:/R/xlsx.xlsx",1))

坑No1.

見使用方法,不能讀取.xls檔案。

最後對同一個檔案,使用這五個包中的相關方法,對讀取結果做一個對比。可以看看這些包在效率和對Excel中一些特殊的資料格式的讀取結果。

[plain] view plain copy print?
  1. #gdata  
  2. library(gdata)  
  3. system.time(table_test <- gdata::read.xls("D:/R/ceshi.xlsx",2, fileEncoding="UTF-8",sep=","))  
  4. #RODBC  
  5. library(RODBC)  
  6. con <- odbcConnectExcel2007("D:/R/ceshi.xlsx") #64位機下方法  
  7. tbls <- sqlTables(con)  
  8. system.time(table_test1 <- sqlFetch(con, tbls$TABLE_NAME[2]))  
  9. odbcClose(con)  
  10. #xlsx  
  11. library(xlsx)  
  12. system.time(table_test2 <- xlsx::read.xlsx("D:/R/ceshi.xlsx",2,encoding="UTF-8"))  
  13. #openxlsx  
  14. library(openxlsx)  
  15. system.time(table_test3 <- openxlsx::read.xlsx("D:/R/ceshi.xlsx",2))  
  16. #readxl  
  17. library(readxl)  
  18. system.time(table_tes4 <- read_excel("D:/R/ceshi.xlsx",2))   
#gdata
library(gdata)
system.time(table_test <- gdata::read.xls("D:/R/ceshi.xlsx",2, fileEncoding="UTF-8",sep=","))
#RODBC
library(RODBC)
con <- odbcConnectExcel2007("D:/R/ceshi.xlsx") #64位機下方法
tbls <- sqlTables(con)
system.time(table_test1 <- sqlFetch(con, tbls$TABLE_NAME[2]))
odbcClose(con)
#xlsx
library(xlsx)
system.time(table_test2 <- xlsx::read.xlsx("D:/R/ceshi.xlsx",2,encoding="UTF-8"))
#openxlsx
library(openxlsx)
system.time(table_test3 <- openxlsx::read.xlsx("D:/R/ceshi.xlsx",2))
#readxl
library(readxl)
system.time(table_tes4 <- read_excel("D:/R/ceshi.xlsx",2)) 

原始資料表


gdata讀入結果


RODBC讀入結果


xlsx讀入結果


openxl讀入結果


readxl讀入結果


可以說沒有完美的方法。

綜上,對Excel資料分析的基本原則:

1.      能轉化成csv格式,請儘量這樣做,這個才是最高效的選擇。

2.      1無法達到的情況下,小資料量,並且資料格式比較統一的情況下優先選擇RODBC。

3.      非.xls檔案時,優先選擇readxl、openxlsx。

4.      同時需要讀寫操作,xlsx(效率較低,對記憶體要求高)或者openxlsx。