En muchas ocasiones es necesario calcular un determinado estadístico en función de una o varias variables, con el fin de poder establecer comparaciones entre esos subconjuntos.
En este tema abordamos el cálculo de estadísticos descriptivos aplicados a subconjuntos de datos, utilizando herramientas modernas del ecosistema tidyverse, principalmente:
filter()
select()
group_by()
summarise()
mutate()
count()
arrange()
Estas funciones sustituyen a las tradicionales subset(),
aggregate(), tapply() y otras de base R.
Por ejemplo, imaginemos la siguiente una base de datos. En primer lugar, generaremos la base de datos con esas variables.
⚠️ ESTABLECER SEMILLA:
Para que los resultados de algunos cálculos sean idénticos a los mostrados en la página web, es necesario iniciar cada actividad estableciendo una semilla que asegure su reproducibilidad.
set.seed(123)
library(dplyr)
dataset <- data.frame(contaminante = round(rnorm(100, sd = 10, mean = 30)),
estacion = sample(c("invierno","primavera","verano", "otoño"), size = 100, replace = TRUE),
localidad = sample(paste("localidad", 1:4),
size = 100,
replace = TRUE))
head(dataset)
## contaminante estacion localidad
## 1 24 primavera localidad 2
## 2 28 primavera localidad 2
## 3 46 otoño localidad 1
## 4 31 invierno localidad 2
## 5 31 otoño localidad 1
## 6 47 otoño localidad 1
str(dataset)
## 'data.frame': 100 obs. of 3 variables:
## $ contaminante: num 24 28 46 31 31 47 35 17 23 26 ...
## $ estacion : chr "primavera" "primavera" "otoño" "invierno" ...
## $ localidad : chr "localidad 2" "localidad 2" "localidad 1" "localidad 2" ...
Esta base de datos contiene las siguiente variables:
Valores de contaminación.
Estación del año.
Localidad en la que están situadas esas estaciones.
Existen diferentes posibilidades para calcular esos valores desagregados según otras variables.
Por ejemplo, para el cálculo de la concentracion de contaminantes según la estación del año.
dataset %>%
group_by(estacion) %>%
summarise(
media = mean(contaminante),
sd = sd(contaminante),
n = n(),
.groups = "drop")
## # A tibble: 4 × 4
## estacion media sd n
## <chr> <dbl> <dbl> <int>
## 1 invierno 29.6 9.72 32
## 2 otoño 34.0 8.85 25
## 3 primavera 30.5 8.65 24
## 4 verano 29.6 8.86 19
Una alternativa es calcular el promedio y la desviación típica según la localidad
dataset %>%
group_by(localidad) %>%
summarise(
media = mean(contaminante),
sd = sd(contaminante),
n = n(),
.groups = "drop"
)
## # A tibble: 4 × 4
## localidad media sd n
## <chr> <dbl> <dbl> <int>
## 1 localidad 1 29.9 8.66 37
## 2 localidad 2 30.3 8.67 25
## 3 localidad 3 31.4 12.4 20
## 4 localidad 4 33.4 6.42 18
Y también podríamos calcular el promedio por estación y localidad
dataset %>%
group_by(estacion, localidad) %>%
summarise(
media = mean(contaminante),
sd = sd(contaminante),
n = n(),
.groups = "drop"
)
## # A tibble: 16 × 5
## estacion localidad media sd n
## <chr> <chr> <dbl> <dbl> <int>
## 1 invierno localidad 1 30.7 9.57 10
## 2 invierno localidad 2 26.1 9.31 8
## 3 invierno localidad 3 26.6 11.9 7
## 4 invierno localidad 4 34.9 6.82 7
## 5 otoño localidad 1 31.6 8.36 13
## 6 otoño localidad 2 41 9.90 2
## 7 otoño localidad 3 39.7 13.1 3
## 8 otoño localidad 4 34.1 7.45 7
## 9 primavera localidad 1 28 8.41 4
## 10 primavera localidad 2 28.7 5.66 10
## 11 primavera localidad 3 33.9 12.3 8
## 12 primavera localidad 4 31.5 2.12 2
## 13 verano localidad 1 27.5 8.86 10
## 14 verano localidad 2 35.8 8.14 5
## 15 verano localidad 3 26.5 13.4 2
## 16 verano localidad 4 28 0 2
La opción .groups = “drop” dentro de summarise()
controla qué ocurre con los grupos después de resumir.Cuando ejecutamos
summarise() el resultado sigue estando “agrupado” por
estacion, aunque ya solo queda una fila por grupo. Esto a veces no es
deseable, porque:
puede afectar a operaciones posteriores (por ejemplo, otro summarise(), mutate(), etc.)
puede generar advertencias
puede causar confusión en pipelines largos
El argumento groups = "drop" le indica a dplyr que
desagrupes completamente el resultado después del resumen.
Si quisiéramos calcular los deciles extremos la sintaxis sería la siguiente:
dataset %>%
group_by(localidad) %>%
summarise(
decil_10 = quantile(contaminante, 0.10, na.rm = TRUE),
decil_90 = quantile(contaminante, 0.90, na.rm = TRUE),
.groups = "drop")
## # A tibble: 4 × 3
## localidad decil_10 decil_90
## <chr> <dbl> <dbl>
## 1 localidad 1 19.6 41
## 2 localidad 2 19.4 41.2
## 3 localidad 3 16.6 45.7
## 4 localidad 4 26.1 41.3
media_2_factores <- dataset %>%
group_by(estacion, localidad) %>%
summarise(
media_contaminante = mean(contaminante, na.rm = TRUE),
.groups = "drop")
diferentes_estadisticos <- dataset %>%
group_by(estacion, localidad) %>%
summarise(
suma = sum(contaminante, na.rm = TRUE),
media = mean(contaminante, na.rm = TRUE),
sd = sd(contaminante, na.rm = TRUE),
.groups = "drop")
📝 ACTIVIDAD DE EVALUACIÓN CONTINUA:
EJERCICIO 1. A partir del dataframe zonas_verdes
calcula:
El número total de parques en cada barrio
La superficie media, la superficie mediana, los percentiles 25 y 75, la desviación típica y el coeficiente de variación de la superficie según barrios.
El número máximo y mínimo de parques en obras/sin obras según barrio.
EJERCICIO 2.
A partir del dataframe airquality calcula el valor
medio mensual de las variables Temp, Ozone,
Solar.R y Wind.
Filtrar los días con Ozone mayor de 100
Filtrar los días de julio y agosto con Wind < 10
Seleccionar solo Ozone, Wind y Temp
Seleccionar todas las variables menos Solar.R
Crear una variable que indique si la temperatura es alta (>85°F)
Crear un índice de confort térmico (Temp / Wind)
Calcular la media, mediana y desviación típica mensual del ozono
Calcular el número de días válidos (no NA) por mes y por variable
Encontrar el día más cálido de cada mes
Encontrar el día con el ozono mínimo de cada mes
Ordenar los días por contaminación (Ozone) de mayor a menor
Rellenar los valores NA de Ozone con la media mensual
Calcular el rango intercuartílico de Temp por mes
Detectar valores atípicos de Ozone usando 1.5 × IQR
Estandarizar cada variable numérica
Obtener el total de días con Temp > 90 por mes
Crear categorías de ozono: bajo, medio, alto (terciles)
Calcular medias mensuales para todas las variables con across()
Calcular anomalías respecto a la media mensual (valor – media del mes)
Filtrar los días con Ozone mayor de 100