Ricerca…


introduzione

Data.table supporta i vettori di colonna appartenenti alla classe di list di R.

Osservazioni

Nel caso in cui sembri strano che stiamo parlando di liste senza usare quella parola nel codice, nota che .() È un alias per list() se usato all'interno di una chiamata DT[...] .

Lettura in molti file correlati

Supponiamo di voler leggere e impilare un gruppo di file formattati in modo simile. La soluzione rapida è:

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

Potremmo non essere soddisfatti di questo per un paio di motivi:

  • Potrebbe verificarsi errori durante la lettura con fread o quando si impila con rbindlist causa della formattazione dei dati incoerente o rbindlist .
  • Potremmo voler tenere traccia dei metadati per ogni file, afferrati dal nome del file o forse da alcune righe di intestazione all'interno dei file (non del tutto tabulari).

Un modo per gestire ciò è creare una "tabella di file" e memorizzare il contenuto di ciascun file come una voce della colonna di elenco sulla riga associata.

Dati di esempio

Prima di inserire i dati di esempio qui sotto, assicurati di essere in una cartella vuota su cui scrivere. Esegui getwd() e leggi ?setwd se hai bisogno di cambiare cartella.

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

Identifica i file e i metadati dei file

Questa parte è abbastanza semplice:

# 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

Leggi nei file

Leggi nei file come una colonna di lista:

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>

Se c'è un intoppo nel leggere uno dei file o è necessario modificare gli argomenti fread seconda attributi del file, questo passaggio può essere facilmente esteso, guardando come:

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

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

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

Per i dettagli sulle opzioni di lettura in file CSV e file simili, vedere ?fread

Impila i dati

Da qui, vogliamo impilare i dati:

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

Se si verificano alcuni problemi nello stacking (come i nomi delle colonne o le classi che non corrispondono), possiamo tornare alle singole tabelle in fileDT per verificare dove ha avuto origine il problema. Per esempio,

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

estensioni

Se i file non si trovano nella directory di lavoro corrente, utilizzare

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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow