La familia de funciones apply pertenecen al paquete base de R, son de especial utilidad al combinar su uso con funciones para manipular porciones de matrices, arreglos, listas y marcos de datos de una manera repetitiva. Estas funciones permiten cruzar los datos de múltiples maneras para así evadir el uso de ciclos que usualmente son computacionalmente más pesados.
La primera función de la que hablaremos en esta serie es la función apply()
, la cual en su forma de utilización más sencilla se utiliza para evaluar sobre los márgenes (1=filas ó 2=columnas) de un arreglo o una matriz para aplicar una función a las mismas.
Como primer ejemplo se parte de una matriz con tres filas y tres columnas.
mat <- matrix(c(2, 4, 6, 7, 8, 9, 1, 12, 21), nrow = 3, ncol = 3)
mat
## [,1] [,2] [,3]
## [1,] 2 7 1
## [2,] 4 8 12
## [3,] 6 9 21
Si se desea, por ejemplo, obtener la suma de cada columna puede usarse la función apply()
de la siguiente manera.
apply(mat, 2, sum)
## [1] 12 24 34
O bien, puede calcularse si se desea el promedio de cada una de las filas.
apply(mat, 1, mean)
## [1] 3.333333 8.000000 12.000000
Existen además algunas funciones ya programadas en el paquete base
de R que replican rápidamente los resultados anteriores. Por ejemplo está la función colSums()
para calcular la cuma de cada columna, y rowMeans()
para obtener la media aritmética de cada fila.
colSums(mat)
## [1] 12 24 34
rowMeans(mat)
## [1] 3.333333 8.000000 12.000000
Los dos casos mostrados anteriormente ejemplifican un uso básico de la función apply()
, sin embargo, esta función es mucho más potente y es capaz de trabajar de manera multidimensional. Consideremos, por ejemplo, un objeto en dos dimensiones (filas y columnas) similar al creado con anterioridad, es decir, una matriz.
mat2 <- matrix(1:9, nrow = 3, ncol = 3)
mat2
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
El objeto mat2
representa un caso particular de lo que en R se conoce como arreglos, los cuales pueden ser creados mediante la función array()
.
array(data=1:9, dim = c(3,3))
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
La función array()
también permite agregar etiquetas a las filas y las columnas mediante su argumento dimnames
.
nombres.columnas <- c("COL1","COL2","COL3")
nombres.filas <- c("FILA1","FILA2","FILA3")
arreglo <- array(data=1:9, dim = c(3,3),
dimnames = list(nombres.columnas, nombres.filas))
arreglo
## FILA1 FILA2 FILA3
## COL1 1 4 7
## COL2 2 5 8
## COL3 3 6 9
Pueden agregarse varias dimensiones a los arreglos. Para esto, supongamos que se desean tener las siguientes dimensiones:
- DIM1: Números del 1 al 9.
- DIM2: Números del 1 al 9 multiplicados por 10.
- DIM3: Números del 1 al 9 multiplicados por 100.
- DIM4: Números del 1 al 9 multiplicados por 1000.
Una forma de generar el arreglo anterior es mediante el siguiente código:
nombres.dimensiones <- c("DIM1","DIM2","DIM3","DIM4")
arreglo <- array(data = c(seq(from=1, to=9, by=1), #1 al 9
seq(from=10, to=90, by=10), #10 al 90
seq(from=100, to=900, by=100), #100 al 900
seq(from=1000, to=9000, by=1000)), #1000 al 9000
dim = c(3, 3, 4), #3 filas, 3 columnas y 4 dimensiones
dimnames = list(nombres.filas,
nombres.columnas,
nombres.dimensiones))
arreglo
## , , DIM1
##
## COL1 COL2 COL3
## FILA1 1 4 7
## FILA2 2 5 8
## FILA3 3 6 9
##
## , , DIM2
##
## COL1 COL2 COL3
## FILA1 10 40 70
## FILA2 20 50 80
## FILA3 30 60 90
##
## , , DIM3
##
## COL1 COL2 COL3
## FILA1 100 400 700
## FILA2 200 500 800
## FILA3 300 600 900
##
## , , DIM4
##
## COL1 COL2 COL3
## FILA1 1000 4000 7000
## FILA2 2000 5000 8000
## FILA3 3000 6000 9000
Partiendo del arreglo anterior, supongamos que se desea obtener de cada dimensión el valor máximo por filas.
apply(arreglo, c(3,1), max)
## FILA1 FILA2 FILA3
## DIM1 7 8 9
## DIM2 70 80 90
## DIM3 700 800 900
## DIM4 7000 8000 9000
O bien, quizás interese obtener de cada dimensión el valor máximo de cada columna.
apply(arreglo, c(3,2), max)
## COL1 COL2 COL3
## DIM1 3 6 9
## DIM2 30 60 90
## DIM3 300 600 900
## DIM4 3000 6000 9000
El siguiente resultado muestra el mínimo de cada columna en cada dimensión.
apply(arreglo, c(2,3), min)
## DIM1 DIM2 DIM3 DIM4
## COL1 1 10 100 1000
## COL2 4 40 400 4000
## COL3 7 70 700 7000
Los ejemplos anteriores pueden ser aplicados a un número mayor de dimensiones, para ello basta con tener un arreglo adecuado y operar sobre los márgenes correspondientes con la función apply()
.