in

r – ¿Cómo hago una lista de marcos de datos?

apple touch icon@2

Las otras respuestas te muestran cómo para hacer una lista de data.frames cuando ya tengo un montón de marcos de datos, por ejemplo, d1, d2, …. Tener marcos de datos con nombres secuenciales es un problema, y ​​ponerlos en una lista es una buena solución, pero la mejor práctica es evitar tener un montón de marcos de datos que no estén en una lista en primer lugar.

Las otras respuestas dan muchos detalles sobre cómo asignar marcos de datos a los elementos de la lista, acceder a ellos, etc. También cubriremos eso un poco aquí, pero el Punto principal Es decir no espere hasta tener un montón de data.frames para agregarlos a una lista. Empiece con la lista.

El resto de esta respuesta cubrirá algunos casos comunes en los que podría tener la tentación de crear variables secuenciales y le mostrará cómo ir directamente a las listas. Si es nuevo en las listas en R, es posible que desee leer también ¿Cuál es la diferencia entre [[ and [ in accessing elements of a list?.


Lists from the start

Don’t ever create d1 d2 d3, …, dn in the first place. Create a list d with n elements.

Reading multiple files into a list of data frames

This is done pretty easily when reading in files. Maybe you’ve got files data1.csv, data2.csv, ... in a directory. Your goal is a list of data.frames called mydata. The first thing you need is a vector with all the file names. You can construct this with paste (e.g., my_files = paste0("data", 1:5, ".csv")), but it’s probably easier to use list.files to grab all the appropriate files: my_files <- list.files(pattern = "\.csv$"). You can use regular expressions to match the files, read more about regular expressions in other questions if you need help there. This way you can grab all CSV files even if they don’t follow a nice naming scheme. Or you can use a fancier regex pattern if you need to pick certain CSV files out from a bunch of them.

At this point, most R beginners will use a for loop, and there’s nothing wrong with that, it works just fine.

my_data <- list()
for (i in seq_along(my_files)) {
    my_data[[i]]<- read.csv (file = my_files[i])}

Una forma más parecida a la de R es con lapply, que es un atajo para lo anterior

my_data <- lapply(my_files, read.csv)

Por supuesto, sustituya otra función de importación de datos por read.csv según sea apropiado. readr::read_csv o data.table::fread será más rápido, o es posible que también necesite una función diferente para un tipo de archivo diferente.

De cualquier manera, es útil nombrar los elementos de la lista para que coincidan con los archivos.

names(my_data) <- gsub("\.csv$", "", my_files)
# or, if you prefer the consistent syntax of stringr
names(my_data) <- stringr::str_replace(my_files, pattern = ".csv", replacement = "")

Dividir un marco de datos en una lista de marcos de datos

Esto es superfácil, la función básica split() lo hace por ti. Puede dividir por una columna (o columnas) de los datos, o por cualquier otra cosa que desee

mt_list = split(mtcars, f = mtcars$cyl)
# This gives a list of three data frames, one for each value of cyl

Esta también es una buena forma de dividir un marco de datos en pedazos para la validación cruzada. Tal vez quieras dividirte mtcars en piezas de capacitación, prueba y validación.

groups = sample(c("train", "test", "validate"),
                size = nrow(mtcars), replace = TRUE)
mt_split = split(mtcars, f = groups)
# and mt_split has appropriate names already!

Simular una lista de marcos de datos

Tal vez esté simulando datos, algo como esto:

my_sim_data = data.frame(x = rnorm(50), y = rnorm(50))

Pero, ¿quién hace una sola simulación? ¡Quieres hacer esto 100 veces, 1000 veces, más! Pero tu no quiere 10,000 marcos de datos en su espacio de trabajo. Usar replicate y ponerlos en una lista:

sim_list = replicate(n = 10,
                     expr = {data.frame(x = rnorm(50), y = rnorm(50))},
                     simplify = F)

Especialmente en este caso, también debe considerar si realmente necesita marcos de datos separados o si un solo marco de datos con una columna de "grupo" funcionaría igual de bien. Utilizando data.table o dplyr es bastante fácil hacer cosas "por grupo" en un marco de datos.

No puse mis datos en una lista 🙁 Lo haré la próxima vez, pero ¿qué puedo hacer ahora?

Si son un surtido extraño (lo cual es inusual), simplemente puede asignarlos:

mylist <- list()
mylist[[1]] <- mtcars
mylist[[2]] <- data.frame(a = rnorm(50), b = runif(50))
...

Si tiene marcos de datos nombrados en un patrón, por ejemplo, df1, df2, df3y los quiere en una lista, puede get ellos si puede escribir una expresión regular para que coincida con los nombres. Algo como

df_list = mget(ls(pattern = "df[0-9]"))
# this would match any object with "df" followed by a digit in its name
# you can test what objects will be got by just running the
ls(pattern = "df[0-9]")
# part and adjusting the pattern until it gets the right objects.

Generalmente, mget se utiliza para obtener varios objetos y devolverlos en una lista con nombre. Su contraparte get se usa para obtener un solo objeto y devolverlo (no en una lista).

Combinar una lista de marcos de datos en un solo marco de datos

Una tarea común es combinar una lista de marcos de datos en un marco de datos grandes. Si desea apilarlos uno encima del otro, usaría rbind para un par de ellos, pero para una lista de marcos de datos, aquí hay tres buenas opciones:

# base option - slower but not extra dependencies
big_data = do.call(what = rbind, args = df_list)

# data table and dplyr have nice functions for this that
#  - are much faster
#  - add id columns to identify the source
#  - fill in missing values if some data frames have more columns than others
# see their help pages for details
big_data = data.table::rbindlist(df_list)
big_data = dplyr::bind_rows(df_list)

(De manera similar usando cbind o dplyr::bind_cols para columnas.)

Para fusionar (unir) una lista de marcos de datos, puede ver estas respuestas. A menudo, la idea es utilizar Reduce con merge (o alguna otra función de unión) para juntarlos.

¿Por qué poner los datos en una lista?

Coloque datos similares en listas porque desea hacer cosas similares para cada marco de datos y funciones como lapply, sapply do.call, los purrr paquetey el viejo plyr l*ply Las funciones facilitan hacerlo. Los ejemplos de personas que hacen cosas fácilmente con listas están por todas partes.

Incluso si usa un bucle for simple, es mucho más fácil recorrer los elementos de una lista que construir nombres de variables con paste y acceder a los objetos con get. También es más fácil de depurar.

Pensar en escalabilidad. Si realmente solo necesita tres variables, está bien usar d1, d2, d3. Pero luego, si resulta que realmente necesitas 6, eso es mucho más tipeo. Y la próxima vez, cuando necesite 10 o 20, se encontrará copiando y pegando líneas de código, tal vez usando buscar / reemplazar para cambiar d14 para d15y tu estas pensando así no es como debería ser la programación. Si usa una lista, la diferencia entre 3 casos, 30 casos y 300 casos es como máximo una línea de código --- sin cambio en absoluto si su número de casos se detecta automáticamente por, por ejemplo, cuántos .csv los archivos están en su directorio.

Puede nombrar los elementos de una lista, en caso de que quiera usar algo que no sean índices numéricos para acceder a sus marcos de datos (y puede usar ambos, esta no es una opción de XOR).

En general, el uso de listas lo llevará a escribir un código más limpio y más fácil de leer, lo que resultará en menos errores y menos confusión.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

tkmenubutton

Python – Botón de menú Tkinter

hHY3SVmX7P89c6Lz5ehgxJ 1200 80

10 mejores alineaciones de los Vengadores de todos los tiempos