Поиск…


Вступление

Data.table поддерживает векторы столбцов, принадлежащие классу list R.

замечания

В случае, если странно, что мы говорим о списках без использования этого слова в коде, обратите внимание, что .() Является псевдонимом для list() когда используется внутри вызова DT[...] .

Чтение во многих связанных файлах

Предположим, мы хотим читать и складывать кучу файлов с одинаковым форматированием. Быстрое решение:

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

Мы не можем быть удовлетворены этим по нескольким причинам:

  • Это может привести к ошибкам при чтении с помощью fread или при укладке с помощью rbindlist из-за несогласованного или ошибочного форматирования данных.
  • Мы можем отслеживать метаданные для каждого файла, извлекать их из имени файла или, возможно, из некоторых строк заголовка в (не совсем табличных) файлах.

Один из способов справиться с этим - создать «таблицу файлов» и сохранить содержимое каждого файла в виде записи в столбце списка в связанной с ним строке.

Примеры данных

Прежде чем приводить приведенные ниже примеры данных, убедитесь, что вы находитесь в пустой папке, в которую вы можете писать. Запустите getwd() и прочитайте ?setwd если вам нужно сменить папки.

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

Идентификация файлов и метаданных файлов

Эта часть довольно проста:

# 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

Чтение в файлах

Чтение в файлах в виде столбца списка:

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>

Если есть необходимость в чтении одного из файлов или вам нужно изменить аргументы на fread зависимости от атрибутов файла, этот шаг можно легко расширить, выглядя так:

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

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

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

Подробнее о параметрах чтения в CSV-файлах и подобных файлах см. « ?fread .

Данные стека

Отсюда мы хотим собрать данные:

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

Если в стеке возникает некоторая проблема (например, имена столбцов или классы не совпадают), мы можем вернуться к отдельным таблицам в fileDT чтобы проверить, где возникла проблема. Например,

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

расширения

Если файлы не находятся в текущем рабочем каталоге, используйте

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow