[Lenguajes: R]
Problema
Se tiene una lista de matrices, todas de las mismas dimensiones y se quiere realizar operaciones estadísticas, como la media o la desviación estándar, elemento a elemento. Por ejemplo, la media de todos los elementos con índices [1,1], [2,1], … [i,j], etc. Esto es, el resultado será una matriz, con las mismas dimensiones que cada una de las originales, pero que contendrá la media de los correspondientes elementos en cada una de las matrices.
Para entender el problema, propondré un ejemplo, como sigue:
a <- matrix(1:9, nrow=3) b <- matrix(2:10, nrow=3) c <- matrix(3:11, nrow=3) d <- matrix(4:12, nrow=3) L <- list(a,b,c,d) L
## [[1]]
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
##
## [[2]]
## [,1] [,2] [,3]
## [1,] 2 5 8
## [2,] 3 6 9
## [3,] 4 7 10
##
## [[3]]
## [,1] [,2] [,3]
## [1,] 3 6 9
## [2,] 4 7 10
## [3,] 5 8 11
##
## [[4]]
## [,1] [,2] [,3]
## [1,] 4 7 10
## [2,] 5 8 11
## [3,] 6 9 12
En el caso mostrado, la matriz resultante tendría igualmente 3 renglones y 3 columnas y si la operación que se desea efectuar es la media, por ejemplo, el elemento [3,1] de esa matriz debería contener el siguiente valor:
mean(c(L[[1]][3,1], L[[2]][3,1], L[[3]][3,1], L[[4]][3,1]))
## [1] 4.5
# O sea mean(c(3,4,5,6))
Esto, desde luego debería hacerse para todos y cada uno de los elementos. ¿Cómo hacer esta operación de manera sencilla?
Solución
El primer paso consiste en convertir la lista a un arreglo de 3 dimensiones, de la siguiente manera:
simplify2array(L)
## , , 1
##
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
##
## , , 2
##
## [,1] [,2] [,3]
## [1,] 2 5 8
## [2,] 3 6 9
## [3,] 4 7 10
##
## , , 3
##
## [,1] [,2] [,3]
## [1,] 3 6 9
## [2,] 4 7 10
## [3,] 5 8 11
##
## , , 4
##
## [,1] [,2] [,3]
## [1,] 4 7 10
## [2,] 5 8 11
## [3,] 6 9 12
Notemos ahora que, en este arreglo, los dos primeros índices corresponden a los índices de las matrices originales y el tercer índice, correspondería al orden de cada una de las matrices. De modo que lo que se tiene que hacer es aplicar una operación marginal mediante la función apply(), donde el margen donde queremos los resultados está dado por los índices 1 y 2.
Entonces el resultado que esperamos lo obtenemos fácilmente de la siguiente manera:
apply(simplify2array(L), MARGIN=1:2, FUN=mean)
## [,1] [,2] [,3]
## [1,] 2.5 5.5 8.5
## [2,] 3.5 6.5 9.5
## [3,] 4.5 7.5 10.5
Es fácil ver que cualquier otra operación es aplicable, por ejemplo, la sumatoria, sum():
apply(simplify2array(L), MARGIN=1:2, FUN=sum)
## [,1] [,2] [,3]
## [1,] 10 22 34
## [2,] 14 26 38
## [3,] 18 30 42
Con esto se concluye la solución del problema.
No hay comentarios.:
Publicar un comentario