Leia um arquivo Excel diretamente de um script R


95

Como posso ler um arquivo Excel diretamente no R? Ou devo primeiro exportar os dados para um arquivo de texto ou CSV e importar esse arquivo para o R?


@Sacha Epskamp: com xlsReadWrite, você nem precisa instalar o Perl.
Joris Meys

1
gdataa versão 2.8.2 lê xlsxarquivos com a read.xlsfunção
Ben

1
Veja meu aviso (como resposta abaixo) sobre a possível perda de precisão se você exportar os dados para um formato de texto do Excel.
russellpierce

1
xlsxpacote para xlsx / xlsm / xls, não sei sobre xlam etc.
Qbik

2
"Nunca vejo razão para não exportar primeiro para um arquivo de texto". Que tal isto: quando exporto para CSV, um dos campos de que preciso não é escrito. Parece algum tipo de DRM, mas como não escrevi a planilha, não sei.
Nate Reed

Respostas:


41

Sim. Veja a página relevante no R wiki . Resposta curta: read.xlso gdatapacote funciona na maioria das vezes (embora você precise ter Perl instalado em seu sistema - geralmente já é verdade no MacOS e Linux, mas dá um passo extra no Windows, ou seja, consulte http://strawberryperl.com/ ) Existem várias advertências e alternativas listadas na página R wiki.

A única razão que vejo para não fazer isso diretamente é que você pode querer examinar a planilha para ver se ela tem falhas (cabeçalhos estranhos, várias planilhas [você só pode ler uma de cada vez, embora possa obviamente percorrer todas] , plotagens incluídas, etc.). Mas para uma planilha retangular bem formada com números simples e dados de caracteres (ou seja, números não formatados por vírgula, datas, fórmulas com erros de divisão por zero, valores ausentes, etc. etc. ..) Eu geralmente não tenho problemas com este processo.


6
Há muitos problemas potenciais a serem considerados, que enfrentei pessoalmente. Os campos com números com vírgulas precisam ser removidos e convertidos em numéricos em R. Os campos com "-" precisam ser recodificados para NA. A recomendação geral é realmente olhar para seus números no Excel e garantir que eles estão sendo traduzidos corretamente para R.
Brandon Bertelsen

3
Não é possível argumentar com "você realmente precisa olhar seus números" ... qual é o problema com os campos "-"? não na.strings="-"resolver o problema? Quantos desses problemas são genéricos e quantos deles (por exemplo, campos numéricos com vírgulas) podem ser resolvidos com outras ferramentas como o XLConnect ...?
Ben Bolker

1
Esse comentário foi direcionado ao OP, não a você Ben, minha culpa por má colocação.
Brandon Bertelsen

1
Anedota relevante: read.xlssucesso na leitura de uma planilha muito grande de um arquivo Excel em que XLConnecte xlsxfalhou (acredito porque ambos dependem do Apache POI )
Matt Parker

49

Deixe-me reiterar o que @Chase recomendou: use o XLConnect .

As razões para usar o XLConnect são, em minha opinião:

  1. Plataforma cruzada. XLConnect é escrito em Java e, portanto, será executado em Win, Linux, Mac sem nenhuma alteração de seu código R (exceto possivelmente strings de caminho)
  2. Nada mais para carregar. Basta instalar o XLConnect e seguir em frente.
  3. Você apenas mencionou a leitura de arquivos Excel, mas o XLConnect também gravará arquivos Excel, incluindo a alteração da formatação das células. E fará isso no Linux ou Mac, não apenas no Win.

O XLConnect é um tanto novo em comparação com outras soluções, por isso é mencionado com menos frequência em postagens de blog e documentos de referência. Para mim tem sido muito útil.


48

E agora existe readxl :

O pacote readxl facilita a obtenção de dados do Excel e para o R. Comparado com os pacotes existentes (por exemplo, gdata, xlsx, xlsReadWrite etc), readxl não tem dependências externas, portanto é fácil de instalar e usar em todos os sistemas operacionais. Ele é projetado para trabalhar com dados tabulares armazenados em uma única folha.

readxl é construído em cima da biblioteca libxls C, que abstrai muitas das complexidades do formato binário subjacente.

Suporta o formato legado .xls e .xlsx

readxl está disponível no CRAN ou você pode instalá-lo no github com:

# install.packages("devtools")
devtools::install_github("hadley/readxl")

Uso

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")

Observe que, embora a descrição diga 'sem dependências externas', ela requer o Rcpppacote , que por sua vez requer Rtools (para Windows) ou Xcode (para OSX), que são dependências externas a R. Embora muitas pessoas os instalem por outros motivos .


3
Muito mais rápido do que xlsx. O tempo de leitura é como read.xlsx2, mas infere tipos.
Steve Rowe

1
@SteveRowe veja uma nova resposta para alguns benchmarks objetivos (tentados) que confirmam isso
MichaelChirico

Existe uma maneira de ler strings como fatores usando read_excel? Eu gosto da velocidade em comparação com read.xlsx, mas ter que converter manualmente as colunas de caracteres em fatores anula o propósito.
coip de

2
+1 pelo fato de não ter dependências. Eu odeio ter que instalar o java. E eu tentei e funciona muito bem para mim.
Bastian,

2
readxl e openxlsx são os melhores. readxl é mais rápido, mas não permite a gravação. De qualquer forma, nenhum deles funciona bem ao tentar especificar classes / tipos de coluna.
Skan de

29

EDIT 2015-outubro: Como outros comentaram aqui, os pacotes openxlsxe readxlsão muito mais rápidos do que o xlsxpacote e na verdade conseguem abrir arquivos Excel maiores (> 1500 linhas e> 120 colunas). @MichaelChirico demonstra que readxlé melhor quando a velocidade é preferida e openxlsxsubstitui a funcionalidade fornecida pelo xlsxpacote. Se você está procurando um pacote para ler, gravar e modificar arquivos do Excel em 2015, escolha o em openxlsxvez de xlsx.

Pré-2015: Usei o xlsxpacote . Isso mudou meu fluxo de trabalho com Excel e R. Chega de pop-ups irritantes perguntando se eu tenho certeza que quero salvar minha planilha do Excel no formato .txt. O pacote também grava arquivos do Excel.

No entanto, acho a read.xlsxfunção lenta, ao abrir arquivos grandes do Excel. read.xlsx2função é consideravelmente mais rápida, mas não abandona a classe vetorial de colunas data.frame. Você tem que usar o colClassescomando para especificar as classes de coluna desejadas, se usar a read.xlsx2função. Aqui está um exemplo prático:

read.xlsx("filename.xlsx", 1)lê seu arquivo e torna as classes de coluna data.frame quase úteis, mas é muito lento para grandes conjuntos de dados. Funciona também para .xlsarquivos.

read.xlsx2("filename.xlsx", 1)é mais rápido, mas você terá que definir as classes de coluna manualmente. Um atalho é executar o comando duas vezes (veja o exemplo abaixo). characterespecificação converte suas colunas em fatores. Use Datee POSIXctopções de tempo.

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)))

25

Dada a proliferação de diferentes maneiras de ler um arquivo do Excel Re a abundância de respostas aqui, pensei em tentar esclarecer qual das opções mencionadas aqui tem melhor desempenho (em algumas situações simples).

Eu mesmo tenho usado xlsxdesde que comecei a usar R, por inércia, se nada mais, e recentemente percebi que não parece haver nenhuma informação objetiva sobre qual pacote funciona melhor.

Qualquer exercício de benchmarking está repleto de dificuldades, pois alguns pacotes certamente lidam com certas situações melhor do que outros, e uma cascata de outras advertências.

Dito isso, estou usando um conjunto de dados (reproduzível) que acho que está em um formato bastante comum (8 campos de string, 3 numéricos, 1 inteiro, 3 datas):

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)
)

Eu, então, escreveu isto para CSV e inaugurado em LibreOffice e salva-lo como um arquivo .xlsx, então aferido 4 dos pacotes mencionados neste tópico: xlsx, openxlsx, readxl, e gdata, usando as opções padrão (Eu também tentei uma versão de haver ou não eu especificar os tipos de coluna, mas isso não alterou as classificações).

Estou excluindo RODBCporque estou no Linux; XLConnectporque parece que seu objetivo principal não é ler em planilhas únicas do Excel, mas importar pastas de trabalho inteiras do Excel, portanto, colocar seu cavalo na corrida apenas em suas capacidades de leitura parece injusto; e xlsReadWriteporque não é mais compatível com a minha versão do R(parece ter sido desativado).

Em seguida, executei benchmarks com NN=1000Le NN=25000L(redefinindo a semente antes de cada declaração data.frameacima) para permitir as diferenças em relação ao tamanho do arquivo do Excel. gcé principalmente para xlsx, que às vezes pode criar obstruções de memória. Sem mais delongas, aqui estão os resultados que encontrei:

Arquivo Excel de 1.000 linhas

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

Assim readxlé o vencedor, com um perdedor openxlsxcompetitivo e gdataclaro. Tomando cada medida em relação ao mínimo da coluna:

#       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

Vemos o meu favorito, xlsxé 60% mais lento do que readxl.

Arquivo Excel de 25.000 linhas

Devido ao tempo que leva, fiz apenas 20 repetições no arquivo maior, caso contrário, os comandos eram idênticos. Aqui estão os dados brutos:

# 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

Aqui estão os dados relativos:

#       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

Então, readxlé o vencedor claro quando se trata de velocidade. gdataé melhor ter algo mais a seu favor, já que é dolorosamente lento para ler arquivos do Excel, e esse problema só é agravado para tabelas maiores.

Dois empates openxlsxsão 1) seus outros métodos extensivos ( readxlé projetado para fazer apenas uma coisa, o que provavelmente é parte do motivo pelo qual é tão rápido), especialmente sua write.xlsxfunção, e 2) (mais uma desvantagem para readxl) o col_typesargumento em readxlapenas (como desta redação) aceita alguns não padrão R: em "text"vez de "character"e em "date"vez de "Date".


Seria ótimo se você também adicionasse o benchmark para XLConnect. Comente também que readxl não é capaz de escrever. xlsx e openxlsx não funcionam corretamente com a opção col_types ou colClasses.
skan

@skan Inicialmente executei alguns testes, XLConnectmas é muito lento; Acredito que readxlas desvantagens de foram suficientemente cobertas em meu parágrafo final; e não tenho experiência semelhante à sua com xlsxou openxlsxcomo uso regularmente ambos para especificar tipos.
MichaelChirico de


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)

Pessoalmente, gosto do RODBC e posso recomendá-lo.


7
Advertência: às vezes, o ODBC pode ser difícil de ser executado em plataformas diferentes do Windows.
JD Long

1
@JD Long e até no Windows é um PITA. Nenhum momento sexy para mim e ODBC no W7 de 64 bits ...
Roman Luštrik

4
Carregando o pacote necessário: RODBC Erro em odbcConnectExcel (file.name): odbcConnectExcel só pode ser usado com Windows de 32 bits
andrekos


6

Outra solução é o xlsReadWritepacote, que não requer instalações adicionais, mas requer que você baixe o shlib adicional antes de usá-lo pela primeira vez:

require(xlsReadWrite)
xls.getshlib()

Esquecer isso pode causar frustração absoluta. Já esteve lá e tudo isso ...

Em uma nota: você pode querer considerar a conversão para um formato baseado em texto (por exemplo, csv) e ler a partir daí. Isso por uma série de razões:

  • qualquer que seja a sua solução (RODBC, gdata, xlsReadWrite), algumas coisas estranhas podem acontecer quando seus dados são convertidos. Especialmente as datas podem ser bastante complicadas. O HFWutilspacote possui algumas ferramentas para lidar com datas EXCEL (por comentário de @Ben Bolker).

  • se você tiver folhas grandes, ler arquivos de texto é mais rápido do que ler do EXCEL.

  • para arquivos .xls e .xlsx, soluções diferentes podem ser necessárias. Por exemplo, o pacote xlsReadWrite atualmente não suporta .xlsx AFAIK. gdatarequer que você instale bibliotecas perl adicionais para suporte .xlsx. xlsxpacote pode lidar com extensões do mesmo nome.


@Ben Thx pela dica, vou incluí-la na minha resposta. Eu não tentei ser completo, pois a página wiki para a qual a resposta aceita já está bastante completa. Mas não menciona o pacote HFWutils.
Joris Meys

1
-1; Veja minha resposta. TL: DR: O Excel não salva um conjunto de dados de precisão total em csv (ou na área de transferência). Apenas os valores visíveis são mantidos.
russellpierce

5

Conforme observado acima em muitas das outras respostas, existem muitos pacotes bons que se conectam ao arquivo XLS / X e obtêm os dados de uma maneira razoável. No entanto, você deve ser avisado que em nenhuma circunstância você deve usar o arquivo da área de transferência (ou .csv) para recuperar dados do Excel. Para ver por quê, entre =1/3em uma célula do Excel. Agora, reduza o número de casas decimais visíveis para você para dois. Em seguida, copie e cole os dados em R. Agora salve o CSV. Você perceberá que, em ambos os casos, o Excel apenas manteve os dados que estavam visíveis para você por meio da interface e você perdeu toda a precisão dos dados de origem reais.


1
Adoraria saber quem achou que a fidelidade numérica não era relevante / importante.
russellpierce de

1
Bom aviso. No entanto, depende do pacote que você usa. alguns não estão caindo nessa armadilha.
RockScience

@RocketScience Esta é uma escolha de design fundamental na exportação de CSV pelo Excel. Você tem um exemplo de pacote que usa a área de transferência que não tem esse problema? Pacotes que analisam diretamente o arquivo xls xlsx estariam propensos a não cair nessa armadilha. Portanto, o escopo específico do meu aviso.
russellpierce

no Unix você pode tentar gnumeric::read.gnumeric.sheet. No Windows Não estou 100% de certeza, mas acho que gdata::read.xlstambém deve funcionar bem (necessidade de instalar perl embora)
RockScience

@RockScience Respeitosamente, gdata :: read.xls não opera em dados da área de transferência (a menos que você saia do seu caminho) e gnumeric não é Excel. Portanto, na ausência de provas extraordinárias, meu aviso permanece. Existem tantas outras boas opções em resposta a esta pergunta - esperemos que as pessoas as usem.
russellpierce

5

Expandindo a resposta fornecida por @Mikko, você pode usar um truque interessante para acelerar as coisas sem ter que "saber" suas classes de coluna com antecedência. Basta usar read.xlsxpara obter um número limitado de registros para determinar as classes e, em seguida, seguir comread.xlsx2

Exemplo

# 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)))

1
Sua solução retorna numericpara factorsno meu computador. read.xlsxusa characterem readColumnsfunção para especificar fatores. Estou certo de que há uma maneira mais elegante de obter fatores como personagens, mas aqui é uma versão modificada de sua função que funciona: df.real <- read.xlsx2("filename.xlsx", 1, colClasses=gsub("factor", "character", as.vector(sapply(df.temp, class)))).
Mikko

Isso só funciona na medida em que o tipo de coluna pode ser determinado de forma adequada pela primeira linha. Normalmente, analisa-se mais do que a primeira linha para fazer essa determinação. A resposta poderia ser melhorada para abordar o comentário do aaa90210 nomeando o pacote de onde vêm essas funções.
russellpierce

1

Um arquivo Excel pode ser lido diretamente em R da seguinte maneira:

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

Lendo arquivos xls e xlxs usando o pacote readxl

library("readxl")
my_data <- read_excel("xxxxx.xls")
my_data <- read_excel("xxxxx.xlsx")
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.