Recherche…


Introduction

Data.table prend en charge les vecteurs de colonne appartenant à la classe de list de R.

Remarques

Dans le cas où il semble étrange que nous parlions de listes sans utiliser ce mot dans le code, notez que .() Est un alias pour list() lorsqu'il est utilisé dans un appel DT[...] .

Lecture dans de nombreux fichiers liés

Supposons que nous voulions lire et empiler un tas de fichiers de format similaire. La solution rapide est la suivante:

rbindlist(lapply(list.files(patt="csv$"), fread), id=TRUE)

Nous pourrions ne pas être satisfaits de cela pour deux raisons:

  • Il peut se rbindlist à des erreurs lors de la lecture avec fread ou lors de l'empilement avec rbindlist raison d'un formatage de données incohérent ou rbindlist .
  • Nous pouvons vouloir garder une trace des métadonnées pour chaque fichier, extraites du nom du fichier ou peut-être de certaines lignes d'en-tête dans les fichiers (pas tout à fait tabulaires).

Une façon de gérer cela consiste à créer une "table de fichiers" et à stocker le contenu de chaque fichier en tant qu'entrée de colonne de liste sur la ligne qui lui est associée.

Exemple de données

Avant de créer l'exemple de données ci-dessous, assurez-vous que vous êtes dans un dossier vide dans lequel vous pouvez écrire. Exécutez getwd() et lisez ?setwd si vous devez changer de dossier.

# example data
set.seed(1)
for (i in 1:3) 
  fwrite(data.table(id = 1:2, v = sample(letters, 2)), file = sprintf("file201%s.csv", i))

Identifier les fichiers et les métadonnées de fichier

Cette partie est assez simple:

# First, identify the files you want:
fileDT = data.table(fn = list.files(pattern="csv$"))

# Next, optionally parse the names for metadata using regex:
fileDT[, year := type.convert(sub(".*([0-9]{4}).*", "\\1", fn))]

# Finally construct a string file-ID column:
fileDT[, id := as.character(.I)]

#              fn year id
# 1: file2011.csv 2011  1
# 2: file2012.csv 2012  2
# 3: file2013.csv 2013  3

Lire dans les fichiers

Lire dans les fichiers en tant que colonne de liste:

fileDT[, contents := .(lapply(fn, fread))]

#              fn year id     contents
# 1: file2011.csv 2011  1 <data.table>
# 2: file2012.csv 2012  2 <data.table>
# 3: file2013.csv 2013  3 <data.table>

S'il y a un accroc dans la lecture de l'un des fichiers ou si vous devez changer les arguments en fread fonction des attributs du fichier, cette étape peut facilement être étendue, ressemblant à:

fileDT[, contents := {
  cat(fn, "\n")

  dat = if (year %in% 2011:2012){
    fread(fn, some_args)
  } else {
    fread(fn)
  }

  .(.(dat))
}, by=fn]

Pour plus de détails sur les options de lecture dans les fichiers CSV et les fichiers similaires, voir ?fread .

Empiler les données

De là, nous voulons empiler les données:

fileDT[, rbindlist(setNames(contents, id), idcol="file_id")]

#    file_id id v
# 1:       1  1 g
# 2:       1  2 j
# 3:       2  1 o
# 4:       2  2 w
# 5:       3  1 f
# 6:       3  2 w

Si un problème survient lors de l'empilement (comme les noms de colonne ou les classes non correspondantes), nous pouvons revenir aux tables individuelles dans fileDT pour inspecter l'origine du problème. Par exemple,

fileDT[id == "2", contents[[1]]]
#    id v
# 1:  1 o
# 2:  2 w

Les extensions

Si les fichiers ne sont pas dans votre répertoire de travail actuel, utilisez

my_dir = "whatever"
fileDT = data.table(fn = list.files(my_dir, pattern="*.csv"))

# and when reading
fileDT[, contents := .(lapply(fn, function(n) fread(file.path(my_dir, n))))]


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow