varias - Media de elementos en una lista de datos.
superponer graficas en r (6)
¿No puedes usar llamadas lapply()
anidadas?
Esto parece dar el resultado correcto en mi máquina.
mean.dat <- lapply(all.dat, function (x) lapply(x, mean, na.rm=TRUE))
Supongamos que tengo una lista de data.frames (de filas y columnas iguales)
dat1 <- as.data.frame(matrix(rnorm(25), ncol=5))
dat2 <- as.data.frame(matrix(rnorm(25), ncol=5))
dat3 <- as.data.frame(matrix(rnorm(25), ncol=5))
all.dat <- list(dat1=dat1, dat2=dat2, dat3=dat3)
¿Cómo puedo devolver un único data.frame que sea la media (o suma, etc.) para cada elemento en los data.frames en la lista (por ejemplo, la media de la primera fila y la primera columna de las listas 1, 2, 3 y así sucesivamente)? en)? He probado lapply
y ldply
en plyr
pero estos devuelven la estadística para cada data.frame dentro de la lista.
Edit: Por alguna razón, esto fue reetiquetado como tarea. No es que importe de ninguna manera, pero esto no es una pregunta de tarea. Simplemente no sé por qué no puedo hacer que esto funcione. Gracias por cualquier idea!
Edit2: Para mayor aclaración: puedo obtener los resultados utilizando bucles, pero esperaba que hubiera una manera (una forma más simple y rápida porque los datos que estoy usando tienen data.frames que son de 12 filas por 100 columnas y hay un lista de más de 1000 de estos marcos de datos).
z <- matrix(0, nrow(all.dat$dat1), ncol(all.dat$dat1))
for(l in 1:nrow(all.dat$dat1)){
for(m in 1:ncol(all.dat$dat1)){
z[l, m] <- mean(unlist(lapply(all.dat, `[`, i =l, j = m)))
}
}
Con un resultado de los medios:
> z
[,1] [,2] [,3] [,4] [,5]
[1,] -0.64185488 0.06220447 -0.02153806 0.83567173 0.3978507
[2,] -0.27953054 -0.19567085 0.45718399 -0.02823715 0.4932950
[3,] 0.40506666 0.95157856 1.00017954 0.57434125 -0.5969884
[4,] 0.71972821 -0.29190645 0.16257478 -0.08897047 0.9703909
[5,] -0.05570302 0.62045662 0.93427522 -0.55295824 0.7064439
Me preguntaba si habría una forma menos torpe y más rápida de hacer esto. ¡Gracias!
Aquí hay un trazador de líneas con plyr
. Puede reemplazar el mean
con cualquier otra función que desee.
ans1 = aaply(laply(all.dat, as.matrix), c(2, 3), mean)
Di una respuesta que utiliza una estructura de datos completamente diferente para lograr el resultado. Esta respuesta utiliza la estructura de datos (lista de marcos de datos) dada directamente. Creo que es menos elegante, pero quería proporcionarlo de todos modos.
Reduce(`+`, all.dat) / length(all.dat)
La lógica es agregar los marcos de datos elemento por elemento (lo que +
hará con los marcos de datos), luego dividir por el número de marcos de datos. Usar Reduce
es necesario ya que +
solo puede tomar dos argumentos a la vez (y la adición es asociativa).
Le resultaría más fácil cambiar la estructura de los datos, combinando las tres matrices bidimensionales en una única matriz tridimensional (utilizando la abind
biblioteca). Entonces, la solución es más directa si se apply
y se especifican las dimensiones para promediar.
EDITAR:
Cuando respondí la pregunta, estaba etiquetada como homework
, por lo que acabo de dar un enfoque. El póster original eliminó esa etiqueta, por lo que le diré que no es así.
library("abind")
all.matrix <- abind(all.dat, along=3)
apply(all.matrix, c(1,2), mean)
Otro enfoque que usa solo funciones base
para cambiar la estructura del objeto:
listVec <- lapply(all.dat, c, recursive=TRUE)
m <- do.call(cbind, listVec)
Ahora puedes calcular la mean
con rowMeans
o la median
con apply
:
means <- rowMeans(m)
medians <- apply(m, 1, median)
Tomaría un enfoque ligeramente diferente:
library(plyr)
tmp <- ldply(all.dat) # convert to df
tmp$counter <- 1:5 # 1:12 for your actual situation
ddply(tmp, .(counter), function(x) colMeans(x[2:ncol(x)]))