El trabajo actual ha sido realizado con fines de estudio, para poder ver el impacto que tienen los outliers sobre la media, mediana y moda.
Número de variables: 2
Número de observaciones: 100
Calcular y representar gráficamente la media, mediana y moda
Visualizar y comprender el impacto que tienen los outliers sobre la media, mediana y moda.
Instalamos los paquetes y cargamos las librerías necesarias.
# Install necessary packages and libraries
#install.packages("tidyverse")
#install.packages("ggplot2")
#install.packages("dplyr")
library(readr)
library(dplyr)
library(ggplot2)
# Read raw
mark <- c(6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
27, 28, 30, 31, 32, 36, 37, 38, 40, 41,
42, 44, 46, 50, 51, 52, 53, 54)
freqs <- c(5, 3, 3, 4, 2, 4, 3, 4, 2, 1,
3, 5, 4, 4, 5, 2, 2, 2, 6, 1,
2, 2, 1, 3, 1, 1, 2, 2, 4, 3,
2, 2, 1, 1, 3, 1, 3, 1)
mark <- rep(mark, freqs)
df <- data.frame(
student = as.character(seq(1, 100)),
mark = mark
)
# First six lines of the df
head(df)
# Internal structure of the df
glimpse(df)
Rows: 100
Columns: 2
$ student <chr> "1", "2", "3", "4", "5", "6", "7", "8…
$ mark <dbl> 6, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9…
# Statistical summary
summary(df)
student mark
Length:100 Min. : 6.00
Class :character 1st Qu.:13.00
Mode :character Median :20.00
Mean :24.08
3rd Qu.:36.25
Max. :54.00
# Test for NAs
anyNA(df)
[1] FALSE
sum(is.na(df))
[1] 0
# Freq by obs
table(df$mark)
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
5 3 3 4 2 4 3 4 2 1 3 5 4 4 5 2 2 2
24 25 27 28 30 31 32 36 37 38 40 41 42 44 46 50 51 52
6 1 2 2 1 3 1 1 2 2 4 3 2 2 1 1 3 1
53 54
3 1
# Looking for outliers
boxplot(df$mark)
# How's the data
hist(df$mark)
# How's the data
plot(density(df$mark))
Cálculo de la media, mediana y moda respecto a la variable mark.
# Calculate mean
media <- mean(df$mark, na.rm = TRUE)
print(round(media,1))
[1] 24.1
# Calculate median
mediana <- median(df$mark, na.rm = TRUE)
print(round(mediana, 1))
[1] 20
# Calculate mode
# In a bimodal or multimodal situation, it only returns the lowest mode.
freq_table <- table(df$mark)
moda <- min(as.numeric(names(freq_table)[freq_table == max(freq_table)]))
print(round(moda, 1))
[1] 24
ggplot(df, aes(x = mark)) +
geom_histogram(binwidth = 7, fill = "lightgray", color = "gray36") +
# Media
geom_vline(aes(xintercept = media), color = "#CD6090", linetype = "dashed", size = 1) +
annotate("text", x = media + 2, y = 8, label = paste("Media = ", round(media, 1)), color = "#CD6090") +
# Mediana
geom_vline(aes(xintercept = mediana), color = "#008B45", linetype = "dashed", size = 1) +
annotate("text", x = mediana + 2, y = 10, label = paste("Mediana = ", round(mediana, 1)), color = "#008B45") +
# Moda
geom_vline(aes(xintercept = moda), color = "#4169E1", linetype = "dashed", size = 1) +
annotate("text", x = moda + 2, y = 12, label = paste("Moda = ", round(moda, 1)), color = "#4169E1") +
# Etiquetas
labs(title = "Frecuencia de puntajes con medidas de localización", x = "Puntaje", y = "Frecuencia") +
# Fondo personalizado
theme(
panel.background = element_rect(fill = "#FFF8DC"), # Fondo del panel
plot.background = element_rect(fill = "#FFF8DC"), # Fondo total del gráfico
panel.grid.major = element_line(color = "#FFF8DC"), # Líneas de cuadrícula principales
panel.grid.minor = element_line(color = "#FFF8DC") # Líneas de cuadrícula menores
)
# Copy the df
df_outliers <- df
# Add outliers
df_outliers <- rbind(df_outliers, data.frame(
student = c("a", "b"),
mark = c(100, 99)
)
)
# Show the changes
tail(df_outliers)
# Calculate mean
media_out <- mean(df_outliers$mark, na.rm = TRUE)
print(round(media_out, 1))
[1] 25.6
# Calculate median
mediana_out <- median(df_outliers$mark, na.rm = TRUE)
print(round(mediana_out, 1))
[1] 20
# Calculate mode
# In a bimodal or multimodal situation, it only returns the lowest mode.
freq_table_out <- table(df_outliers$mark)
moda_out <- min(as.numeric(names(freq_table_out)[freq_table_out == max(freq_table_out)]))
print(round(moda_out, 1))
[1] 24
ggplot(df_outliers, aes(x = mark)) +
geom_histogram(binwidth = 5, fill = "lightgray", color = "gray36") +
# Mean
geom_vline(aes(xintercept = media_out), color = "#CD6090", linetype = "dashed", size = 1) +
annotate("text", x = media_out + 2, y = 7, label = paste("Media_out = ", round(media_out, 1)), color = "#CD6090") +
# Median
geom_vline(aes(xintercept = mediana_out), color = "#008B45", linetype = "dashed", size = 1) +
annotate("text", x = mediana_out + 2, y = 8, label = paste("Mediana_out = ", round(mediana_out, 1)), color = "#008B45") +
# Mode
geom_vline(aes(xintercept = moda_out), color = "#4169E1", linetype = "dashed", size = 1) +
annotate("text", x = moda_out + 2, y = 9, label = paste("Moda_out = ", round(moda_out, 1)), color = "#4169E1") +
# Labels
labs(title = "Frecuencia de puntajes con medidas de localización en presencia de outliers", x ="Puntaje", y ="Frecuencia")+
# Fondo personalizado
theme(
panel.background = element_rect(fill = "#FFF8DC"), # Fondo del panel
plot.background = element_rect(fill = "#FFF8DC"), # Fondo total del gráfico
panel.grid.major = element_line(color = "#FFF8DC"), # Líneas de cuadrícula principales
panel.grid.minor = element_line(color = "#FFF8DC"), # Líneas de cuadrícula menores
)
La media es la medida más afectada por la presencia de outliers, desplazándose considerablemente hacia el extremo (donde se encuentran estos outliers).
La mediana presenta una afectación mínima por la presencia de outliers, lo cual podríamos interpretar como que es más resistente a valores extremos; por lo que es la medida más robusta ante outliers.
La moda no se afecta por los outliers, ya que aparecen en menor cantidad que los valores con frecuencia máxima (modas).
En análisis de datos reales, especialmente con presencia de outliers, la mediana y otras medidas robustas suelen proporcionar una descripción más representativa que la media.
Este análisis evidencia la importancia de identificar y manejar los outliers antes de interpretar las medidas de tendencia central, especialmente cuando la media se utiliza como indicador principal en contextos educativos o de rendimiento académico.