Szukaj…


Wprowadzenie

Data.table obsługuje wektory kolumnowe należące do klasy list R.

Uwagi

W przypadku, gdy wygląda dziwnie, że mówimy o listach bez użycia tego słowa w kodzie, zauważ, że .() Jest aliasem dla list() gdy jest używany w wywołaniu DT[...] .

Czytanie w wielu powiązanych plikach

Załóżmy, że chcemy odczytać i ułożyć stos plików o podobnym formacie. Szybkie rozwiązanie to:

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

Możemy nie być z tego zadowoleni z kilku powodów:

  • Może rbindlist błędy podczas czytania z fread lub podczas układania w stos z rbindlist z powodu niespójnego lub rbindlist formatowania danych.
  • Możemy chcieć śledzić metadane dla każdego pliku, pobrane z nazwy pliku lub być może z niektórych wierszy nagłówka w plikach (niezupełnie tabelarycznych).

Jednym ze sposobów poradzenia sobie z tym jest utworzenie „tabeli plików” i zapisanie zawartości każdego pliku jako pozycji kolumny listy w wierszu z nim powiązanym.

Przykładowe dane

Przed wykonaniem poniższych przykładowych danych upewnij się, że znajdujesz się w pustym folderze, w którym możesz pisać. Uruchom getwd() i przeczytaj ?setwd jeśli chcesz zmienić foldery.

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

Zidentyfikuj pliki i metadane plików

Ta część jest dość prosta:

# 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

Wczytaj pliki

Wczytaj pliki jako kolumnę listy:

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>

Jeśli w czytaniu jednego z plików pojawi się problem lub konieczna będzie zmiana argumentów na fread zależności od atrybutów pliku, ten krok można łatwo przedłużyć, wyglądając:

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

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

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

Aby uzyskać szczegółowe informacje na temat opcji odczytu w plikach CSV i podobnych plikach, zobacz ?fread .

Stos danych

Stąd chcemy ułożyć dane w stos:

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

Jeśli wystąpi jakiś problem w stosie (np. fileDT nazwy kolumn lub klasy), możemy wrócić do poszczególnych tabel w fileDT aby sprawdzić, skąd problem się fileDT . Na przykład,

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

Rozszerzenia

Jeśli plików nie ma w bieżącym katalogu roboczym, użyj

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow