¿Cómo hago una lista de marcos de datos y cómo accedo a cada uno de esos marcos de datos de la lista?
Por ejemplo, ¿cómo puedo poner estos marcos de datos en una lista?
d1 <- data.frame(y1 = c(1, 2, 3),
y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1),
y2 = c(6, 5, 4))
=
no lo uses<-
dentrodata.frame()
. Al usar<-
creay1
yy2
en su entorno global y su marco de datos no es lo que quiere que sea.<-
ys dentro de data.frame (). Qué nuevo era yo.Respuestas:
Esto no está relacionado con su pregunta, pero desea usarlo
=
y no<-
dentro de la llamada a la función. Si lo usa<-
, terminará creando variablesy1
yy2
en cualquier entorno en el que esté trabajando:Esto no tendrá el efecto aparentemente deseado de crear nombres de columna en el marco de datos:
El
=
operador, por otro lado, asociará sus vectores con argumentos paradata.frame
.En cuanto a su pregunta, es fácil hacer una lista de marcos de datos:
Accede a los marcos de datos como accedería a cualquier otro elemento de la lista:
fuente
Las otras respuestas le muestran cómo hacer una lista de data.frames cuando ya tiene un montón de data.frames, p. Ej
d1
.d2
, ... Tener cuadros de datos con nombre secuencial es un problema, y ponerlos en una lista es un buena solución, pero la mejor práctica es evitar tener un montón de data.frames que no están en una lista en primer lugar.Las otras respuestas brindan muchos detalles sobre cómo asignar marcos de datos para enumerar elementos, acceder a ellos, etc. También cubriremos eso un poco aquí, pero el punto principal es decir que no espere hasta que tenga un montón de
data.frames
para agregarlos a una lista. Comience con la lista.El resto de esta respuesta cubrirá algunos casos comunes en los que podría verse tentado a crear variables secuenciales y le mostrará cómo ir directamente a las listas. Si eres nuevo en las listas en R, es posible que también quieras leer ¿Cuál es la diferencia entre
[[
y[
al acceder a los elementos de una lista? .Listas desde el principio
Nunca crees
d1
d2
d3
, ...,dn
en primer lugar. Crea una listad
conn
elementos.Leer múltiples archivos en una lista de marcos de datos
Esto se hace con bastante facilidad al leer en archivos. Tal vez tienes archivos
data1.csv, data2.csv, ...
en un directorio. Su objetivo es una lista de data.frames llamadosmydata
. Lo primero que necesita es un vector con todos los nombres de archivo. Puede construir este con pasta (por ejemplo,my_files = paste0("data", 1:5, ".csv")
), pero es probable que sea más fácil de usarlist.files
para agarrar todos los archivos correspondientes:my_files <- list.files(pattern = "\\.csv$")
. Puede usar expresiones regulares para hacer coincidir los archivos, leer más sobre expresiones regulares en otras preguntas si necesita ayuda allí. De esta manera, puede tomar todos los archivos CSV, incluso si no siguen un buen esquema de nombres. O puede usar un patrón de expresiones regulares más sofisticado si necesita seleccionar ciertos archivos CSV de entre muchos de ellos.En este punto, la mayoría de los principiantes de R usarán un
for
bucle, y no hay nada de malo en eso, funciona bien.Una forma más similar a R es hacerlo con
lapply
, que es un atajo para lo anteriorPor supuesto, sustituya otra función de importación de datos
read.csv
según corresponda.readr::read_csv
odata.table::fread
será más rápido, o también puede necesitar 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
División de un marco de datos en una lista de marcos de datos
Esto es súper fácil, la función base lo
split()
hace por usted. Puede dividir por una columna (o columnas) de los datos, o por cualquier otra cosa que deseeEsta también es una buena manera de dividir un marco de datos en partes para la validación cruzada. Tal vez quieras dividirte
mtcars
en piezas de entrenamiento, prueba y validación.Simulando una lista de marcos de datos
Tal vez estás simulando datos, algo como esto:
¿Pero quién hace una sola simulación? ¡Quieres hacer esto 100 veces, 1000 veces, más! Pero no desea 10,000 marcos de datos en su espacio de trabajo. Úselos
replicate
y póngalos en una lista:En este caso especialmente, 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. Usar
data.table
odplyr
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 una variedad extraña (lo cual es inusual), simplemente puede asignarlos:
Si usted tiene marcos de datos con nombre en un patrón, por ejemplo,
df1
,df2
,df3
, y usted los quiere en una lista, puedeget
que si se puede escribir una expresión regular para coincidir con los nombres. Algo comoEn general,
mget
se usa para obtener varios objetos y devolverlos en una lista con nombre. Su contraparteget
se usa para obtener un solo objeto y devolverlo (no en una lista).Combinando 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 gran marco de datos. Si desea apilarlos uno encima del otro, los usaría
rbind
para un par de ellos, pero para una lista de marcos de datos aquí hay tres buenas opciones:(Del mismo modo usando
cbind
odplyr::bind_cols
para columnas).Para fusionar (unir) una lista de marcos de datos, puede ver estas respuestas . A menudo, la idea es usar
Reduce
conmerge
(o alguna otra función de unión) para unirlos.¿Por qué poner los datos en una lista?
Poner los datos similares en las listas porque quiere hacer cosas similares a cada trama de datos, y funciones como
lapply
,sapply
do.call
, elpurrr
paquete , y las antiguasplyr
l*ply
funciones hacen que sea fácil para hacer eso. Ejemplos de personas que hacen cosas fácilmente con listas están en todo SO.Incluso si usa un bucle for bajo, es mucho más fácil recorrer los elementos de una lista que construir nombres de variables
paste
y acceder a los objetos con ellosget
. Más fácil de depurar, también.Piensa en la escalabilidad . Si realmente necesita solamente tres variables, está bien para su uso
d1
,d2
,d3
. Pero si resulta que realmente necesitas 6, eso es mucho más escribir. Y la próxima vez, cuando se necesita 10 o 20, usted se encuentra copiar y pegar líneas de código, tal vez el uso de buscar / reemplazar al cambiod14
ad15
, y que está pensando que esto no es la forma en la programación debe ser . 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 ningún cambio si su número de casos se detecta automáticamente, por ejemplo, cuántos.csv
archivos hay en su directorio.Puede nombrar los elementos de una lista, en caso de que quiera usar algo más que índices numéricos para acceder a sus marcos de datos (y puede usar ambos, esta no es una opción XOR).
En general, el uso de listas lo llevará a escribir un código más limpio y fácil de leer, lo que dará como resultado menos errores y menos confusión.
fuente
r
ylist
.my_data <- NULL
lugar de `my_data <- list () '. :)my_data <- list()
deja en claro que está creando una lista, ¡lo cual es bueno! El código claro es algo bueno. No veo ninguna ventaja de usar en sumy_data <- NULL
lugar.names(my_data) <- gsub("\\.csv$", "", my_files)
;) <br> Pero respeto sus consejos ya que estoy aprendiendo mucho de ellos como novato y realmente lo aprecio :)También puede acceder a columnas y valores específicos en cada elemento de la lista con
[
y[[
. Aquí hay un par de ejemplos. Primero, podemos acceder solo a la primera columna de cada marco de datos en la lista conlapply(ldf, "[", 1)
, donde1
significa el número de columna.Del mismo modo, podemos acceder al primer valor en la segunda columna con
Entonces también podemos acceder a los valores de la columna directamente, como un vector, con
[[
fuente
Si tiene una gran cantidad de marcos de datos con nombre secuencial, puede crear una lista del subconjunto deseado de marcos de datos como este:
donde
my.list2
devuelve una lista que contiene los marcos de datos segundo, tercero y cuarto.Sin embargo, tenga en cuenta que los marcos de datos en la lista anterior ya no se nombran. Si desea crear una lista que contenga un subconjunto de marcos de datos y desea preservar sus nombres, puede intentar esto:
que devuelve:
fuente
lapply(foo, get)
, simplemente usemget(foo)
Teniendo en cuenta que tiene un "gran" número de marcos de datos con nombres similares (aquí d # donde # es un número entero positivo), la siguiente es una ligera mejora del método de @ mark-miller. Es más conciso y devuelve una lista con nombre de data.frames, donde cada nombre en la lista es el nombre del correspondiente data.frame original.
La clave está usando
mget
junto conls
. Si los marcos de datos d1 y d2 proporcionados en la pregunta eran los únicos objetos con nombres d # en el entorno, entoncesque volvería
Este método aprovecha el argumento de patrón en
ls
, que nos permite usar expresiones regulares para hacer un análisis más preciso de los nombres de los objetos en el entorno. Una alternativa a la expresión regular"^d[0-9]+$"
es"^d\\d+$"
.Como @gregor señala , es mejor en general configurar su proceso de construcción de datos para que los data.frames se coloquen en listas con nombre al principio.
datos
fuente
Esto puede ser un poco tarde, pero volviendo a su ejemplo, pensé que ampliaría la respuesta solo un poco.
Entonces haces tu lista fácilmente:
Ahora tiene una lista, pero en lugar de acceder a la lista de la manera anterior, como
puede usar esta función para obtener y asignar el marco de datos de su elección.
Ahora consigue el que quieres.
Espero que ese bit extra ayude.
¡Salud!
fuente
GETDF_FROMLIST(mylist, 1)
hacerlomylist[[1]]
? Si prefiere la sintaxis de la función, incluso podría hacerlo"[["(mylist, 1)
sin definir una función personalizada.return(DF_LIST[[ITEM_LOC]])
, sin necesidad de asignar una variable intermedia.Muy simple ! Aquí está mi sugerencia:
Si desea seleccionar marcos de datos en su espacio de trabajo, intente esto:
o
todo esto dará el mismo resultado.
Puede cambiar
is.data.frame
para verificar otros tipos de variables comois.function
fuente
Me considero un novato completo, pero creo que tengo una respuesta extremadamente simple a una de las preguntas originales que no se ha mencionado aquí: acceder a los marcos de datos, o partes de ellos.
Comencemos creando la lista con marcos de datos como se indicó anteriormente:
Luego, si desea acceder a un valor específico en uno de los marcos de datos, puede hacerlo utilizando los corchetes dobles secuencialmente. El primer conjunto lo lleva al marco de datos, y el segundo conjunto lo lleva a las coordenadas específicas:
fuente