Read an Excel file directly from a R script
如何将Excel文件直接读入R? 还是应该首先将数据导出到文本或CSV文件,然后将该文件导入R?
让我重申@Chase的建议:使用XLConnect。
我认为使用XLConnect的原因是:
与其他解决方案相比,XLConnect有点新,因此在博客文章和参考文档中很少提及。对我来说,这非常有用。
现在有readxl:
The readxl package makes it easy to get data out of Excel and into R.
Compared to the existing packages (e.g. gdata, xlsx, xlsReadWrite etc)
readxl has no external dependencies so it's easy to install and use on
all operating systems. It is designed to work with tabular data stored
in a single sheet.readxl is built on top of the libxls C library, which abstracts away
many of the complexities of the underlying binary format.It supports both the legacy .xls format and .xlsx
readxl is available from CRAN, or you can install it from github with:
1 2 | # install.packages("devtools") devtools::install_github("hadley/readxl") |
用法
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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") |
请注意,尽管描述中说"没有外部依赖项",但它确实需要
是。请参阅R Wiki上的相关页面。简短的答案:
我不直接执行此操作的唯一原因是,您可能需要检查电子表格以查看其是否存在故障(怪异的标题,多个工作表[您一次只能阅读一个,尽管显然可以遍历所有这些工作表] ,包括地块等)。但是对于格式完整的矩形电子表格,它具有纯数字和字符数据(即,非逗号格式的数字,日期,具有零除错误的公式,缺少值等)..我通常没有问题这个过程。
EDIT 2015年10月:正如其他人在这里评论的那样,
2015年之前:我使用过
但是,打开大型Excel文件时,我发现
1 2 3 4 5 6 7 8 9 10 11 | 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))) |
考虑到以多种方式读取
自从我开始使用
任何基准测试活动都充满困难,因为某些软件包肯定会比其他软件包更好地处理某些情况,而其他方面则需??要注意。
就是说,我正在使用一种(可重现的)数据集,我认为它是一种非常常见的格式(8个字符串字段,3个数字,1个整数,3个日期):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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个包进行基准测试:
我排除
然后,我使用
1,000行Excel文件
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
因此,
1 2 3 4 5 | # 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 |
我们看到了我自己的最爱,
25,000行Excel文件
由于花费的时间,我只对较大的文件进行了20次重复,否则命令是相同的。这是原始数据:
1 2 3 4 5 6 | # 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 |
以下是相关数据:
1 2 3 4 5 | # 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 |
因此,
我对
1 2 3 4 5 6 7 8 | 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并且可以推荐它。
今天就尝试使用包
http://cran.r-project.org/web/packages/openxlsx/index.html
另一个解决方案是
1 2 | require(xlsReadWrite) xls.getshlib() |
忘记这一点会导致完全沮丧。去过那里...
旁注:您可能要考虑转换为基于文本的格式(例如csv)并从中读取。这有很多原因:
-
不管您使用什么解决方案(RODBC,gdata,xlsReadWrite),在转换数据时都可能会发生一些奇怪的事情。特别是日期可能非常麻烦。
HFWutils 软件包具有一些处理EXCEL日期的工具(根据@Ben Bolker的评论)。 -
如果您有大张纸,则读取文本文件要比从EXCEL读取数据快。
-
对于.xls和.xlsx文件,可能需要不同的解决方案。例如,xlsReadWrite软件包当前不支持.xlsx AFAIK。
gdata 要求您安装其他支持.xlsx的perl库。xlsx 包可以处理相同名称的扩展名。
通过扩展@Mikko提供的答案,您可以使用巧妙的技巧来加快处理速度,而不必提前"知道"您的列类。只需使用
例
1 2 3 4 | # 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))) |
如上文在其他许多答案中所述,有很多不错的程序包可以连接到XLS / X文件并以合理的方式获取数据。但是,应警告您,在任何情况下都不应使用剪贴板(或.csv)文件从Excel中检索数据。若要查看原因,请在excel的单元格中输入
可以将Excel文件直接读取到R中,如下所示:
1 | my_data <- read.table(file ="xxxxxx.xls", sep ="\\t", header=TRUE) |
使用readxl包读取xls和xlxs文件
1 2 3 | library("readxl") my_data <- read_excel("xxxxx.xls") my_data <- read_excel("xxxxx.xlsx") |