Zoeken…


Invoering

Data.table steunen kolom vectoren behoren tot R's list klasse.

Opmerkingen

In het geval dat het vreemd lijkt dat we het over lijsten hebben zonder dat woord in de code te gebruiken, merk dan op dat .() Een alias is voor list() wanneer het wordt gebruikt in een DT[...] aanroep.

Inlezen van veel gerelateerde bestanden

Stel dat we een aantal bestanden met dezelfde indeling willen lezen en stapelen. De snelle oplossing is:

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

We kunnen hier om een aantal redenen niet tevreden over zijn:

  • Er kunnen fouten rbindlist bij het lezen met fread of bij het stapelen met rbindlist vanwege inconsistente of buggy gegevensindeling.
  • We willen misschien metadata bijhouden voor elk bestand, opgehaald uit de bestandsnaam of misschien uit enkele koprijen in de (niet geheel tabelvormige) bestanden.

Een manier om dit aan te pakken is om een "bestandstabel" te maken en de inhoud van elk bestand op te slaan als een item in de lijstkolom op de bijbehorende rij.

Voorbeeld gegevens

Voordat u de onderstaande voorbeeldgegevens maakt, moet u zich in een lege map bevinden waarnaar u kunt schrijven. Voer getwd() en lees ?setwd als u mappen moet wijzigen.

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

Identificeer bestanden en bestandsmetagegevens

Dit deel is vrij eenvoudig:

# 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

Inlezen van bestanden

Lees de bestanden in als een lijstkolom:

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>

Als er een probleem is met het lezen van een van de bestanden of als u de argumenten voor fread moet wijzigen, afhankelijk van de kenmerken van het bestand, kan deze stap eenvoudig worden uitgebreid, ziet er als volgt uit:

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

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

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

Zie ?fread Fread voor meer informatie over opties voor het lezen in CSV's en soortgelijke bestanden.

Gegevens stapelen

Vanaf hier willen we de gegevens stapelen:

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

Als er een probleem optreedt bij het stapelen (zoals kolomnamen of klassen die niet overeenkomen), kunnen we teruggaan naar de afzonderlijke tabellen in fileDT om te inspecteren waar het probleem is ontstaan. Bijvoorbeeld,

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

uitbreidingen

Gebruik als de bestanden niet in uw huidige werkende map staan

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow