Autor/a

Eileen Michell Fajardo Rivera

Fecha de publicación

21 de abril de 2025

Librerias

Código
library(readxl)
library(tidyverse)
library(knitr)
library(kableExtra)
library(dplyr)
library(ggplot2)

Base de datos

Código
df <- read_excel("C:/Users/Usuario/Desktop/Miguel/seguros.xlsx")
head(df)
# A tibble: 6 × 8
   EDAD SEXO     IMC HIJOS FUMA  REGION    PRECIO CALIFICACION
  <dbl> <chr>  <dbl> <dbl> <chr> <chr>      <dbl> <chr>       
1    19 female  27.9     0 yes   southwest 16885. excellent   
2    18 male    33.8     1 no    southeast  1726. bad         
3    28 male    33       3 no    southeast  4449. bad         
4    33 male    22.7     0 no    northwest 21984. regular     
5    32 male    28.9     0 no    northwest  3867. regular     
6    31 female  25.7     0 no    southeast  3757. bad         
Código
str(df)
tibble [1,338 × 8] (S3: tbl_df/tbl/data.frame)
 $ EDAD        : num [1:1338] 19 18 28 33 32 31 46 37 37 60 ...
 $ SEXO        : chr [1:1338] "female" "male" "male" "male" ...
 $ IMC         : num [1:1338] 27.9 33.8 33 22.7 28.9 ...
 $ HIJOS       : num [1:1338] 0 1 3 0 0 0 1 3 2 0 ...
 $ FUMA        : chr [1:1338] "yes" "no" "no" "no" ...
 $ REGION      : chr [1:1338] "southwest" "southeast" "southeast" "northwest" ...
 $ PRECIO      : num [1:1338] 16885 1726 4449 21984 3867 ...
 $ CALIFICACION: chr [1:1338] "excellent" "bad" "bad" "regular" ...
Código
summary(df)
      EDAD           SEXO                IMC            HIJOS      
 Min.   :18.00   Length:1338        Min.   :15.96   Min.   :0.000  
 1st Qu.:27.00   Class :character   1st Qu.:26.30   1st Qu.:0.000  
 Median :39.00   Mode  :character   Median :30.40   Median :1.000  
 Mean   :39.21                      Mean   :30.66   Mean   :1.095  
 3rd Qu.:51.00                      3rd Qu.:34.69   3rd Qu.:2.000  
 Max.   :64.00                      Max.   :53.13   Max.   :5.000  
     FUMA              REGION              PRECIO      CALIFICACION      
 Length:1338        Length:1338        Min.   : 1122   Length:1338       
 Class :character   Class :character   1st Qu.: 4740   Class :character  
 Mode  :character   Mode  :character   Median : 9382   Mode  :character  
                                       Mean   :13270                     
                                       3rd Qu.:16640                     
                                       Max.   :63770                     

Distribución de frecuencia

Distribución cualitativa

Distribución nominal

Código
tabla_region <- df %>%
  count(REGION, name = "Frecuencia_absoluta") %>%
  mutate(
    Frecuencia_relativa = Frecuencia_absoluta / sum(Frecuencia_absoluta),
    Porcentaje = round(Frecuencia_relativa * 100, 2)
  ) %>%
  rename(Región = REGION)

tabla_region %>%
  kable(format = "html", digits = 2, align = "c",
        caption = "Tabla 1. Frecuencias de la variable Región") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center",
                font_size = 14)
Tabla 1. Frecuencias de la variable Región
Región Frecuencia_absoluta Frecuencia_relativa Porcentaje
northeast 324 0.24 24.22
northwest 325 0.24 24.29
southeast 364 0.27 27.20
southwest 325 0.24 24.29
Código
df_calif <- df %>%
  count(REGION)

ggplot(df_calif, aes(x = REGION, y = n)) +
  geom_bar(stat = "identity", fill = "#4C72B0") +
  labs(title = "Cantidad de personas por calificación",
       x = "Calificación",
       y = "Frecuencia") +
  theme_minimal()

Código
df_calif <- df %>%
  count(REGION) %>%
  mutate(porcentaje = n / sum(n) * 100,
         etiqueta = paste0(round(porcentaje, 1), "%"))

ggplot(df_calif, aes(x = "", y = n, fill = REGION)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  labs(title = "Distribución de calificación") +
  theme_void() +
  theme(legend.title = element_blank()) +
  geom_text(aes(label = etiqueta), position = position_stack(vjust = 0.5))

La región southeast presenta la mayor frecuencia absoluta (364 casos) y relativa (27%), representando el 27.20% del total, lo que la convierte en la región con mayor representación. Las regiones northeast, northwest y southwest tienen frecuencias similares, con aproximadamente 324-325 casos cada una (24% de frecuencia relativa y 24.22%-24.29% en porcentaje). Esto sugiere que, aunque hay una ligera predominancia del southeast, las demás regiones mantienen una distribución equilibrada, sin diferencias extremas entre ellas.

Distribución ordinal

Código
tabla_clasificacion <- df %>%
  count(CALIFICACION, name = "Frecuencia_absoluta") %>%
  mutate(
    Frecuencia_relativa = Frecuencia_absoluta / sum(Frecuencia_absoluta),
    Porcentaje = round(Frecuencia_relativa * 100, 2)
  ) %>%
  rename(Clasificación = CALIFICACION)

tabla_clasificacion %>%
  kable(format = "html", digits = 2, align = "c",
        caption = "Tabla 1. Frecuencias de la variable Calificación") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center",
                font_size = 14)
Tabla 1. Frecuencias de la variable Calificación
Clasificación Frecuencia_absoluta Frecuencia_relativa Porcentaje
bad 343 0.26 25.64
excellent 323 0.24 24.14
good 345 0.26 25.78
regular 327 0.24 24.44
Código
df_calif <- df %>%
  count(CALIFICACION)

ggplot(df_calif, aes(x = CALIFICACION, y = n)) +
  geom_bar(stat = "identity", fill = "#4C72B0") +
  labs(title = "Cantidad de personas por calificación",
       x = "Calificación",
       y = "Frecuencia") +
  theme_minimal()

Código
df_calif <- df %>%
  count(CALIFICACION) %>%
  mutate(porcentaje = n / sum(n) * 100,
         etiqueta = paste0(round(porcentaje, 1), "%"))

ggplot(df_calif, aes(x = "", y = n, fill = CALIFICACION)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  labs(title = "Distribución de calificación") +
  theme_void() +
  theme(legend.title = element_blank()) +
  geom_text(aes(label = etiqueta), position = position_stack(vjust = 0.5))

Las clasificaciones bad y good presentan las frecuencias absolutas más altas (343 y 345 casos, respectivamente), cada una con una frecuencia relativa del 26% y porcentajes cercanos al 25-26% (25.64% para “bad” y 25.78% para “good”). Por otro lado, las categorías excellent y regular muestran frecuencias ligeramente menores (323 y 327 casos), ambas con una frecuencia relativa del 24% y porcentajes similares (24.14% y 24.44%). Esto indica que no hay diferencias marcadas entre las categorías, aunque good es la más frecuente por un margen mínimo, seguida de cerca por bad, mientras que excellent y regular tienen una representación ligeramente inferior. La distribución sugiere que las evaluaciones tienden a concentrarse en los rangos intermedios (“good” y “bad”) en comparación con los extremos (“excellent” y “regular”).

Dicotomica

Código
tabla_region <- df %>%
  count(SEXO, name = "Frecuencia_absoluta") %>%
  mutate(
    Frecuencia_relativa = Frecuencia_absoluta / sum(Frecuencia_absoluta),
    Porcentaje = round(Frecuencia_relativa * 100, 2)
  ) %>%
  rename(Región = SEXO)

tabla_region %>%
  kable(format = "html", digits = 2, align = "c",
        caption = "Tabla 1. Frecuencias de la variable Sexo") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center",
                font_size = 14)
Tabla 1. Frecuencias de la variable Sexo
Región Frecuencia_absoluta Frecuencia_relativa Porcentaje
female 662 0.49 49.48
male 676 0.51 50.52
Código
df_calif <- df %>%
  count(SEXO)

ggplot(df_calif, aes(x = SEXO, y = n)) +
  geom_bar(stat = "identity", fill = "#4C72B0") +
  labs(title = "Cantidad de personas por calificación",
       x = "Calificación",
       y = "Frecuencia") +
  theme_minimal()

Código
df_calif <- df %>%
  count(SEXO) %>%
  mutate(porcentaje = n / sum(n) * 100,
         etiqueta = paste0(round(porcentaje, 1), "%"))

ggplot(df_calif, aes(x = "", y = n, fill = SEXO)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  labs(title = "Distribución de calificación") +
  theme_void() +
  theme(legend.title = element_blank()) +
  geom_text(aes(label = etiqueta), position = position_stack(vjust = 0.5))

La frecuencia absoluta para male (676 casos) es ligeramente mayor que para female (662 casos), con una diferencia de solo 14 observaciones. En términos relativos, male representa el 51% (frecuencia relativa de 0.51) de los datos, mientras que female constituye el 49% (frecuencia relativa de 0.49). Esta mínima diferencia (1.04 puntos porcentuales) sugiere que la muestra está balanceada en cuanto al género, sin predominancias significativas de uno sobre el otro. Tal equilibrio podría indicar una representación proporcional en el conjunto de datos analizado, lo que es relevante para evitar sesgos en análisis posteriores.

Distribución cuantitativa

Distribición discreta

Código
tabla_hijos <- df %>%
  count(HIJOS, name = "Frecuencia_Absoluta") %>%
  arrange(HIJOS) %>%
  mutate(
    Frecuencia_Relativa = round(Frecuencia_Absoluta / sum(Frecuencia_Absoluta), 4),
    Frecuencia_Abs_Acum = cumsum(Frecuencia_Absoluta),
    Frecuencia_Rel_Acum = cumsum(Frecuencia_Relativa)
  )

tabla_hijos %>%
  kbl(caption = "Tabla 2  
Distribución de frecuencias del número de hijos",
      align = "c",
      col.names = c("Número de hijos", 
                    "Frecuencia absoluta", 
                    "Frecuencia relativa", 
                    "Frecuencia absoluta acumulada", 
                    "Frecuencia relativa acumulada"),
      format = "html", digits = 4) %>%
  kable_styling(full_width = FALSE, 
                bootstrap_options = c("striped", "hover", "condensed"),
                font_size = 13,
                position = "center") %>%
  row_spec(0, bold = TRUE)
Tabla 2 Distribución de frecuencias del número de hijos
Número de hijos Frecuencia absoluta Frecuencia relativa Frecuencia absoluta acumulada Frecuencia relativa acumulada
0 574 0.4290 574 0.4290
1 324 0.2422 898 0.6712
2 240 0.1794 1138 0.8506
3 157 0.1173 1295 0.9679
4 25 0.0187 1320 0.9866
5 18 0.0135 1338 1.0001
Código
df_calif <- df %>%
  count(HIJOS)

ggplot(df_calif, aes(x = HIJOS, y = n)) +
  geom_bar(stat = "identity", fill = "#4C72B0") +
  labs(title = "Cantidad de personas por calificación",
       x = "Calificación",
       y = "Frecuencia") +
  theme_minimal()

Código
df_hijos <- df %>%
  count(HIJOS) %>%
  mutate(
    porcentaje = round(n / sum(n) * 100, 1),
    etiqueta = paste0(porcentaje, "%")
  )

ggplot(df_hijos, aes(x = "", y = n, fill = factor(HIJOS))) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  labs(title = "Distribución porcentual del número de hijos") +
  theme_void() +
  theme(legend.title = element_blank()) 

La categoría 0 hijos es la más frecuente, con 574 casos (42.9% del total), lo que indica que casi la mitad de la población analizada no tiene hijos. Le siguen 1 hijo (24.2% de los casos) y 2 hijos (17.9%), que en conjunto representan el 85.1% de la distribución acumulada. A partir de 3 hijos, las frecuencias disminuyen notablemente, con solo el 11.7% para 3 hijos, 1.9% para 4 hijos y 1.4% para 5 hijos.

El análisis acumulado revela que:

  • El 67.1% de la población tiene 1 hijo o menos.

  • El 85.1% tiene 2 hijos o menos.

  • Solo el 1.4% supera los 4 hijos.

Esta distribución refleja un patrón común en estudios demográficos, donde la mayoría de las familias tienen entre 0 y 2 hijos, con una proporción significativamente menor en hogares con 3 o más hijos. La presencia marginal de casos con 5 hijos (solo 18 observaciones) sugiere que las familias numerosas son poco frecuentes en esta muestra.

Distribución continua

Código
rango <- max(df$EDAD) - min(df$EDAD)

k <- ceiling(1 + 3.322 * log10(nrow(df)))

amplitud <- ceiling(rango / k)

rango; k; amplitud
[1] 46
[1] 12
[1] 4
Código
breaks <- seq(from = min(df$EDAD),
              to = max(df$EDAD) + amplitud,  
              by = amplitud)

clases <- cut(df$EDAD, breaks = breaks, right = FALSE, include.lowest = TRUE)

tabla_frec <- as.data.frame(table(clases))
colnames(tabla_frec) <- c("Intervalo", "Frecuencia_Absoluta")

tabla_frec$Frecuencia_Relativa <- round(tabla_frec$Frecuencia_Absoluta / sum(tabla_frec$Frecuencia_Absoluta), 4)

tabla_frec$Frecuencia_Abs_Acum <- cumsum(tabla_frec$Frecuencia_Absoluta)
tabla_frec$Frecuencia_Rel_Acum <- cumsum(tabla_frec$Frecuencia_Relativa)

tabla_frec %>%
  kbl(caption = "Tabla 1  
Distribución de frecuencias de la variable PRECIO",
      align = "c",
      col.names = c("Intervalo", 
                    "Frecuencia absoluta", 
                    "Frecuencia relativa", 
                    "Frecuencia absoluta acumulada", 
                    "Frecuencia relativa acumulada"),
      format = "html", digits = 4) %>%
  kable_styling(full_width = FALSE, 
                bootstrap_options = c("striped", "hover", "condensed"),
                font_size = 13,
                position = "center") %>%
  row_spec(0, bold = TRUE)
Tabla 1 Distribución de frecuencias de la variable PRECIO
Intervalo Frecuencia absoluta Frecuencia relativa Frecuencia absoluta acumulada Frecuencia relativa acumulada
[18,22) 194 0.1450 194 0.1450
[22,26) 112 0.0837 306 0.2287
[26,30) 111 0.0830 417 0.3117
[30,34) 106 0.0792 523 0.3909
[34,38) 101 0.0755 624 0.4664
[38,42) 104 0.0777 728 0.5441
[42,46) 110 0.0822 838 0.6263
[46,50) 115 0.0859 953 0.7122
[50,54) 115 0.0859 1068 0.7981
[54,58) 106 0.0792 1174 0.8773
[58,62) 96 0.0717 1270 0.9490
[62,66] 68 0.0508 1338 0.9998
Código
ggplot(df, aes(x = EDAD)) +
  geom_histogram(aes(y = ..density..), 
                 breaks = breaks,
                 fill = "steelblue", 
                 color = "white", 
                 alpha = 0.8) +
  geom_density(color = "red", linewidth = 1) +
  labs(title = "Histograma de EDAD con curva de densidad",
       x = "Edad", 
       y = "Densidad") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))

La distribución de frecuencias de la variable PRECIO revela un comportamiento multimodal, donde el intervalo más frecuente es [18,22) con 194 casos (14.5%), seguido de los rangos [46,50) y [50,54) con 115 casos cada uno (8.6%). Aunque los precios bajos (≤26) concentran el 22.9% de los datos, la distribución no sigue un patrón uniforme, mostrando picos en rangos intermedios (46-54) y una disminución progresiva en los valores superiores (≥54), donde el intervalo [62,66) solo registra 68 casos (5.1%). El 71.2% de los precios se ubican por debajo de 50, y el 94.9% bajo 62, lo que sugiere una mayor concentración en rangos medios-bajos y una demanda limitada en precios elevados. Esta variabilidad podría indicar la presencia de categorías diferenciadas (como productos estándar y premium) o factores externos que segmentan el mercado, recomendándose un análisis más detallado para identificar las causas detrás de estos patrones.