Sök…


Introduktion

Data.table stöder kolumnvektorer som tillhör R: s list .

Anmärkningar

Om det ser konstigt ut att vi pratar om listor utan att använda det ordet i koden, observera att .() Är ett alias för list() när det används i ett DT[...] -samtal.

Läser i många relaterade filer

Anta att vi vill läsa och stapla ett gäng liknande formaterade filer. Den snabba lösningen är:

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

Vi kanske inte är nöjda med detta av några skäl:

  • Det kan fread fel när du läser med fread eller när du staplar med rbindlist grund av inkonsekvent eller buggy dataformatering.
  • Vi kanske vill hålla reda på metadata för varje fil, tagna från filnamnet eller kanske från några rubrikrader i filerna (inte riktigt tabellformat).

Ett sätt att hantera detta är att skapa en "filtabell" och lagra innehållet i varje fil som en listkolumnpost på raden som är associerad med den.

Exempel data

Innan du gör exempeldata nedan, se till att du är i en tom mapp du kan skriva till. Kör getwd() och läs ?setwd om du behöver byta mappar.

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

Identifiera filer och filmetadata

Den här delen är ganska enkel:

# 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

Läs i filer

Läs filerna som en listkolumn:

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>

Om det finns en häng vid läsning av en av filerna eller om du behöver ändra argumenten för att fread beroende på filens attribut, kan detta steg enkelt utökas, så att det ser ut som:

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

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

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

För detaljer om läsning i CSV-filer och liknande filer, se ?fread .

Stapla data

Härifrån vill vi stapla uppgifterna:

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

Om något problem uppstår vid stapling (som kolumnnamn eller klasser som inte matchar) kan vi gå tillbaka till de enskilda tabellerna i fileDT att fileDT var problemet har sitt ursprung. Till exempel,

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

Extensions

Om filerna inte finns i ditt nuvarande arbetsdir, använd

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow