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?- install.packages(“RODBC”, dependencies=TRUE) #可能需要安裝一些依賴包
install.packages(“RODBC”, dependencies=TRUE) #可能需要安裝一些依賴包
使用方法
[plain] view plain copy print?- #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)
#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?
- #32位機下,.xls和.xlsx檔案主要在方法odbcConnectExcel2007()和odbcConnectExcel()的差異,其餘方法相同
- con <- odbcConnectExcel ("D:/R/RODBC.xlsx") #
- sqlTables(con) #檢視該xlsx檔案中有哪些表
- table_test <- sqlFetch(con,"銷售資訊")
- 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?- #在表結構相同的情況下,讀取所有的表內容
- con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法
- tbls <- sqlTables(con)
- table_test <- sqlFetch(con, tbls$TABLE_NAME[3])
- 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?- library(RODBC)
- con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法
- table_test3 <- sqlFetch(con,"補充說明")
- table_test3
- 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?- library(RODBC)
- con <- odbcConnectExcel2007("D:/R/RODBC.xlsx") #64位機下方法
- table_test2 <- sqlFetch(con,"商品資訊")
- 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?- 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,可自定義新的列。
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列。
- 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"))
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?- library(openxlsx)
- table_test <- read.xlsx("D:/R/xlsx.xlsx",1)
- 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?- 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?- install.packages("gdata") #電腦已安裝Perl
install.packages("gdata") #電腦已安裝Perl
使用方法
[plain] view plain copy print?- 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檔案
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?- 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?- install.packages("readxl")
install.packages("readxl")
使用方法
[plain] view plain copy print?- 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檔案
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?- 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?- #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
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。