Buscar..


Introducción

Data.table admite vectores de columna que pertenecen a la clase de list de R.

Observaciones

En caso de que parezca extraño que estemos hablando de listas sin usar esa palabra en el código, tenga en cuenta que .() Es un alias para la list() cuando se usa dentro de una llamada DT[...] .

Leyendo en muchos archivos relacionados

Supongamos que queremos leer y apilar un montón de archivos con formato similar. La solución rápida es:

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

Puede que no estemos satisfechos con esto por un par de razones:

  • Es posible que se fread errores al leer con fread o al apilar con rbindlist debido a un formato de datos inconsistente o rbindlist .
  • Es posible que queramos realizar un seguimiento de los metadatos de cada archivo, tomados del nombre del archivo o quizás de algunas filas de encabezado dentro de los archivos (no del todo tabulares).

Una forma de manejar esto es hacer una "tabla de archivos" y almacenar el contenido de cada archivo como una entrada de columna de lista en la fila asociada a él.

Ejemplo de datos

Antes de crear los datos de ejemplo a continuación, asegúrese de estar en una carpeta vacía en la que pueda escribir. Ejecute getwd() y lea ?setwd si necesita cambiar las carpetas.

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

Identificar archivos y metadatos de archivos.

Esta parte es bastante sencilla:

# 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

Leer en archivos

Lea en los archivos como una columna de la 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>

Si hay un obstáculo en la lectura de uno de los archivos o si necesita cambiar los argumentos a fread según los atributos del archivo, este paso puede extenderse fácilmente, con el siguiente aspecto:

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

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

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

Para obtener detalles sobre las opciones de lectura en CSV y archivos similares, consulte ?fread .

Apilar datos

A partir de aquí, queremos apilar los datos:

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

Si ocurre algún problema en el apilamiento (como nombres de columnas o clases que no coinciden), podemos regresar a las tablas individuales en fileDT para inspeccionar dónde se originó el problema. Por ejemplo,

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

Extensiones

Si los archivos no están en su directorio de trabajo actual, use

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow