95

如何将 Excel 文件直接读入 R?还是我应该先将数据导出到文本或 CSV 文件,然后将该文件导入 R?

4

12 回答 12

49

让我重申@Chase 的建议:使用XLConnect

在我看来,使用 XLConnect 的原因是:

  1. 跨平台。XLConnect 是用 Java 编写的,因此可以在 Win、Linux、Mac 上运行,而无需更改您的 R 代码(可能的路径字符串除外)
  2. 没有其他东西可以加载。只需安装 XLConnect 并继续生活。
  3. 您只提到了读取 Excel 文件,但 XLConnect 也会写入 Excel 文件,包括更改单元格格式。它将在 Linux 或 Mac 上执行此操作,而不仅仅是 Win。

与其他解决方案相比,XLConnect 有点新,因此在博客文章和参考文档中很少提及。对我来说它非常有用。

于 2011-05-23T16:51:33.053 回答
48

现在有readxl

readxl 包可以很容易地将数据从 Excel 中获取到 R 中。与现有的包(例如 gdata、xlsx、xlsReadWrite 等)相比,readxl 没有外部依赖项,因此它很容易在所有操作系统上安装和使用。它旨在处理存储在单个工作表中的表格数据。

readxl 建立在 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")

请注意,虽然描述说“没有外部依赖项”,但它确实需要Rcpppackage,这反过来又需要 Rtools(对于 Windows)或 Xcode(对于 OSX),它们R 外部的依赖项。尽管许多人出于其他原因安装了它们.

于 2015-03-17T19:54:32.530 回答
41

是的。请参阅R wiki 上的相关页面。简短的回答:read.xlsgdata包中大部分时间都可以工作(尽管您需要在系统上安装 Perl——通常在 MacOS 和 Linux 上已经安装,但在 Windows 上需要额外的步骤,即参见http://strawberryperl.com/)。R wiki 页面上列出了各种警告和替代方案。

我认为不直接执行此操作的唯一原因是您可能想要检查电子表格以查看它是否存在故障(奇怪的标题,多个工作表[您一次只能阅读一个,尽管您显然可以遍历它们] ,包括地块等)。但是对于具有纯数字和字符数据的格式良好的矩形电子表格(即,不是逗号格式的数字、日期、具有被零除错误的公式、缺失值等......)我通常没有问题用这个过程。

于 2011-05-23T15:22:54.773 回答
29

编辑 2015 年至 10 月:正如其他人在这里评论的那样,openxlsxreadxl包比xlsx包快得多,实际上可以打开更大的 Excel 文件(> 1500 行和> 120 列)。@MichaelChirico 演示了readxl在优先考虑速度并openxlsx替换xlsx包提供的功能时会更好。如果您正在寻找用于在 2015 年读取、写入和修改 Excel 文件的包,请openxlsx选择xlsx.

2015 年之前:我使用过xlsxpackage。它使用 Excel 和 R 改变了我的工作流程。不再有烦人的弹出窗口询问我是否确定要以 .txt 格式保存我的 Excel 工作表。该软件包还写入 Excel 文件。

read.xlsx但是,打开大型 Excel 文件时,我发现功能很慢。read.xlsx2函数要快得多,但不会询问 data.frame 列的向量类。如果使用函数,则必须使用colClasses命令指定所需的列类。read.xlsx2这是一个实际的例子:

read.xlsx("filename.xlsx", 1)读取您的文件并使 data.frame 列类几乎有用,但对于大型数据集来说非常慢。也适用于.xls文件。

read.xlsx2("filename.xlsx", 1)更快,但您必须手动定义列类。一个快捷方式是运行该命令两次(参见下面的示例)。character规范将您的列转换为因子。时间的使用DatePOSIXct选项。

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)))
于 2013-01-22T10:23:01.453 回答
25

鉴于读取 Excel 文件的不同方法的激增以及R此处的大量答案,我想我会尝试阐明此处提到的哪些选项表现最好(在一些简单的情况下)。

xlsx自从我开始使用, 以来,我自己一直在使用R,如果没有别的原因的话,我最近注意到似乎没有任何关于哪个包效果更好的客观信息。

任何基准测试都充满了困难,因为某些包肯定会比其他包更好地处理某些情况,以及其他警告的瀑布。

也就是说,我正在使用一个(可重现的)数据集,我认为它是一种非常常见的格式(8 个字符串字段、3 个数字、1 个整数、3 个日期):

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 个包进行基准测试:xlsx、、、和指定列类型,但这并没有改变排名)。openxlsxreadxlgdata

我排除在外RODBC是因为我在 Linux 上;XLConnect因为它的主要目的似乎不是阅读单个 Excel 工作表,而是导入整个 Excel 工作簿,所以只看它的阅读能力是不公平的;并且xlsReadWrite因为它不再与我的版本兼容R(似乎已被淘汰)。

NN=1000L然后,我使用和NN=25000L(在上述每个声明之前重置种子)运行基准测试,data.frame以允许在 Excel 文件大小方面存在差异。gc主要用于xlsx,我发现有时会造成内存阻塞。事不宜迟,以下是我发现的结果:

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比 . 慢 60% readxl

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在速度方面,明显的赢家也是如此。gdata最好有别的办法,因为它在读取 Excel 文件时非常缓慢,而且这个问题只会在更大的表格中加剧。

两个优点openxlsx是 1)它广泛的其他方法(readxl旨在只做一件事,这可能是它如此快的部分原因),尤其是它的write.xlsx功能,以及 2)(更多的缺点readxl)仅在col_types参数中readxl(如写这篇文章)接受一些非标准的R"text"代替"character""date"代替"Date"

于 2015-07-30T21:16:06.043 回答
19

我很幸运XLConnecthttp ://cran.r-project.org/web/packages/XLConnect/index.html

于 2011-05-23T15:39:56.850 回答
13
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 并且可以推荐它。

于 2011-05-23T16:12:12.353 回答
7

今天刚openxlsx试了一下这个包。它工作得非常好(而且很快)。

http://cran.r-project.org/web/packages/openxlsx/index.html

于 2015-02-05T19:49:28.700 回答
6

另一个解决方案是xlsReadWrite软件包,它不需要额外安装,但需要您在第一次使用之前下载额外的 shlib:

require(xlsReadWrite)
xls.getshlib()

忘记这一点可能会导致彻底的挫败感。去过那里和所有...

附注:您可能需要考虑转换为基于文本的格式(例如 csv)并从那里读取。这有几个原因:

  • 无论您的解决方案(RODBC、gdata、xlsReadWrite)如何,当您的数据被转换时,都会发生一些奇怪的事情。特别是日期可能相当麻烦。该HFWutils软件包有一些工具来处理 EXCEL 日期(根据@Ben Bolker 的评论)。

  • 如果你有大表格,读入文本文件比从 EXCEL 中读入要快。

  • 对于 .xls 和 .xlsx 文件,可能需要不同的解决方案。EG xlsReadWrite 包目前不支持 .xlsx AFAIK。gdata要求您安装额外的 perl 库以支持 .xlsx。xlsxpackage 可以处理同名的扩展。

于 2011-05-23T15:44:16.943 回答
5

正如上面在许多其他答案中所指出的,有许多很好的包可以连接到 XLS/X 文件并以合理的方式获取数据。但是,应该警告您,在任何情况下都不应使用剪贴板(或 .csv)文件从 Excel 中检索数据。要了解原因,请=1/3在 Excel 中输入一个单元格。现在,将您可见的小数点减少到两个。然后将数据复制并粘贴到 R 中。现在保存 CSV。您会注意到,在这两种情况下,Excel 只保留了通过界面对您可见的数据,而您已经失去了实际源数据的所有精度。

于 2014-10-08T20:02:10.497 回答
5

扩展@Mikko 提供的答案,您可以使用一个巧妙的技巧来加快速度,而无需提前“了解”您的列类。只需使用read.xlsx抓取有限数量的记录来确定类,然后再跟进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)))
于 2014-10-28T13:31:36.703 回答
1

一个 Excel 文件可以直接读入 R,如下所示:

my_data <- read.table(file = "xxxxxx.xls", sep = "\t", header=TRUE)

使用 readxl 包读取 xls 和 xlxs 文件

library("readxl")
my_data <- read_excel("xxxxx.xls")
my_data <- read_excel("xxxxx.xlsx")
于 2018-08-30T12:33:21.683 回答