Suche…


Einführung

Data.table unterstützt Vektoren Spalte R Zugehörigkeit list Klasse.

Bemerkungen

Wenn es komisch aussieht, dass wir über Listen sprechen, ohne dieses Wort im Code zu verwenden, beachten Sie, dass .() Ein Alias ​​für list() wenn er in einem DT[...] Aufruf DT[...] .

Lesen in vielen verwandten Dateien

Angenommen, wir möchten eine Reihe ähnlich formatierter Dateien lesen und stapeln. Die schnelle Lösung ist:

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

Wir sind aus einigen Gründen nicht zufrieden damit:

  • Beim Lesen mit fread oder beim Stapeln mit rbindlist aufgrund inkonsistenter oder rbindlist fread Fehler auftreten.
  • Wir möchten die Metadaten für jede Datei verfolgen, die aus dem Dateinamen oder aus einigen Kopfzeilen in den (nicht ganz tabellarischen) Dateien entnommen wurde.

Eine Möglichkeit, dies zu behandeln, besteht darin, eine "Dateitabelle" zu erstellen und den Inhalt jeder Datei als Listenspalteneintrag in der zugehörigen Zeile zu speichern.

Beispieldaten

Stellen Sie vor dem Erstellen der Beispieldaten sicher, dass Sie sich in einem leeren Ordner befinden, in den Sie schreiben können. Führen Sie getwd() und lesen Sie ?setwd wenn Sie Ordner wechseln müssen.

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

Identifizieren Sie Dateien und Datei-Metadaten

Dieser Teil ist ziemlich einfach:

# 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

Dateien einlesen

Lesen Sie die Dateien als Listenspalte ein:

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>

Wenn es bei der Lektüre einer der Dateien ein Haken ist oder müssen Sie die Argumente ändern fread auf der Datei - Attribute abhängig, kann dieser Schritt leicht erweitert werden, die aussehen wie:

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

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

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

Weitere Informationen zu den Optionen zum Einlesen von CSV-Dateien und ähnlichen Dateien finden ?fread .

Daten stapeln

Von hier aus wollen wir die Daten stapeln:

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

Wenn beim Stapeln Probleme auftreten (z. B. Spaltennamen oder nicht übereinstimmende Klassen), können wir zu den einzelnen Tabellen in fileDT , um zu überprüfen, wo das Problem entstanden ist. Zum Beispiel,

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

Erweiterungen

Wenn sich die Dateien nicht in Ihrem aktuellen Arbeitsverzeichnis befinden, verwenden Sie

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow