data.table
Lijstkolommen gebruiken om gegevens op te slaan
Zoeken…
Invoering
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 metfread
of bij het stapelen metrbindlist
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))))]