web-dev-qa-db-fra.com

Lire un fichier Excel directement à partir d'un script R

Comment lire un fichier Excel directement dans R? Ou devrais-je d'abord exporter les données dans un fichier texte ou CSV et importer ce fichier dans R?

93
waanders

Oui. Voir la page correspondante sur le wiki R . Réponse courte: read.xls du package gdata fonctionne la plupart du temps (bien que Perl soit installé sur votre système - généralement déjà vrai sur MacOS et Linux, mais nécessite une étape supplémentaire sous Windows, c'est à dire voir http://strawberryperl.com/ ). Il existe diverses mises en garde et alternatives répertoriées sur la page wiki de R.

La seule raison pour laquelle je vois que je ne le fais pas directement, c'est que vous voudrez peut-être examiner la feuille de calcul pour voir si elle présente des problèmes (en-têtes étranges, plusieurs feuilles de calcul (vous ne pouvez en lire qu'une à la fois, bien que vous puissiez évidemment les parcourir toutes en boucle). , parcelles incluses, etc.). Mais pour une feuille de calcul rectangulaire bien formée avec des nombres simples et des données de caractères (c'est-à-dire des nombres, des dates, des formules avec des erreurs de division par zéro, des valeurs manquantes, etc.), je n'ai généralement aucun problème avec ce processus.

40
Ben Bolker

Permettez-moi de répéter ce que @Chase a recommandé: Utilisez XLConnect .

Les raisons pour utiliser XLConnect sont, à mon avis:

  1. Cross plate-forme. XLConnect est écrit en Java et fonctionnera donc sous Win, Linux, Mac sans modification de votre code R (sauf éventuellement des chaînes de chemin d'accès).
  2. Rien d'autre à charger. Installez simplement XLConnect et poursuivez votre vie.
  3. Vous avez uniquement mentionné la lecture de fichiers Excel, mais XLConnect écrit également des fichiers Excel, notamment en modifiant le formatage des cellules. Et cela se fera sous Linux ou Mac, pas seulement sous Win.

XLConnect est quelque peu nouveau par rapport à d’autres solutions. Il est donc moins souvent mentionné dans les articles de blog et les documents de référence. Pour moi, cela a été très utile.

48
JD Long

Et maintenant, il y a readxl :

Le package readxl facilite l'extraction de données dans Excel et R. Les comparés aux packages existants (par exemple, gdata, xlsx, xlsReadWrite, etc.), readxl n'a pas de dépendances externes et est donc facile à installer et à utiliser sur tous les systèmes d'exploitation. Il est conçu pour fonctionner avec des données tabulaires stockées dans une seule feuille.

readxl est construit sur la bibliothèque C libxls, qui élimine bon nombre des complexités du format binaire sous-jacent.

Il prend en charge les anciens formats .xls et .xlsx

readxl est disponible à partir de CRAN, ou vous pouvez l’installer à partir de github avec:

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

Usage

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

Notez que bien que la description indique "pas de dépendances externes", elle nécessite le Rcpp package , qui à son tour nécessite Rtools (pour Windows) ou Xcode (pour OSX), qui sont des dépendances externes à R. Bien que beaucoup de gens les aient installées pour d'autres raisons.

44
Ben

EDITER 2015-Octobre: ​​ Comme d'autres l'ont commenté ici openxlsx et Les packages readxl sont de loin plus rapides que le package xlsx et parviennent à ouvrir des fichiers Excel plus volumineux (> 1 500 lignes et> 120 colonnes). @MichaelChirico démontre que readxl est préférable lorsque la vitesse est préférée et que openxlsx remplace la fonctionnalité fournie par le package xlsx. Si vous recherchez un package pour lire, écrire et modifier des fichiers Excel en 2015, choisissez openxlsx au lieu de xlsx.

Avant 2015: J'ai utilisé xlsxpackage . Cela a changé mon flux de travail avec Excel et R. Plus de fenêtres pop-up gênantes, si je suis sûr de vouloir enregistrer ma feuille Excel au format .txt. Le paquet écrit aussi des fichiers Excel.

Cependant, je trouve la fonction read.xlsx lente lors de l’ouverture de gros fichiers Excel. La fonction read.xlsx2 est considérablement plus rapide, mais n'annule pas la classe de vecteur des colonnes data.frame. Vous devez utiliser la commande colClasses pour spécifier les classes de colonnes souhaitées, si vous utilisez la fonction read.xlsx2. Voici un exemple pratique:

read.xlsx("filename.xlsx", 1) lit votre fichier et rend les classes de colonne data.frame presque utiles, mais est très lent pour les grands ensembles de données. Fonctionne également pour les fichiers .xls.

read.xlsx2("filename.xlsx", 1) est plus rapide, mais vous devrez définir les classes de colonnes manuellement. Un raccourci consiste à exécuter la commande deux fois (voir l'exemple ci-dessous). La spécification character convertit vos colonnes en facteurs. Utilisez les options Dateet POSIXct pour la durée.

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

Compte tenu de la multiplication des façons différentes de lire un fichier Excel dans R et de la pléthore de réponses fournies ici, j’ai pensé essayer d’éclaircir la question de savoir laquelle des options mentionnées fonctionne le mieux (dans quelques situations simples ).

J'utilise moi-même xlsx depuis que j'ai commencé à utiliser R, pour l'inertie si rien d'autre, et j'ai récemment remarqué qu'il ne semblait y avoir aucune information objective sur le paquet qui fonctionne le mieux.

Tout exercice d’étalonnage des performances est semé d’embûches, car certains forfaits sont sûrs de gérer certaines situations mieux que d’autres, et une cascade d’autres mises en garde.

Cela dit, j'utilise un ensemble de données (reproductible) qui, à mon avis, est dans un format assez courant (8 champs de chaîne, 3 numériques, 1 entier, 3 dates):

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

J'ai ensuite écrit ceci au format csv, puis ouvert dans LibreOffice et sauvegardé sous un fichier .xlsx, puis comparé 4 des packages mentionnés dans ce fil de discussion: xlsx, openxlsx, readxl et gdata, en utilisant les options par défaut (j'ai également essayé une version indiquant si je spécifiais ou non des types de colonne, mais cela ne changeait pas le classement).

J'exclus RODBC parce que je suis sous Linux; XLConnect car il semble que son objectif principal ne soit pas de lire dans des feuilles Excel simples, mais d'importer des classeurs Excel entiers. et xlsReadWrite car il n'est plus compatible avec ma version de R (semble avoir été supprimé progressivement).

J'ai ensuite exécuté des tests de performances avec NN=1000L et NN=25000L (réinitialisant le germe avant chaque déclaration du data.frame ci-dessus) afin de permettre des différences en ce qui concerne la taille du fichier Excel. gc est principalement destiné à xlsx, que j'ai parfois découvert, pouvant créer des sabots mémoire. Sans plus tarder, voici les résultats que j'ai trouvés:

Fichier Excel à 1 000 lignes

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

Donc, readxl est le gagnant, avec openxlsx concurrentiel et gdata un perdant net. En prenant chaque mesure par rapport à la colonne minimum:

#       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

Nous voyons mon propre favori, xlsx est 60% plus lent que readxl.

Fichier Excel 25 000 lignes

En raison du temps que cela prend, je n'ai fait que 20 répétitions sur le fichier plus volumineux, sinon les commandes étaient identiques. Voici les données brutes:

# 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

Voici les données relatives:

#       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

Donc, readxl est clairement le vainqueur en termes de vitesse. gdata il vaut mieux avoir quelque chose d'autre, car la lecture des fichiers Excel est extrêmement lente et ce problème ne fait qu'exacerber pour les tables plus volumineuses.

Deux tirages de openxlsx sont 1) ses nombreuses autres méthodes (readxl est conçu pour le faire niquement une chose, ce qui explique probablement en partie pourquoi il est si rapide), en particulier son write.xlsx fonction, et 2) (plus d'un inconvénient pour readxl) l'argument col_types dans readxl seulement (à la date de cette écriture) accepte quelques R non standard: "text" au lieu de "character" et "date" au lieu de "Date".

22
MichaelChirico
19
Chase
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)

Personnellement, j'aime RODBC et je peux le recommander.

12

Je viens d'essayer le paquet openxlsx aujourd'hui. Cela a très bien fonctionné (et rapidement).

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

7
Chris

Comme indiqué ci-dessus dans de nombreuses autres réponses, de nombreux bons packages se connectent au fichier XLS/X et récupèrent les données de manière raisonnable. Toutefois, vous devez être averti que vous ne devez en aucun cas utiliser le fichier Presse-papiers (ou un fichier .csv) pour récupérer des données à partir d'Excel. Pour voir pourquoi, entrez =1/3 dans une cellule d'Excel. Maintenant, réduisez le nombre de points décimaux visibles à deux. Ensuite, copiez et collez les données dans R. Enregistrez maintenant le fichier CSV. Vous remarquerez que, dans les deux cas, Excel n'a utilement gardé que les données visibles à travers l'interface et que vous avez perdu toute la précision de vos données source réelles.

4
russellpierce

En développant la réponse fournie par @Mikko, vous pouvez utiliser une astuce astucieuse pour accélérer les choses sans avoir à "connaître" vos classes de colonnes à l'avance. Utilisez simplement read.xlsx pour saisir un nombre limité d’enregistrements afin de déterminer les classes, puis faites un suivi avec read.xlsx2

Exemple

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

Un fichier Excel peut être lu directement dans R comme suit:

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

Lecture de fichiers xls et xlxs à l'aide du package readxl

library("readxl")
my_data <- read_Excel("xxxxx.xls")
my_data <- read_Excel("xxxxx.xlsx")
1