直接从R脚本读取Excel文件
我怎样才能直接读取一个Excel文件到R? 或者我应该首先将数据导出到文本或CSV文件并将该文件导入到R?
是。 请参阅R wiki上的相关页面 。 简而言之: gdata
包中的read.xls
在大多数情况下read.xls
的(尽pipe你需要在你的系统上安装Perl,通常在MacOS和Linux上都是如此,但是在Windows上需要额外的步骤,例如http:// strawberryperl.com/ )。 R维基页面上列出了各种注意事项和备选scheme。
我直接看到不这样做的唯一原因是,你可能想要检查电子表格,看看它是否有毛病(奇怪的标题,多个工作表[你一次只能阅读一个,虽然你可以明显地遍历它们] ,包括情节等)。 但是,对于一个格式正确的矩形电子表格,其中包含简单的数字和字符数据(即不是逗号格式的数字,date,带有零除误差的公式,缺失值等等)。我通常没有问题用这个过程。
让我重申@Chasebuild议:使用XLConnect 。
在我看来,使用XLConnect的原因是:
- 跨平台。 XLConnect是用Java编写的,因此可以在Win,Linux,Mac上运行,不会改变你的R代码(除了可能的pathstring)
- 没有别的要加载。 只需安装XLConnect并继续生活。
- 您只提到读取Excel文件,但XLConnect也将编写Excel文件,包括更改单元格格式。 它会从Linux或Mac,而不仅仅是Win。
与其他解决scheme相比,XLConnect有点新,因此在博客文章和参考文档中不多提及。 对我来说这非常有用。
编辑2015年10月:正如其他人在这里评论说, openxlsx
和readxl
软件包比xlsx
软件包快得多,实际上pipe理打开更大的Excel文件(> 1500行和> 120列)。 @MichaelChirico表明,当速度是首选时, readxl
更好,而openxlsx
取代了xlsx
软件包提供的function。 如果您正在寻找一个在2015年阅读,编写和修改Excel文件的软件包,请selectopenxlsx
而不是xlsx
。
2015年之前:我已经使用了xlsx
软件包 。 它改变了我的工作stream程与Excel和R没有更烦人的popup窗口问,如果我确定我想保存我的Excel表格.txt格式。 该包也写入Excel文件。
但是,我发现read.xlsx
函数打开大型Excel文件时速度慢。 read.xlsx2
函数的速度相当快,但不会导致data.frame列的向量类。 如果使用read.xlsx2
函数,则必须使用colClasses
命令来指定所需的列类。 这是一个实际的例子:
read.xlsx("filename.xlsx", 1)
读取您的文件并使data.frame列类几乎有用,但是对于大型数据集非常慢。 也适用于.xls
文件。
read.xlsx2("filename.xlsx", 1)
更快,但您将不得不手动定义列类。 一个快捷方式是运行该命令两次(见下面的例子)。 character
规范将您的列转换为因素。 使用Date
和POSIXct
选项的时间。
coln <- function(x){y <- rbind(seq(1,ncol(x))); colnames(y) <- colnames(x) rownames(y) <- "col.number"; return(y)} # A function to see column numbers data <- read.xlsx2("filename.xlsx", 1) # Open the file coln(data) # Check the column numbers you want to have as factors x <- 3 # Say you want columns 1-3 as factors, the rest numeric data <- read.xlsx2("filename.xlsx", 1, colClasses= c(rep("character", x), rep("numeric", ncol(data)-x+1)))
现在有readxl :
readxl软件包可以很容易地将数据从Excel中导出并导入到R中。与现有的软件包(例如gdata,xlsx,xlsReadWrite等)相比,readxl没有外部依赖关系,所以在所有操作系统上安装和使用都很简单。 它被devise用来处理存储在一个表格中的表格数据。
readxlbuild立在libxls C库之上,它将基础二进制格式的许多复杂性抽象出来。
它支持传统的.xls格式和.xlsx
readxl可以从CRAN获得,或者你可以从github上安装:
# install.packages("devtools") devtools::install_github("hadley/readxl")
用法
library(readxl) # read_excel reads both xls and xlsx files read_excel("my-old-spreadsheet.xls") read_excel("my-new-spreadsheet.xlsx") # Specify sheet with a number or name read_excel("my-spreadsheet.xls", sheet = "data") read_excel("my-spreadsheet.xls", sheet = 2) # If NAs are represented by something other than blank cells, # set the na argument read_excel("my-spreadsheet.xls", na = "NA")
请注意,虽然描述中提到“没有外部依赖”,但它确实需要Rcpp
包 ,而Rcpp
包需要Rtools(用于Windows)或Xcode(用于OSX),这是 R的外部依赖关系。尽pipe许多人已经为其他人原因。
我用XLConnect
祝你好运: http : XLConnect
考虑到在R
读取Excel文件的不同方式的激增,以及这里的答案过多,我想尽量说明在这里提到的哪个选项performance最好(在一些简单的情况下)。
自从我开始使用R
以来,我自己一直在使用xlsx
因为如果没有其他的东西,我就会xlsx
惯性,最近我注意到似乎没有关于哪个软件包效果更好的客观信息。
任何基准testing都充满了困难,因为有些软件包肯定比其他软件更好地处理某些情况,还有其他一些注意事项。
这就是说,我正在使用一个(可重现的)数据集,我认为它是一个非常常见的格式(8个string字段,3个数字,1个整数,3个date):
set.seed(51423) data.frame( str1 = sample(sprintf("%010d", 1:NN)), #ID field 1 str2 = sample(sprintf("%09d", 1:NN)), #ID field 2 #varying length string field--think names/addresses, etc. str3 = replicate(NN, paste0(sample(LETTERS, sample(10:30, 1L), TRUE), collapse = "")), #factor-like string field with 50 "levels" str4 = sprintf("%05d", sample(sample(1e5, 50L), NN, TRUE)), #factor-like string field with 17 levels, varying length str5 = sample(replicate(17L, paste0(sample(LETTERS, sample(15:25, 1L), TRUE), collapse = "")), NN, TRUE), #lognormally distributed numeric num1 = round(exp(rnorm(NN, mean = 6.5, sd = 1.5)), 2L), #3 binary strings str6 = sample(c("Y","N"), NN, TRUE), str7 = sample(c("M","F"), NN, TRUE), str8 = sample(c("B","W"), NN, TRUE), #right-skewed integer int1 = ceiling(rexp(NN)), #dates by month dat1 = sample(seq(from = as.Date("2005-12-31"), to = as.Date("2015-12-31"), by = "month"), NN, TRUE), dat2 = sample(seq(from = as.Date("2005-12-31"), to = as.Date("2015-12-31"), by = "month"), NN, TRUE), num2 = round(exp(rnorm(NN, mean = 6, sd = 1.5)), 2L), #date by day dat3 = sample(seq(from = as.Date("2015-06-01"), to = as.Date("2015-07-15"), by = "day"), NN, TRUE), #lognormal numeric that can be positive or negative num3 = (-1) ^ sample(2, NN, TRUE) * round(exp(rnorm(NN, mean = 6, sd = 1.5)), 2L) )
然后我写了这个文件到csv并在LibreOffice中打开并保存为一个.xlsx文件,然后使用默认选项对这个线程中提到的4个包进行了基准testing: xlsx
, openxlsx
, readxl
和gdata
(我也试过了不pipe我是否指定列types,但这并没有改变排名)。
我不包括RODBC
因为我在Linux上; XLConnect
因为它似乎其主要目的不是阅读单个Excel表单,而是导入整个Excel工作簿,所以把它的马只在其阅读能力看起来不公平; 和xlsReadWrite
因为它不再与我的R
版本兼容(似乎已经被淘汰)。
然后,我运行NN=1000L
和NN=25000L
基准testing(在每次声明data.frame
之前重置种子),以考虑到Excel文件大小的不同。 gc
主要用于xlsx
,我发现它有时可以创build内存阻塞。 不用再说了,下面是我find的结果:
1,000行Excel文件
benchmark1k <- microbenchmark(times = 100L, xlsx = {xlsx::read.xlsx2(fl, sheetIndex=1); invisible(gc())}, openxlsx = {openxlsx::read.xlsx(fl); invisible(gc())}, readxl = {readxl::read_excel(fl); invisible(gc())}, gdata = {gdata::read.xls(fl); invisible(gc())}) # Unit: milliseconds # expr min lq mean median uq max neval # xlsx 194.1958 199.2662 214.1512 201.9063 212.7563 354.0327 100 # openxlsx 142.2074 142.9028 151.9127 143.7239 148.0940 255.0124 100 # readxl 122.0238 122.8448 132.4021 123.6964 130.2881 214.5138 100 # gdata 2004.4745 2042.0732 2087.8724 2062.5259 2116.7795 2425.6345 100
所以readxl
是赢家, openxlsx
竞争激烈, gdata
是明显的失败者。 采取相对于列最小的每个措施:
# expr min lq mean median uq max # 1 xlsx 1.59 1.62 1.62 1.63 1.63 1.65 # 2 openxlsx 1.17 1.16 1.15 1.16 1.14 1.19 # 3 readxl 1.00 1.00 1.00 1.00 1.00 1.00 # 4 gdata 16.43 16.62 15.77 16.67 16.25 11.31
我们看到自己的喜爱, xlsx
比readxl
慢了60%。
25,000行Excel文件
由于需要花费的时间,我只在大文件上做了20次重复,否则命令是一样的。 这里是原始数据:
# Unit: milliseconds # expr min lq mean median uq max neval # xlsx 4451.9553 4539.4599 4738.6366 4762.1768 4941.2331 5091.0057 20 # openxlsx 962.1579 981.0613 988.5006 986.1091 992.6017 1040.4158 20 # readxl 341.0006 344.8904 347.0779 346.4518 348.9273 360.1808 20 # gdata 43860.4013 44375.6340 44848.7797 44991.2208 45251.4441 45652.0826 20
以下是相关数据:
# expr min lq mean median uq max # 1 xlsx 13.06 13.16 13.65 13.75 14.16 14.13 # 2 openxlsx 2.82 2.84 2.85 2.85 2.84 2.89 # 3 readxl 1.00 1.00 1.00 1.00 1.00 1.00 # 4 gdata 128.62 128.67 129.22 129.86 129.69 126.75
所以readxl
在速度readxl
是明显的赢家。 gdata
最好有其他的东西去做,因为它在阅读Excel文件时的速度很慢,而这个问题只会在更大的表格上加剧。
两个openxlsx
绘制是:1)其广泛的其他方法( readxl
被devise为只做一件事,这可能是为什么它如此之快),特别是其write.xlsx
函数,2)( readxl
更多的缺点)仅在readxl
的col_types
参数(在撰写本文时)接受一些非标准的R
: "text"
而不是"character"
和"date"
而不是"Date"
。
library(RODBC) file.name <- "file.xls" sheet.name <- "Sheet Name" ## Connect to Excel File Pull and Format Data excel.connect <- odbcConnectExcel(file.name) dat <- sqlFetch(excel.connect, sheet.name, na.strings=c("","-")) odbcClose(excel.connect)
我个人喜欢RODBC,可以推荐它。
刚刚给了包openxlsx
今天一试。 它工作得很好(而且速度很快)。
另一个解决scheme是xlsReadWrite
软件包,它不需要额外的安装,但是需要在第一次使用之前下载额外的shlib:
require(xlsReadWrite) xls.getshlib()
忘记这可能会导致彻底的沮丧。 在那里和所有的…
在旁注:你可能要考虑转换为基于文本的格式(例如csv)并从那里读入。 这有几个原因:
-
无论您的解决scheme(RODBC,gdata,xlsReadWrite),当您的数据转换时,可能会发生一些奇怪的事情。 特别是date可能相当麻烦。
HFWutils
软件包有一些工具来处理EXCELdate(根据@Ben Bolker的评论)。 -
如果您有大张纸,则在文本文件中阅读比从EXCEL中读取更快。
-
对于.xls和.xlsx文件,可能需要不同的解决scheme。 EG xlsReadWrite软件包目前不支持.xlsx AFAIK。
gdata
要求你为.xlsx支持安装额外的perl库。xlsx
包可以处理相同名称的扩展名。
正如上面在许多其他答案中提到的,有很多很好的包连接到XLS / X文件并以合理的方式获取数据。 但是,应该警告您在任何情况下都不应使用剪贴板(或.csv)文件从Excel中检索数据。 要知道为什么,在excel中input=1/3
到单元格中。 现在,将可见的小数点减less到两个。 然后将数据复制并粘贴到R.现在保存CSV。 在这两种情况下,您都会注意到,Excel只会帮助您保存通过界面显示给您的数据,并且您已经失去了实际源数据的所有精度。
扩展@Mikko提供的答案,您可以使用一个简洁的技巧来加快速度,而不必提前“知道”列类。 只需使用read.xlsx
获取有限数量的logging以确定类,然后使用read.xlsx2
例
# just the first 50 rows should do... df.temp <- read.xlsx("filename.xlsx", 1, startRow=1, endRow=50) df.real <- read.xlsx2("filename.xlsx", 1, colClasses=as.vector(sapply(df.temp, mode)))