5.1 For loop y familia Apply
La familia de funciones apply pertenece a la librería base
en R y facilitan la manipulación de datos de forma repetitiva.
Las funciones de esta familia son: apply(), lapply(), sapply(), vapply()
, mapply()
, rapply()
, and tapply()
.
En este taller solo se verán las primeras tres funciones.
5.1.1 apply()
Esta es la función que manipula arreglos homogéneos, en particular, se revisa el caso de matrices que son arreglos de dos dimensiones.
La función tiene los siguientes argumentos: apply(X, MARGIN, FUN, ...)
X
representa el arreglo de dos dimensiones.MARGIN
representa la dimensión sobre la que se va a resumir la información. Donde 1 = renglon o primera dimensión y 2 = columna o segunda dimensión.FUN
representa la función que resume la información.
Tomemos la siguiente matriz de simulaciones
set.seed(1)
mat_norm <- matrix(rnorm(24, mean = 0, sd = 1), nrow = 4, ncol = 6)
mat_norm
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] -0.6264538 0.3295078 0.5757814 -0.62124058 -0.01619026 0.91897737
## [2,] 0.1836433 -0.8204684 -0.3053884 -2.21469989 0.94383621 0.78213630
## [3,] -0.8356286 0.4874291 1.5117812 1.12493092 0.82122120 0.07456498
## [4,] 1.5952808 0.7383247 0.3898432 -0.04493361 0.59390132 -1.98935170
Deseamos obtener la suma de cada columna de la matriz.
El primer método, quizá el mas intuitivo en este momento, es obtener cada elemento o columna, aplicar la función a cada elemento y concatenar:
prom_col_m1 <- c(sum(mat_norm[, 1]),
sum(mat_norm[, 2]),
sum(mat_norm[, 3]),
sum(mat_norm[, 4]),
sum(mat_norm[, 5]),
sum(mat_norm[, 6]))
prom_col_m1
## [1] 0.3168417 0.7347931 2.1720174 -1.7559432 2.3427685 -0.2136730
Segundo método
prom_col_m2 <- vector( length = ncol(mat_norm))
for(j in 1:ncol(mat_norm)){
prom_col_m2[j] <- sum(mat_norm[, j])
}
prom_col_m2
## [1] 0.3168417 0.7347931 2.1720174 -1.7559432 2.3427685 -0.2136730
Tercer método
prom_col_m3 <- apply(X = mat_norm, MARGIN = 2, FUN = sum)
prom_col_m3
## [1] 0.3168417 0.7347931 2.1720174 -1.7559432 2.3427685 -0.2136730
Cuarto método
prom_col_m4 <- colSums(mat_norm)
prom_col_m4
## [1] 0.3168417 0.7347931 2.1720174 -1.7559432 2.3427685 -0.2136730
Ahora, para obtener la suma por renglón usando el tercer método de la función apply()
, únicamente es necesario cambiar la dimensión sobre la que voy a resumir con el argumento MARGIN = 1
.
prom_row_m3 <- apply(mat_norm, 1, sum)
prom_row_m3
## [1] 0.5603818 -1.4309408 3.1842987 1.2830648
Que es equivalente al primer método que usamos.
prom_row_m1 <- c(sum(mat_norm[1, ]),
sum(mat_norm[2, ]),
sum(mat_norm[3, ]),
sum(mat_norm[4, ]))
prom_row_m1
## [1] 0.5603818 -1.4309408 3.1842987 1.2830648
La ventaja de usar la función apply()
es que se puede usar cualquier función. Por ejemplo, obtener la desviación estándar.
apply(mat_norm, 1, sd)
## [1] 0.6341809 1.1718660 0.8338847 1.2066403
O bien, una crear una función propia (definida por el usuario) con la función function()
cv_vec_m3 <- apply(mat_norm, 1, function(reng){
cv <- mean(reng)/sd(reng)
return(cv)
})
cv_vec_m3
## [1] 0.1472718 -0.2035131 0.6364386 0.1772228
Funciones Anónimas:
A este tipo de funciones se les llama funciones anónimas porque no se nombran ni guardan en el ambiente de R y únicamente funcionan dentro del comando que las llama.5.1.2 lapply()
La función lapply()
aplica una función sobre una lista o un vector y regresa el resultado en otra lista.
Usando el vector de ciudades,
ciudades_vec <- c("Aguascalientes", "Monterrey", "Guadalajara", "México")
ciudades_vec
## [1] "Aguascalientes" "Monterrey" "Guadalajara" "México"
res_nchar_l <- lapply(ciudades_vec, nchar)
res_nchar_l
## [[1]]
## [1] 14
##
## [[2]]
## [1] 9
##
## [[3]]
## [1] 11
##
## [[4]]
## [1] 6
La función lapply()
permite incluir argumentos de las funciones que implementa. Estos argumentos se incluyen dentro de lapply()
después de la función a implementar.
Por ejemplo, usamos la función potencia que se creó antes.
potencia_fun <- function(base, exponente){
base^exponente
}
El objetivo es aplicar a cada elemento de la siguiente lista la función potencia y elevarlo al cubo.
nums_lista <- list(1, 3, 4)
nums_lista
## [[1]]
## [1] 1
##
## [[2]]
## [1] 3
##
## [[3]]
## [1] 4
En la función lapply()
se agrega el argumento exponente = 3
como último argumento.
potencia_lista <- lapply(nums_lista, potencia_fun, exponente = 3)
potencia_lista
## [[1]]
## [1] 1
##
## [[2]]
## [1] 27
##
## [[3]]
## [1] 64
Una forma de reducir la lista obtenida a un vector es con la función unlist()
que vimos antes.
unlist(potencia_lista)
## [1] 1 27 64
5.1.3 sapply()
La función sapply()
es muy similar a lapply()
. La única diferencia es la s que surge de simplified apply.
Al igual que lapply()
aplica una función sobre una lista o un vector pero simplifica el resultado en un arreglo.
res_nchar_s <- sapply(ciudades_vec, nchar)
res_nchar_s
## Aguascalientes Monterrey Guadalajara México
## 14 9 11 6
lapply()
.