DISTRIBUCIONES DE FRECUENCIAS…

TALLER_1

Autor/a
Afiliación

Sebastian Oviedo Rosas
Deisy Yanary Miranda
Omar Julian Chapid

Fecha de publicación

2 de abril de 2026

Logo Universidad del Tolima

1 .Cargar paquetes

Ver código
ipak <- function(pkg){
  
  # Definir repositorio CRAN (evita el error del mirror)
  options(repos = c(CRAN = "https://cloud.r-project.org"))
  
  # Identificar paquetes instalados
  installed <- rownames(installed.packages())
  
  # Identificar paquetes faltantes
  new.pkg <- setdiff(pkg, installed)
  
  # Instalar paquetes faltantes
  if(length(new.pkg) > 0){
    install.packages(new.pkg, dependencies = TRUE)
  }
  
  # Cargar paquetes sin mostrar mensajes
  invisible(lapply(pkg, function(p){
    suppressPackageStartupMessages(
      library(p, character.only = TRUE)
    )
  }))
}

# Crear la lista de los paquetes a utilizar
packages <- c("tidyverse", "kableExtra", "psych", "readxl")

# Instalar y cargar los paquetes del listado anterior
ipak(packages)

(Wickham et al. 2019; Zhu 2024; 2026; Wickham y Bryan 2025)

2 .Introduccion

Distribución de frecuencias

Concepto

Una distribución de frecuencias es una forma de organizar, resumir y presentar un conjunto de datos agrupándolos según el número de veces que aparece cada valor o intervalo dentro de un conjunto de observaciones.

Su objetivo principal es facilitar el análisis e interpretación de los datos, permitiendo identificar patrones, concentraciones de valores, tendencias y comportamientos dentro de una población o muestra.

Las distribuciones de frecuencias se utilizan principalmente en estadística descriptiva y pueden aplicarse a datos cualitativos o cuantitativos.

.Elementos de una distribución de frecuencias

Una tabla de distribución de frecuencias generalmente contiene:

  1. Valores o clases (Xi)
  2. Frecuencia absoluta (fi)
  3. Frecuencia acumulada (Fi)
  4. Frecuencia relativa (hi)
  5. Frecuencia relativa acumulada (Hi)
  6. Marca de clase (cuando hay intervalos)

Tipos de frecuencia y fórmulas

2.1 .Frecuencia absoluta (fi)

Es el número de veces que aparece un dato dentro del conjunto de observaciones.

f_i

No tiene fórmula específica porque se obtiene contando cuántas veces aparece cada valor.

2.2 .Frecuencia absoluta acumulada (Fi)

Es la suma progresiva de las frecuencias absolutas hasta una determinada clase o valor.

F_i = \sum_{j=1}^{i} f_j

2.3 .Frecuencia relativa (hi)

Representa la proporción o parte del total que corresponde a una frecuencia absoluta.

h_i = \frac{f_i}{N}

donde:

  • (f_i) = frecuencia absoluta
  • (N) = número total de datos

2.4 .Frecuencia relativa acumulada (Hi)

Es la suma acumulada de las frecuencias relativas.

H_i = \frac{F_i}{N}

o también

H_i = \sum_{j=1}^{i} h_j

2.5 .Frecuencia porcentual

Expresa la frecuencia relativa en porcentaje.

% = h_i \times 100

o

% = \frac{f_i}{N} \times 100

Distribución de frecuencias para datos agrupados

Cuando los datos son muchos, se agrupan en intervalos de clase.

Número de clases (Regla de Sturges)

k = 1 + 3.322 \log_{10}(N)

donde:

  • (k) = número de clases
  • (N) = número total de datos

Amplitud de clase

A = \frac{R}{k}

donde:

  • (A) = amplitud del intervalo
  • (R) = rango
  • (k) = número de clases

Rango

R = X_{max} - X_{min}

Marca de clase

Es el punto medio de cada intervalo.

X_i = \frac{L_i + L_s}{2}

donde:

  • (L_i) = límite inferior
  • (L_s) = límite superior

Importancia de la distribución de frecuencias

Las distribuciones de frecuencias permiten:

  • Organizar grandes cantidades de datos.

  • Identificar tendencias y patrones.

  • Facilitar la construcción de gráficos estadísticos (histogramas, polígonos de frecuencia, ojivas).

  • Servir de base para el cálculo de medidas estadísticas como:

    • media
    • mediana
    • moda
    • varianza
    • desviación estándar.

3 .Bajar el Dataset

Base de datos DEPORTES

4 .Leer el Dataset

Ver código
deporte <- read_excel("deporte.xlsx")

5 .Conocer el Dataset

  • Mostrar algunas filas del Dataset
Ver código
head(deporte)
# A tibble: 6 × 13
  GENERO   DEPORTE ESCOLARIDAD DESEMPEÑO PRACTICAS  EDAD  PESO LESIONES ESTATURA
  <chr>    <chr>   <chr>       <chr>         <dbl> <dbl> <dbl>    <dbl>    <dbl>
1 Masculi… Fútbol  Posgrado    Medio             5    44    56        2      180
2 Masculi… Voleib… Pregrado    Medio             5    59    66        1      152
3 Femenino Gimnas… Posgrado    Alto              4    27    57        2      157
4 Masculi… Nataci… Secundaria  Alto              3    44    54        3      167
5 Femenino Nataci… Posgrado    Medio             4    59    73        0      189
6 Masculi… Nataci… Pregrado    Bajo              2    58    59        1      188
# ℹ 4 more variables: BORG <dbl>, EVA <dbl>, CINTURA <dbl>, CADERA <dbl>
  • Numero de variables
Ver código
deporte %>% names %>% length()
[1] 13
  • Nombre de las variables
Ver código
names(deporte)
 [1] "GENERO"      "DEPORTE"     "ESCOLARIDAD" "DESEMPEÑO"   "PRACTICAS"  
 [6] "EDAD"        "PESO"        "LESIONES"    "ESTATURA"    "BORG"       
[11] "EVA"         "CINTURA"     "CADERA"     
  • Estructura de las variables
Ver código
glimpse(deporte)
Rows: 200
Columns: 13
$ GENERO      <chr> "Masculino", "Masculino", "Femenino", "Masculino", "Femeni…
$ DEPORTE     <chr> "Fútbol", "Voleibol", "Gimnasia", "Natación", "Natación", …
$ ESCOLARIDAD <chr> "Posgrado", "Pregrado", "Posgrado", "Secundaria", "Posgrad…
$ DESEMPEÑO   <chr> "Medio", "Medio", "Alto", "Alto", "Medio", "Bajo", "Bajo",…
$ PRACTICAS   <dbl> 5, 5, 4, 3, 4, 2, 4, 5, 6, 1, 7, 3, 2, 7, 5, 2, 4, 2, 7, 5…
$ EDAD        <dbl> 44, 59, 27, 44, 59, 58, 21, 40, 54, 46, 35, 54, 38, 38, 53…
$ PESO        <dbl> 56, 66, 57, 54, 73, 59, 69, 55, 65, 69, 56, 53, 54, 80, 59…
$ LESIONES    <dbl> 2, 1, 2, 3, 0, 1, 0, 0, 0, 3, 2, 2, 0, 2, 2, 1, 3, 0, 1, 1…
$ ESTATURA    <dbl> 180, 152, 157, 167, 189, 188, 169, 185, 166, 155, 150, 187…
$ BORG        <dbl> 5, 3, 2, 6, 1, 7, 10, 5, 9, 6, 7, 10, 8, 0, 1, 0, 9, 3, 7,…
$ EVA         <dbl> 0, 4, 2, 4, 2, 2, 4, 2, 2, 4, 1, 0, 4, 1, 1, 3, 0, 5, 5, 4…
$ CINTURA     <dbl> 120, 139, 143, 120, 74, 143, 116, 97, 74, 93, 122, 71, 112…
$ CADERA      <dbl> 88, 94, 90, 99, 94, 89, 95, 95, 92, 95, 87, 109, 102, 88, …
  • Transformar las variables
Ver código
deporte$GENERO <- as.factor(deporte$GENERO)
deporte$ESCOLARIDAD <- as.factor(deporte$ESCOLARIDAD)

deporte$DEPORTE <- factor(deporte$DEPORTE, 
                        levels = c("Fútbol", "Voleibol", "Gimnasia" , "Atletismo" , "Baloncesto" , "Tenis" , "Natación"), ordered = TRUE)


deporte$DESEMPEÑO <- factor(deporte$DESEMPEÑO, 
                         levels = c("Bajo", "Medio", "Alto"), ordered = TRUE)
  • Nueva estructura de las variables
Ver código
glimpse(deporte)
Rows: 200
Columns: 13
$ GENERO      <fct> Masculino, Masculino, Femenino, Masculino, Femenino, Mascu…
$ DEPORTE     <ord> Fútbol, Voleibol, Gimnasia, Natación, Natación, Natación, …
$ ESCOLARIDAD <fct> Posgrado, Pregrado, Posgrado, Secundaria, Posgrado, Pregra…
$ DESEMPEÑO   <ord> Medio, Medio, Alto, Alto, Medio, Bajo, Bajo, Bajo, Medio, …
$ PRACTICAS   <dbl> 5, 5, 4, 3, 4, 2, 4, 5, 6, 1, 7, 3, 2, 7, 5, 2, 4, 2, 7, 5…
$ EDAD        <dbl> 44, 59, 27, 44, 59, 58, 21, 40, 54, 46, 35, 54, 38, 38, 53…
$ PESO        <dbl> 56, 66, 57, 54, 73, 59, 69, 55, 65, 69, 56, 53, 54, 80, 59…
$ LESIONES    <dbl> 2, 1, 2, 3, 0, 1, 0, 0, 0, 3, 2, 2, 0, 2, 2, 1, 3, 0, 1, 1…
$ ESTATURA    <dbl> 180, 152, 157, 167, 189, 188, 169, 185, 166, 155, 150, 187…
$ BORG        <dbl> 5, 3, 2, 6, 1, 7, 10, 5, 9, 6, 7, 10, 8, 0, 1, 0, 9, 3, 7,…
$ EVA         <dbl> 0, 4, 2, 4, 2, 2, 4, 2, 2, 4, 1, 0, 4, 1, 1, 3, 0, 5, 5, 4…
$ CINTURA     <dbl> 120, 139, 143, 120, 74, 143, 116, 97, 74, 93, 122, 71, 112…
$ CADERA      <dbl> 88, 94, 90, 99, 94, 89, 95, 95, 92, 95, 87, 109, 102, 88, …

6 .Tablas y Graficas

6.1 .Variable Nominal

AdvertenciaLa variable nominal tiene solo frecuencia absoluta, relativa y porcentaje

Tabla No 1: Análisis de frecuencias del genero de los deportistas

Ver código
# Crear la tabla original
tabla <- tibble(Genero = deporte$GENERO) %>% 
  group_by(Genero) %>% 
  summarise(fi = n()) %>%
  mutate(
    hi = round(fi/sum(fi), 4), 
    Porcentaje = paste0(hi*100, "%"),)

# Convertir las columnas a character para evitar conflictos
tabla <- tabla %>% mutate(
  Genero = as.character(Genero))

# Añadir la fila de totales
totales <- tibble(
  Genero = "Total",
  fi = sum(tabla$fi),
  hi = round(sum(tabla$hi), 4),
  Porcentaje = paste0(round(sum(tabla$hi) * 100, 2), "%"))

# Combinar la tabla con los totales
tabla_final <- bind_rows(tabla, totales)

# Mostrar la tabla final con kable
tabla_final %>% 
  knitr::kable(
    col.names = c("Genero", "$f_i$", "$h_i$", "Porcentaje"), 
    align = c("l", "c", "c", "c"))
Genero f_i h_i Porcentaje
Femenino 93 0.465 46.5%
Masculino 107 0.535 53.5%
Total 200 1.000 100%
Ver código
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
library(readxl)


# Calcular los porcentajes de cada categoría en la variable ESTADO
genero_counts <- deporte %>%
  dplyr::count(GENERO) %>%
  mutate(porcentaje = n / sum(n) * 100)

# Crear el diagrama de barras
ggplot(genero_counts, aes(x = GENERO, y = porcentaje, fill = GENERO)) +
  geom_bar(stat = "identity") +
  labs(title = "Distribución porcentual del genero de los deportistas", 
       x = "Genero", 
       y = "Porcentaje") +
  theme_minimal() +
  theme(legend.position = "none") +
  geom_text(aes(label = sprintf("%.1f%%", porcentaje)), 
            vjust = -0.5, 
            color = "black", 
            size = 3.5)

Ver código
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
library(readxl)



# Calcular los porcentajes de cada categoría en la variable ESTADO
genero_counts <- deporte %>%
  dplyr::count(GENERO) %>%
  mutate(porcentaje = n / sum(n) * 100)

# Crear el diagrama circular
ggplot(genero_counts, aes(x = "", y = porcentaje, fill = GENERO)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  labs(title = "Distribución porcentual del genero de los deportistas") +
  theme_minimal() +
  theme(axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        panel.grid = element_blank(),
        axis.text.x = element_blank()) +
  geom_text(aes(label = sprintf("%.1f%%", porcentaje)), 
            position = position_stack(vjust = 0.5), 
            color = "white", 
            size = 4)

La tabla presenta la distribución de la variable género en una muestra de 200 participantes, donde el 53.5% (107 individuos) corresponde al género masculino y el 46.5% (93 individuos) al género femenino, evidenciando una ligera predominancia del género masculino; sin embargo, la diferencia no es amplia, lo que indica una distribución relativamente equilibrada entre ambos grupos y permite considerar que la muestra es adecuada para realizar comparaciones sin un sesgo significativo por género.


Tabla No 2: Análisis de frecuencias del deporte

Ver código
# Crear la tabla original
tabla <- tibble(Deporte = deporte$DEPORTE) %>% 
  group_by(Deporte) %>% 
  summarise(fi = n()) %>%
  mutate(
    hi = round(fi/sum(fi), 4), 
    Porcentaje = paste0(hi*100, "%"),)

# Convertir las columnas a character para evitar conflictos
tabla <- tabla %>% mutate(
  Deporte = as.character(Deporte))

# Añadir la fila de totales
totales <- tibble(
  Deporte = "Total",
  fi = sum(tabla$fi),
  hi = round(sum(tabla$hi), 4),
  Porcentaje = paste0(round(sum(tabla$hi) * 100, 2), "%"))

# Combinar la tabla con los totales
tabla_final <- bind_rows(tabla, totales)

# Mostrar la tabla final con kable
tabla_final %>% 
  knitr::kable(
    col.names = c("Deporte", "$f_i$", "$h_i$", "Porcentaje"), 
    align = c("l", "c", "c", "c"))
Deporte f_i h_i Porcentaje
Fútbol 31 0.155 15.5%
Voleibol 28 0.140 14%
Gimnasia 26 0.130 13%
Atletismo 25 0.125 12.5%
Baloncesto 36 0.180 18%
Tenis 22 0.110 11%
Natación 32 0.160 16%
Total 200 1.000 100%
Ver código
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
library(readxl)


# Calcular los porcentajes de cada categoría en la variable ESTADO
deporte_counts <- deporte %>%
  dplyr::count(DEPORTE) %>%
  mutate(porcentaje = n / sum(n) * 100)

# Crear el diagrama de barras
ggplot(deporte_counts, aes(x = DEPORTE, y = porcentaje, fill = DEPORTE)) +
  geom_bar(stat = "identity") +
  labs(title = "Distribución porcentual del deporte", 
       x = "Deporte", 
       y = "Porcentaje") +
  theme_minimal() +
  theme(legend.position = "none") +
  geom_text(aes(label = sprintf("%.1f%%", porcentaje)), 
            vjust = -0.5, 
            color = "black", 
            size = 3.5)

Ver código
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
library(readxl)



# Calcular los porcentajes de cada categoría en la variable ESTADO
deporte_counts <- deporte %>%
  dplyr::count(DEPORTE) %>%
  mutate(porcentaje = n / sum(n) * 100)

# Crear el diagrama circular
ggplot(deporte_counts, aes(x = "", y = porcentaje, fill = DEPORTE)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y") +
  labs(title = "Distribución porcentual del deporte") +
  theme_minimal() +
  theme(axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        panel.grid = element_blank(),
        axis.text.x = element_blank()) +
  geom_text(aes(label = sprintf("%.1f%%", porcentaje)), 
            position = position_stack(vjust = 0.5), 
            color = "white", 
            size = 4)

La tabla presenta la distribución de los deportes practicados por los 200 participantes, evidenciando que el baloncesto es el deporte con mayor frecuencia (18%), seguido de la natación (16%) y el fútbol (15.5%), mientras que voleibol (14%), gimnasia (13%) y atletismo (12.5%) muestran proporciones intermedias, y el tenis registra la menor participación (11%); en general, se observa una distribución relativamente equilibrada entre las distintas disciplinas, sin concentraciones excesivas en un solo deporte, lo que sugiere diversidad en las prácticas deportivas de la muestra.


6.2 .Variable Ordinal

TipLa variable ordinal tiene los cuatro tipos de frecuencias

Tabla No 1: Distribución de frecuencias de la escolaridad de los deportistas

Ver código
# Crear la tabla original
tabla <- tibble(Escolaridad = deporte$ESCOLARIDAD) %>% 
  group_by(Escolaridad) %>% 
  summarise(fi = n()) %>%
  mutate(
    hi = round(fi/sum(fi), 4), 
    Porcentaje = paste0(hi*100, "%"),
    Fi = cumsum(fi),
    Hi = cumsum(hi)
  )

# Convertir las columnas Fucion, Fi, y Hi a character para evitar conflictos
tabla <- tabla %>% mutate(
  Escolaridad = as.character(Escolaridad),
  Fi = as.character(Fi),
  Hi = as.character(Hi)
)

# Añadir la fila de totales, dejando Fi y Hi vacíos
totales <- tibble(
  Escolaridad = "Total",
  fi = sum(tabla$fi),
  hi = round(sum(tabla$hi), 4),
  Porcentaje = paste0(round(sum(tabla$hi) * 100, 2), "%"),
  Fi = "",  # Puedes dejar en blanco o usar un valor numérico
  Hi = ""   # Puedes dejar en blanco o usar un valor numérico
)

# Combinar la tabla con los totales
tabla_final <- bind_rows(tabla, totales)

# Mostrar la tabla final con kable
tabla_final %>% 
  knitr::kable(
    col.names = c("Escolaridad", "fi", "hi", "Porcentaje", "Fi", "Hi"), 
    align = c("l", "c", "c", "c", "c", "c")
  )
Escolaridad fi hi Porcentaje Fi Hi
Posgrado 56 0.280 28% 56 0.28
Pregrado 53 0.265 26.5% 109 0.545
Primaria 44 0.220 22% 153 0.765
Secundaria 47 0.235 23.5% 200 1
Total 200 1.000 100%
Ver código
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
library(readxl)


# Calcular los porcentajes de cada categoría en la variable ESTADO
escolaridad_counts <- deporte %>%
  dplyr::count(ESCOLARIDAD) %>%
  mutate(porcentaje = n / sum(n) * 100)

# Crear el diagrama de barras
ggplot(escolaridad_counts, aes(x = ESCOLARIDAD, y = porcentaje, fill = ESCOLARIDAD)) +
  geom_bar(stat = "identity") +
  labs(title = "Distribución porcentual de la escolaridad", 
       x = "Escolaridad", 
       y = "Porcentaje") +
  theme_minimal() +
  theme(legend.position = "none") +
  geom_text(aes(label = sprintf("%.1f%%", porcentaje)), 
            vjust = -0.5, 
            color = "black", 
            size = 3.5)

La tabla muestra la distribución del nivel de escolaridad en una muestra de 200 participantes, donde el posgrado presenta la mayor proporción (28%), seguido del pregrado (26.5%), secundaria (23.5%) y primaria (22%); esto evidencia que la mayoría de los individuos se concentra en niveles educativos superiores, aunque las diferencias entre categorías no son muy amplias, lo que indica una distribución relativamente equilibrada. Asimismo, las frecuencias acumuladas reflejan que más de la mitad de la muestra (54.5%) alcanza al menos el nivel de pregrado, lo que sugiere un nivel educativo general medio-alto dentro de la población analizada.

Tabla No 2: Distribución de frecuencias de el desempeño de los deportistas

Ver código
# Crear la tabla original
tabla <- tibble(Desempeño = deporte$DESEMPEÑO) %>% 
  group_by(Desempeño) %>% 
  summarise(fi = n()) %>%
  mutate(
    hi = round(fi/sum(fi), 4), 
    Porcentaje = paste0(hi*100, "%"),
    Fi = cumsum(fi),
    Hi = cumsum(hi)
  )

# Convertir las columnas Fucion, Fi, y Hi a character para evitar conflictos
tabla <- tabla %>% mutate(
  Desempeño = as.character(Desempeño),
  Fi = as.character(Fi),
  Hi = as.character(Hi)
)

# Añadir la fila de totales, dejando Fi y Hi vacíos
totales <- tibble(
  Desempeño = "Total",
  fi = sum(tabla$fi),
  hi = round(sum(tabla$hi), 4),
  Porcentaje = paste0(round(sum(tabla$hi) * 100, 2), "%"),
  Fi = "",  # Puedes dejar en blanco o usar un valor numérico
  Hi = ""   # Puedes dejar en blanco o usar un valor numérico
)

# Combinar la tabla con los totales
tabla_final <- bind_rows(tabla, totales)

# Mostrar la tabla final con kable
tabla_final %>% 
  knitr::kable(
    col.names = c("Desempeño", "fi", "hi", "Porcentaje", "Fi", "Hi"), 
    align = c("l", "c", "c", "c", "c", "c")
  )
Desempeño fi hi Porcentaje Fi Hi
Bajo 67 0.335 33.5% 67 0.335
Medio 61 0.305 30.5% 128 0.64
Alto 72 0.360 36% 200 1
Total 200 1.000 100%
Ver código
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
library(readxl)


# Calcular los porcentajes de cada categoría en la variable ESTADO
desempeño_counts <- deporte %>%
  dplyr::count(DESEMPEÑO) %>%
  mutate(porcentaje = n / sum(n) * 100)

# Crear el diagrama de barras
ggplot(desempeño_counts, aes(x = DESEMPEÑO, y = porcentaje, fill = DESEMPEÑO)) +
  geom_bar(stat = "identity") +
  labs(title = "Distribución porcentual de el desempeño de los deportistas", 
       x = "Desempeño", 
       y = "Porcentaje") +
  theme_minimal() +
  theme(legend.position = "none") +
  geom_text(aes(label = sprintf("%.1f%%", porcentaje)), 
            vjust = -0.5, 
            color = "black", 
            size = 3.5)

El análisis descriptivo de la muestra (n = 200) revela una distribución relativamente equitativa entre los niveles de desempeño, con una ligera prevalencia del nivel Alto (36%) sobre los niveles Bajo (33.5%) y Medio (30.5%). No obstante, el dato acumulado indica que el 64% de los evaluados se sitúa en los rangos inferior y medio, lo que evidencia que la mayoría de la población de estudio aún no alcanza los estándares óptimos de desempeño, sugiriendo un área de oportunidad significativa para intervenciones institucionales.

6.3 .Variable Discreta

AdvertenciaLa variable discreta tiene los cuatro tipos de frecuencias

Distribución de frecuencias de la edad de los deportistas

Ver código
# Crear la tabla original
tabla <- tibble(Edad = deporte$EDAD) %>% 
  group_by(Edad) %>% 
  summarise(fi = n()) %>%
  mutate(
    hi = round(fi/sum(fi), 4), 
    Porcentaje = paste0(hi*100, "%"),
    Fi = cumsum(fi),
    Hi = cumsum(hi)
  )

# Convertir las columnas Personas, Fi, y Hi a character para evitar conflictos
tabla <- tabla %>% mutate(
  Edad = as.character(Edad),
  Fi = as.character(Fi),
  Hi = as.character(Hi)
)

# Añadir la fila de totales, dejando Fi y Hi vacíos
totales <- tibble(
  Edad = "Total",
  fi = sum(tabla$fi),
  hi = round(sum(tabla$hi), 2),
  Porcentaje = paste0(round(sum(tabla$hi) * 100, 2), "%"),
  Fi = "",  # Puedes dejar en blanco o usar un valor numérico
  Hi = ""   # Puedes dejar en blanco o usar un valor numérico
)

# Combinar la tabla con los totales
tabla_final <- bind_rows(tabla, totales)

# Mostrar la tabla final con kable
tabla_final %>% 
  knitr::kable(
    col.names = c("Edad", "fi", "hi", "Porcentaje", "Fi", "Hi"), 
    align = c("l", "r", "r", "r", "r", "r")
  )
Edad fi hi Porcentaje Fi Hi
18 4 0.020 2% 4 0.02
19 2 0.010 1% 6 0.03
20 4 0.020 2% 10 0.05
21 5 0.025 2.5% 15 0.075
22 4 0.020 2% 19 0.095
23 3 0.015 1.5% 22 0.11
24 2 0.010 1% 24 0.12
25 3 0.015 1.5% 27 0.135
26 7 0.035 3.5% 34 0.17
27 7 0.035 3.5% 41 0.205
28 4 0.020 2% 45 0.225
29 3 0.015 1.5% 48 0.24
30 4 0.020 2% 52 0.26
31 3 0.015 1.5% 55 0.275
32 6 0.030 3% 61 0.305
33 6 0.030 3% 67 0.335
34 6 0.030 3% 73 0.365
35 5 0.025 2.5% 78 0.39
36 3 0.015 1.5% 81 0.405
37 3 0.015 1.5% 84 0.42
38 6 0.030 3% 90 0.45
39 6 0.030 3% 96 0.48
40 5 0.025 2.5% 101 0.505
41 2 0.010 1% 103 0.515
42 8 0.040 4% 111 0.555
43 4 0.020 2% 115 0.575
44 5 0.025 2.5% 120 0.6
45 3 0.015 1.5% 123 0.615
46 8 0.040 4% 131 0.655
47 7 0.035 3.5% 138 0.69
48 3 0.015 1.5% 141 0.705
49 9 0.045 4.5% 150 0.75
50 6 0.030 3% 156 0.78
51 2 0.010 1% 158 0.79
52 3 0.015 1.5% 161 0.805
53 5 0.025 2.5% 166 0.83
54 8 0.040 4% 174 0.87
55 5 0.025 2.5% 179 0.895
56 2 0.010 1% 181 0.905
57 4 0.020 2% 185 0.925
58 5 0.025 2.5% 190 0.95
59 5 0.025 2.5% 195 0.975
60 5 0.025 2.5% 200 1
Total 200 1.000 100%
Ver código
# valores de la variable
x <- c(18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60)
# f.m.p.
fx <- c(0.020, 0.010, 0.020, 0.025, 0.020, 0.015, 0.010, 0.015, 0.035, 0.035, 0.020, 0.015, 0.020, 0.015, 0.030, 0.030, 0.030, 0.025, 0.015, 0.015, 0.030, 0.030, 0.025, 0.010, 0.040, 0.020, 0.025, 0.015, 0.040, 0.035, 0.015, 0.045, 0.030, 0.010, 0.015, 0.025, 0.040, 0.025, 0.010, 0.020, 0.025, 0.025, 0.025)

# Crear un dataframe con los datos
df <- data.frame(x = x, fx = fx)

# Gráfico con ggplot2
ggplot(df, aes(x = x, y = fx)) +
  geom_point(shape = 18, color = "red") +
  geom_segment(aes(xend = x, yend = 0), size = 1, color = "blue") +
  labs(x = "Edad", y = "Porcentaje", title = "Diagrama  de bastones") +
  theme_minimal() +
  geom_text(aes(label = fx), vjust = -0.5)

Ver código
# Cargar librerías
library(ggplot2)
library(tibble)

# Crear datos
df <- tibble(
  x = c(18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60),
  
  Hi = c(0.02, 0.03, 0.05, 0.075, 0.095, 0.11, 0.12, 0.135, 0.17, 0.205, 0.225, 0.24, 0.26, 0.275, 0.305, 0.335, 0.365, 0.39, 0.405, 0.42, 0.45, 0.48, 0.505, 0.515, 0.555, 0.575, 0.6, 0.615, 0.655, 0.69, 0.705, 0.75, 0.78, 0.79, 0.805, 0.83, 0.87, 0.895, 0.905, 0.925, 0.95, 0.975, 1)
)

# Gráfica de función de distribución acumulada
ggplot(df, aes(x = x, y = Hi)) +
  geom_step(color = "#2C3E50", size = 1.2) +        # línea escalonada (CDF)
  geom_point(color = "#E74C3C", size = 3) +         # puntos
  scale_x_continuous(breaks = df$x, limits = c(7, 22)) +
  scale_y_continuous(limits = c(0, 1)) +
  labs(
    title = "Función de Distribución Acumulada (FDA)",
    x = "Variable",
    y = "Frecuencia relativa acumulada (Hi)"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    panel.grid.minor = element_blank()
  )

La caracterización demográfica de la muestra (n = 200) revela una alta dispersión etaria en un rango comprendido entre los 18 y 60 años, sin que se observe una concentración dominante en una sola edad específica. No obstante, se identifica que la edad con mayor frecuencia es de 49 años (4.5%), seguida por los 42, 46 y 54 años con un 4% respectivamente, lo que sugiere una ligera tendencia hacia la madurez en la población de estudio. Desde una perspectiva acumulada, se destaca que el 50.5% de los participantes tiene 40 años o menos (H_i = 0.505), lo que evidencia una distribución equilibrada entre adultos jóvenes y adultos en etapa de madurez, garantizando una representatividad generacional diversa para los fines de la investigación.


6.4 .Variable Continua

ImportanteLa variable continua se tabula con intervalos


Generación de intervalos

Ver código
Min <- min(deporte$EDAD)
Min
[1] 18
Ver código
Max <- max(deporte$EDAD)
Max
[1] 60
Ver código
R <- Max-Min
R
[1] 42
Ver código
m <- ceiling(1 + 3.322*log10(nrow(deporte)))
m
[1] 9
Ver código
A <- ceiling((R/m) * 1) / 1
A
[1] 5
Ver código
RC <- A*m
RC
[1] 45
PrecauciónLa amplitud debe tener tanto decimales como lo tienen los datos originales. Si tiene un decimal la fórmula se multiplica y se divide por 10. Si tiene dos decimales la fórmula se multiplica y se divide por 100 y así sucesivamente
Ver código
D <- RC-R
D
[1] 3
Ver código
Xmin <- Min-4
Xmin
[1] 14
Ver código
Xmax <- Max+4
Xmax
[1] 64
ImportanteLa diferencia se debe dividir en dos números lo más equitativos de tal manera que estos números tengan tantos decimales como los datos originales. Al mínimo se le resta uno de los números y al máximo se le suma el otro


Distribución de frecuencias de la edad de los deportistas

Ver código
library(dplyr)
library(kableExtra)

m1 <- (Xmin+(Xmin+A))/2

interv = cut(x = deporte$EDAD, breaks = seq(Xmin, Xmax, by = A), include.lowest = TRUE)

tabla <- tibble(Edad = interv) %>% 
  group_by(Edad) %>% 
  summarise(fi = n()) %>% 
  mutate(hi = fi / sum(fi)) %>% 
  mutate(
    mi = seq(from = m1, by = A, length.out = nrow(.)) %>% as.character(), # Convertir `mi` a carácter
    Fi = cumsum(fi) %>% as.character(),                   # Convertir `Fi` a carácter
    Hi = cumsum(fi / sum(fi)) %>% as.character()          # Convertir `Hi` a carácter
  ) %>% 
  relocate(Edad, mi, fi)
  

# Agregar la fila total con casillas en blanco
tabla <- tabla %>% 
  add_row(Edad = "Total", mi = "", fi = sum(tabla$fi), hi = sum(tabla$hi), Fi = "", Hi = "")

# Generar la tabla con knitr::kable y agregar título
tabla %>% 
  knitr::kable(
    col.names = c("Edad", "mi", "fi", "hi", "Fi", "Hi"), 
    align = c("l", "r", "r", "r", "r", "r")
  ) %>% 
  kableExtra::kable_styling(full_width = FALSE) %>% 
  kableExtra::add_header_above(c("Distribuciones de frecuencias para la variable Edad" = 6))
Distribuciones de frecuencias para la variable Edad
Edad mi fi hi Fi Hi
[14,19] 16.5 6 0.030 6 0.03
(19,24] 21.5 18 0.090 24 0.12
(24,29] 26.5 24 0.120 48 0.24
(29,34] 31.5 25 0.125 73 0.365
(34,39] 36.5 23 0.115 96 0.48
(39,44] 41.5 24 0.120 120 0.6
(44,49] 46.5 30 0.150 150 0.75
(49,54] 51.5 24 0.120 174 0.87
(54,59] 56.5 21 0.105 195 0.975
(59,64] 61.5 5 0.025 200 1
Total 200 1.000
Ver código
library(ggplot2)

# Crear el dataframe manualmente (según tu tabla)
edad <- data.frame(
  li = c(14, 19, 24, 29, 34, 39, 44, 49, 54, 59),
  ls = c(19, 24, 29, 34, 39, 44, 49, 54, 59, 64),
  mi = c(16.5, 21.5, 26.5, 31.5, 36.5, 41.5, 46.5, 51.5, 56.5, 61.5),
  fi = c(6, 18, 24, 25, 23, 24, 30, 24, 21, 5)
)

# Graficar histograma (usando geom_col porque son datos agrupados)
ggplot(edad, aes(x = mi, y = fi)) +
  geom_col(width = 5, fill = "steelblue", color = "black") +
  labs(
    title = "Histograma de la edad de los deportistas",
    x = "Edad",
    y = "Frecuencia"
  ) +
  theme_minimal()

Ver código
library(ggplot2)

# Crear el dataframe según tu tabla
edad <- data.frame(
  li = c(14, 19, 24, 29, 34, 39, 44, 49, 54, 59),
  ls = c(19, 24, 29, 34, 39, 44, 49, 54, 59, 64),
  Hi = c(0.03, 0.12, 0.24, 0.365, 0.48, 0.6, 0.75, 0.87, 0.975, 1)
)

# Graficar la ojiva
ggplot(edad, aes(x = ls, y = Hi)) +
  geom_line(color = "blue", size = 1) +
  geom_point(color = "red", size = 2) +
  labs(
    title = "Ojiva de la edad de los deportistas",
    x = "Edad (límite superior del intervalo)",
    y = "Frecuencia acumulada relativa"
  ) +
  scale_y_continuous(labels = scales::percent) +
  theme_minimal()

Ver código
library(ggplot2)
library(dplyr)

# Datos agrupados
edad <- data.frame(
  mi = c(16.5, 21.5, 26.5, 31.5, 36.5, 41.5, 46.5, 51.5, 56.5, 61.5),
  fi = c(6, 18, 24, 25, 23, 24, 30, 24, 21, 5)
)

# Expandir los datos (aproximación)
edad_expandida <- edad %>%
  slice(rep(1:n(), fi))

# Gráfico de densidad
ggplot(edad_expandida, aes(x = mi)) +
  geom_density(fill = "steelblue", alpha = 0.5, size = 1) +
  labs(
    title = "Densidad de la edad de los deportistas",
    x = "Edad",
    y = "Densidad"
  ) +
  theme_minimal()

La distribución etaria de la muestra (n = 200) evidencia una notable concentración de participantes en la etapa de madurez, destacando el intervalo de 44 a 49 años como el de mayor prevalencia con el 15% (f_i = 30) de la población total. Asimismo, se observa una representatividad significativa y constante en los rangos intermedios entre los *24 y 54 años, donde las frecuencias relativas oscilan alrededor del 12% por cada grupo decenal. En términos acumulados, el 60% de los individuos evaluados tiene 44 años o menos (H_i = 0.60), mientras que los extremos generacionales (menores de 19 y mayores de 59 años) presentan la menor participación con apenas un 3% y 2.5% respectivamente, lo cual delimita el perfil predominante del estudio como una población adulta activa con una baja presencia de jóvenes y adultos mayores.

6.5 .Tablas de contingencia

Ver código
# Cargar las bibliotecas necesarias
library(dplyr)
library(readxl)
library(kableExtra)



# Crear una tabla de contingencia con EDUCACION y ESTRATO
table_ESCOLARIDAD_DEPORTE <- table(deporte$ESCOLARIDAD, deporte$ESCOLARIDAD)

# Convertir la tabla a un data frame para facilitar el manejo de datos
table_df <- as.data.frame.matrix(table_ESCOLARIDAD_DEPORTE)

# Calcular los totales de frecuencia absoluta (Total)
table_df$Total <- rowSums(table_df)  # Totales por fila
total_fi <- sum(table_df$Total)      # Total general

# Añadir una fila de totales al final de la tabla
table_df <- rbind(table_df, Total = c(colSums(table_ESCOLARIDAD_DEPORTE), total_fi))

# Mostrar la tabla con kableExtra, aplicando color solo a la fila de Totales
table_df %>%
  kable("html", caption = "Tabla de Frecuencias absolutas de ESCOLARIDAD vs DEPORTE de los deportistas") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = F, position = "center") %>%
  row_spec(nrow(table_df), bold = T, color = "white", background = "darkblue")  # Resaltar solo la fila de Totales
Tabla de Frecuencias absolutas de ESCOLARIDAD vs DEPORTE de los deportistas
Posgrado Pregrado Primaria Secundaria Total
Posgrado 56 0 0 0 56
Pregrado 0 53 0 0 53
Primaria 0 0 44 0 44
Secundaria 0 0 0 47 47
Total 56 53 44 47 200


Ver código
# Cargar las bibliotecas necesarias
library(dplyr)
library(readxl)
library(kableExtra)


# Crear una tabla de contingencia con FUNCION y ESTRATO
table_ESCOLARIDAD_DEPORTE <- table(deporte$ESCOLARIDAD, deporte$DEPORTE)

# Convertir la tabla a un data frame para facilitar el manejo de datos
table_df <- as.data.frame.matrix(table_ESCOLARIDAD_DEPORTE)

# Calcular el total general para las frecuencias relativas
total_fi <- sum(table_df)  # Total general para todas las celdas

# Calcular las frecuencias relativas
table_df <- table_df / total_fi  # Dividir cada valor por el total general para obtener la frecuencia relativa

# Calcular los totales de frecuencia relativa por fila y columna
table_df$Total <- rowSums(table_df)  # Totales por fila (frecuencias relativas)
total_column <- colSums(table_df)  # Totales por columna (frecuencias relativas)

# Añadir una fila de totales al final de la tabla
table_df <- rbind(table_df, Total = total_column)

# Mostrar la tabla con kableExtra, aplicando color solo a la fila de Totales
table_df %>%
  kable("html", caption = "Tabla de Frecuencias Relativas de ESCOLARIDAD vs DEPORTE de los deportistas") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = F, position = "center") %>%
  row_spec(nrow(table_df), bold = T, color = "white", background = "darkblue")  # Resaltar solo la fila de Totales
Tabla de Frecuencias Relativas de ESCOLARIDAD vs DEPORTE de los deportistas
Fútbol Voleibol Gimnasia Atletismo Baloncesto Tenis Natación Total
Posgrado 0.045 0.045 0.04 0.035 0.035 0.040 0.040 0.280
Pregrado 0.040 0.040 0.03 0.025 0.070 0.015 0.045 0.265
Primaria 0.035 0.025 0.02 0.040 0.050 0.025 0.025 0.220
Secundaria 0.035 0.030 0.04 0.025 0.025 0.030 0.050 0.235
Total 0.155 0.140 0.13 0.125 0.180 0.110 0.160 1.000
Ver código
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
library(readxl)

# Calcular los porcentajes de cada categoría de ESTRATO dentro de cada ESTADO
data_porcentaje <- deporte %>%
  count(PESO, ESTATURA) %>%
  group_by(PESO) %>%
  mutate(porcentaje = n / sum(n) * 100)

# Crear el diagrama de barras conjuntas con porcentajes
ggplot(data_porcentaje, aes(x = PESO, y = porcentaje, fill = ESTATURA)) +
  geom_bar(stat = "identity", position = "dodge") +  # Usar "stack" si deseas barras apiladas
  labs(title = "Distribución porcentual de Peso por Estatura",
       x = "Peso",
       y = "Porcentaje",
       fill = "Estatura") +
  theme_minimal() +
  geom_text(aes(label = sprintf("%.1f%%", porcentaje)), 
            position = position_dodge(0.9), 
            vjust = -0.5, 
            size = 3)

Ver código
# Cargar las librerías necesarias
library(ggplot2)
library(dplyr)
library(readxl)


# Calcular los porcentajes de cada categoría de ESTRATO dentro de cada ESTADO
data_porcentaje <- deporte %>%
  count(CINTURA, CADERA) %>%
  group_by(CINTURA) %>%
  mutate(porcentaje = n / sum(n) * 100)

# Crear el diagrama de barras apiladas con porcentajes
ggplot(data_porcentaje, aes(x = CINTURA, y = porcentaje, fill = CADERA)) +
  geom_bar(stat = "identity", position = "stack") +
  labs(title = "Distribución porcentual de Cintura por Cadera",
       x = "Cintura",
       y = "Porcentaje",
       fill = "Cadera") +
  theme_minimal() +
  geom_text(aes(label = sprintf("%.1f%%", porcentaje)), 
            position = position_stack(vjust = 0.5), 
            color = "white",
            size = 3)

El análisis bivariado de las frecuencias relativas evidencia que el nivel de Posgrado es el de mayor representatividad en la muestra con un 28% del total, mostrando una distribución de prácticas deportivas notablemente homogénea entre sus integrantes. En cuanto a las preferencias disciplinarias de la población general, el Baloncesto destaca como el deporte más practicado con un 18%, impulsado principalmente por los sujetos con nivel de Pregrado (7%). Por el contrario, el Tenis registra la menor participación global con un 11%, concentrándose mínimamente en el sector de nivel superior. En conjunto, los datos sugieren que, a medida que aumenta el nivel de escolaridad (Posgrado y Pregrado, sumando un 54.5%), existe una tendencia a la diversificación de actividades físicas, mientras que en los niveles de Primaria y Secundaria se observa una mayor polarización hacia deportes específicos como el Baloncesto y la Natación, respectivamente.

Referencias

Wickham, Hadley, Mara Averick, Jennifer Bryan, Winston Chang, Lucy D’Agostino McGowan, Romain François, Garrett Grolemund, et al. 2019. «Welcome to the tidyverse» 4: 1686. https://doi.org/10.21105/joss.01686.
Wickham, Hadley, y Jennifer Bryan. 2025. «readxl: Read Excel Files». https://doi.org/10.32614/CRAN.package.readxl.
William Revelle. 2026. «psych: Procedures for Psychological, Psychometric, and Personality Research». https://CRAN.R-project.org/package=psych.
Zhu, Hao. 2024. «kableExtra: Construct Complex Table with ’kable’ and Pipe Syntax». https://doi.org/10.32614/CRAN.package.kableExtra.