Problema a Investigar

El gerente de una empresa de servicios en Neiva afirma que sus empleados están llegando tarde a trabajar de manera sistemática. Igualmente, afirma que más de la mitad de sus empleados llegan después de las 8:30 a.m. a sus puestos de trabajo, lo cual representa el límite de tolerancia antes de efectuar un llamado de atención a sus hojas de vida.

Sabiendo que la hora estipulada es a las 8:00 a.m. y que contamos con los registros de tiempos de entrada de una población de \(N = 70\) empleados, se requiere aplicar un diseño muestral probabilístico estructurado para determinar si la percepción estadística del gerente es acertada o no.


Objetivos

Objetivo General

Determinar estadísticamente si las afirmaciones del Gerente respecto al incumplimiento en las horas de llegada son ciertas, utilizando para ello las estimaciones derivadas de un Muestreo Aleatorio Simple (MAS) y de un Muestreo Sistemático.

Objetivos Específicos

  • Estimar la hora promedio de entrada de los empleados en la empresa (\(\bar{x}\)), validando si el promedio muestral se acerca al parámetro poblacional real.
  • Determinar la proporción (\(p\)) de empleados que llegan tarde a trabajar (es decir, aquellos que ingresan después de las 8:30 a.m., superando los 30 minutos de retraso).
  • Comparar los distintos métodos de muestreo probabilístico (Aleatorio Simple, Sistemático y Sistemático Inverso) para emitir conclusiones sustentadas respecto a los castigos que impondrá el gerente.

Preparación de los Datos y Librerías

Como se especificó previamente, trabajaremos con la transformación de la hora de llegada a “minutos de retraso” tomando como eje temporal o minuto “0” las 8:00 a.m.

# Cargar librería para el tratamiento de datos y gráficos
library(tidyverse)

# 1. Población con N = 70. Los valores representan los minutos transcurridos tras las 8:00 a.m.
tiempos <- c(0,0,0,1,5,10,10,12,13,15,15,15,17,17,17,18,18,18,19,20,
             21,22,24,25,25,25,26,26,28,29,30,30,30,31,32,33,33,33,34,36,
             37,38,39,40,40,40,40,41,41,42,43,45,45,46,47,48,49,50,50,50,
             52,53,54,55,56,57,59,60,70,95)

# Convertir a tibble general para operaciones con dplyr
df_poblacion <- tibble(
  id_empleado = 1:70, # Damos un ID para entender la población en el muestreo
  retraso = tiempos
)

1. Muestreo Aleatorio Simple (MAS)

A diferencia del muestreo por conveniencia, el MAS otorga a cada empleado las mismas posibilidades de ser seleccionado al azar. Dado que se conoce la población total (\(N = 70\)), en lugar de tomar un tamaño de muestra arbitrario, calcularemos el tamaño de la muestra representativo (\(n\)) para estimar la proporción.

Asumimos un nivel de confianza del 95% (\(Z = 1.96\)), un margen de error admisible del \(10\%\) (\(E = 0.10\)), y la máxima varianza posible (\(p = 0.5, q = 0.5\)). Además, considerando posibles inasistencias en la revisión de registros, aplicaremos una tasa de no respuesta (\(TNR\)) del \(5\%\).

# Parámetros para el tamaño de la muestra
N <- nrow(df_poblacion)
Z_conf <- 1.96
p <- 0.5
q <- 0.5
E <- 0.10
TNR <- 0.05

# Fórmula para población finita
n_teorico <- (Z_conf^2 * N * p * q) / (E^2 * (N - 1) + Z_conf^2 * p * q)

# Aplicando Tasa de No Respuesta (TNR)
n_muestra <- ceiling(n_teorico / (1 - TNR))

cat("Tamaño de muestra teórico (n0):", round(n_teorico, 2), "\n")
## Tamaño de muestra teórico (n0): 40.73
cat("Tamaño de muestra real a extraer (n):", n_muestra, "\n\n")
## Tamaño de muestra real a extraer (n): 43
# Fijar semilla para obtener siempre el mismo muestreo en el reporte de RMarkdown
set.seed(123)

# Muestra con Muestreo Aleatorio Simple según 'n_muestra' calculado
df_mas <- df_poblacion %>%
  sample_n(size = n_muestra, replace = FALSE)

# Cálculos Estratégicos del MAS:
resultados_mas <- df_mas %>%
  summarise(
    media_retraso_min = mean(retraso),
    proporcion_mayor_30 = mean(retraso > 30),
    hora_promedio_entrada = format(
      as.POSIXct("08:00", format="%H:%M") + (media_retraso_min * 60), 
      "%H:%M:%S"
    )
  )

resultados_mas
## # A tibble: 1 × 3
##   media_retraso_min proporcion_mayor_30 hora_promedio_entrada
##               <dbl>               <dbl> <chr>                
## 1              34.3               0.558 08:34:20

Lectura MAS: Como vemos, este muestreo probabilístico puro nos arrojará proporciones (p) y medias (\(\bar{x}\)) representativas del comportamiento general, alejadas del sesgo originado por seleccionar solo al “principio de la lista”.


2. Muestreo Sistemático

Para el muestreo sistemático elegimos elementos de la lista en intervalos regulares (\(k\)). Utilizaremos el mismo tamaño de muestra calculado anteriormente (\(n = 43\)) para que ambos métodos probabilísticos sean equivalentes. La fórmula del salto o intervalo sistemático es \(k = \lfloor\frac{N}{n}\rfloor = \lfloor\frac{70}{43}\rfloor = 1\). Con \(k = 1\), la secuencia toma sujetos de forma consecutiva a partir de un arranque aleatorio \(r \in [1, k]\). En este caso, el sistemático normal captura los primeros \(n\) registros de la base de datos.

# Configuración del sistemático usando el n_muestra calculado
n_sist <- n_muestra
k <- floor(N / n_sist) # k = floor(70/43) = 1

# Validar que k sea al menos 1
if(k < 1) k <- 1

# Arranque desde el primer registro
arranque <- 1

# Generación de la secuencia sistemática (arranque, arranque + k, arranque + 2k...)
# Con k=1, se toman los primeros n_sist registros consecutivos
indices_sistematico <- seq(from = arranque, by = k, length.out = n_sist)

# Validamos que los índices no superen N
indices_sistematico <- indices_sistematico[indices_sistematico <= N]

cat("Salto sistemático (k):", k, "\n")
## Salto sistemático (k): 1
cat("Registros seleccionados: del", min(indices_sistematico), "al", max(indices_sistematico), "\n\n")
## Registros seleccionados: del 1 al 43
# Extracción de la muestra
df_sistematico <- df_poblacion %>%
  slice(indices_sistematico)

# Cálculos Estratégicos del Sistemático:
resultados_sistematico <- df_sistematico %>%
  summarise(
    media_retraso_min = mean(retraso),
    proporcion_mayor_30 = mean(retraso > 30),
    hora_promedio_entrada = format(
      as.POSIXct("08:00", format="%H:%M") + (media_retraso_min * 60), 
      "%H:%M:%S"
    )
  )

resultados_sistematico
## # A tibble: 1 × 3
##   media_retraso_min proporcion_mayor_30 hora_promedio_entrada
##               <dbl>               <dbl> <chr>                
## 1              21.6               0.233 08:21:33

2.1. Muestreo Sistemático Inverso (De Abajo hacia Arriba)

Para asegurar la inclusión de los empleados registrados en los últimos tramos de la lista, aplicaremos un Sistemático Inverso. Con el mismo \(k = 1\), el arranque se fija en el último registro (\(N = 70\)) y la secuencia retrocede hasta completar \(n\) sujetos. De esta forma, el sistemático inverso captura los últimos \(n\) registros de la base de datos, creando un contraste directo con el sistemático normal.

# Mismo tamaño de muestra y salto k = 1
n_sist <- n_muestra
k <- floor(N / n_sist)
if(k < 1) k <- 1

# Arranque fijado en el último registro (N = 70)
arranque_inv <- N

# Secuencia sistemática en reversa: del registro 70 hacia atrás
# Con k=1, se toman los últimos n_sist registros consecutivos
indices_sistematico_inv <- seq(from = arranque_inv, by = -k, length.out = n_sist)

# Validamos límites lógicos
indices_sistematico_inv <- indices_sistematico_inv[indices_sistematico_inv >= 1]

cat("Salto sistemático (k):", k, "\n")
## Salto sistemático (k): 1
cat("Registros seleccionados: del", min(indices_sistematico_inv), "al", max(indices_sistematico_inv), "\n\n")
## Registros seleccionados: del 28 al 70
# Extracción de la muestra original con los índices en reversa
df_sistematico_inv <- df_poblacion %>%
  slice(indices_sistematico_inv)

# Cálculos Estratégicos del Sistemático Invertido:
resultados_sistematico_inv <- df_sistematico_inv %>%
  summarise(
    media_retraso_min = mean(retraso, na.rm = TRUE),
    proporcion_mayor_30 = mean(retraso > 30, na.rm = TRUE),
    hora_promedio_entrada = format(
      as.POSIXct("08:00", format="%H:%M") + (media_retraso_min * 60), 
      "%H:%M:%S"
    )
  )

resultados_sistematico_inv
## # A tibble: 1 × 3
##   media_retraso_min proporcion_mayor_30 hora_promedio_entrada
##               <dbl>               <dbl> <chr>                
## 1              43.9               0.860 08:43:53

2.2. Muestreo Sistemático Fraccionario (Cobertura Completa)

A diferencia de los sistemáticos anteriores con \(k = 1\) (que capturan bloques consecutivos), este método utiliza el salto fraccionario exacto \(k = \frac{N}{n} = \frac{70}{43} \approx 1.63\) sin redondear. Esto garantiza que la muestra abarca toda la base de datos de principio a fin, distribuyendo los \(n\) sujetos de forma equidistante a lo largo de los \(N\) registros.

# Salto fraccionario exacto sin redondear
n_sist <- n_muestra
k_frac <- N / n_sist

# Arranque aleatorio dentro del primer intervalo [1, k_frac]
set.seed(42)
arranque_frac <- runif(1, min = 1, max = k_frac)

# Secuencia fraccionaria a lo largo de toda la base
indices_frac_continuo <- seq(from = arranque_frac, by = k_frac, length.out = n_sist)

# Redondeamos al entero más cercano para obtener filas válidas
indices_frac <- round(indices_frac_continuo)
indices_frac <- indices_frac[indices_frac >= 1 & indices_frac <= N]

cat("Salto sistemático fraccionario (k):", round(k_frac, 2), "\n")
## Salto sistemático fraccionario (k): 1.63
cat("Registros seleccionados: del", min(indices_frac), "al", max(indices_frac), "\n")
## Registros seleccionados: del 2 al 70
cat("Total de sujetos extraídos:", length(indices_frac), "\n\n")
## Total de sujetos extraídos: 43
# Extracción de la muestra
df_sistematico_frac <- df_poblacion %>%
  slice(indices_frac)

# Cálculos Estratégicos del Sistemático Fraccionario:
resultados_sistematico_frac <- df_sistematico_frac %>%
  summarise(
    media_retraso_min = mean(retraso),
    proporcion_mayor_30 = mean(retraso > 30),
    hora_promedio_entrada = format(
      as.POSIXct("08:00", format="%H:%M") + (media_retraso_min * 60), 
      "%H:%M:%S"
    )
  )

resultados_sistematico_frac
## # A tibble: 1 × 3
##   media_retraso_min proporcion_mayor_30 hora_promedio_entrada
##               <dbl>               <dbl> <chr>                
## 1              33.2               0.535 08:33:12

Comparación y Validación de la Población Total (N=70)

Para consolidar las estimaciones y medir nuestro error muestral, comprobamos cómo se ven frente a lo que resulta sacando los datos sobre nuestra tabla real completa.

resultados_poblacion <- df_poblacion %>%
  summarise(
    media_retraso_min = mean(retraso),
    proporcion_mayor_30 = mean(retraso > 30), # Límite para el llamado de atención
    hora_promedio_entrada = format(
      as.POSIXct("08:00", format="%H:%M") + (media_retraso_min * 60), 
      "%H:%M:%S"
    )
  )

resultados_poblacion
## # A tibble: 1 × 3
##   media_retraso_min proporcion_mayor_30 hora_promedio_entrada
##               <dbl>               <dbl> <chr>                
## 1              32.8               0.529 08:32:47

Análisis de Prueba de Hipótesis

Para darle soporte matemático a las sospechas de la junta sobre los retardos del personal, planteamos un contraste de hipótesis de una cola (derecha) bajo un nivel de significancia del \(5\%\) (\(\alpha = 0.05\)). El valor \(Z\) se calculará a partir de cada una de las muestras extraídas, ya que la prueba de hipótesis es una herramienta de inferencia muestral diseñada para estimar parámetros desconocidos de la población.

Planteamiento de las Hipótesis

  • Hipótesis Nula (\(H_0\)): \(\mu \le 30 \text{ minutos de retraso (equivalente a las 8:30 a.m.)}\) (El promedio de retraso del personal es igual o inferior al límite de tolerancia. Cualquier valor tardío es producto del azar en la muestra).
  • Hipótesis Alternativa (\(H_1\)): \(\mu > 30 \text{ minutos de retraso (equivalente a las 8:30 a.m.)}\) (Afirmación del Gerente: El promedio global de retraso es genuina y significativamente superior al margen de tolerancia admitido).
# =====================================================
# CÁLCULO DINÁMICO DEL ESTADÍSTICO Z PARA CADA MUESTRA
# =====================================================
mu_0 <- 30          # Hipótesis nula: el límite de tolerancia es 30 min (8:30 a.m.)
alpha <- 0.05
z_critico <- qnorm(1 - alpha)

# Hora promedio poblacional (referencia)
x_barra_pob <- mean(df_poblacion$retraso)
hora_media <- format(
  as.POSIXct("08:00", format="%H:%M") + (x_barra_pob * 60), "%H:%M:%S"
)

# --- Z-Test sobre la Muestra MAS ---
x_mas <- mean(df_mas$retraso)
s_mas <- sd(df_mas$retraso)
n_mas <- nrow(df_mas)
z_mas <- (x_mas - mu_0) / (s_mas / sqrt(n_mas))
p_mas <- pnorm(z_mas, lower.tail = FALSE)

# --- Z-Test sobre la Muestra Sistemática ---
x_sist <- mean(df_sistematico$retraso)
s_sist <- sd(df_sistematico$retraso)
n_sist_test <- nrow(df_sistematico)
z_sist <- (x_sist - mu_0) / (s_sist / sqrt(n_sist_test))
p_sist <- pnorm(z_sist, lower.tail = FALSE)

# --- Z-Test sobre la Muestra Sistemática Inversa ---
x_inv <- mean(df_sistematico_inv$retraso)
s_inv <- sd(df_sistematico_inv$retraso)
n_inv_test <- nrow(df_sistematico_inv)
z_inv <- (x_inv - mu_0) / (s_inv / sqrt(n_inv_test))
p_inv <- pnorm(z_inv, lower.tail = FALSE)

# --- Z-Test sobre la Muestra Sistemática Fraccionaria ---
x_frac <- mean(df_sistematico_frac$retraso)
s_frac <- sd(df_sistematico_frac$retraso)
n_frac_test <- nrow(df_sistematico_frac)
z_frac <- (x_frac - mu_0) / (s_frac / sqrt(n_frac_test))
p_frac <- pnorm(z_frac, lower.tail = FALSE)

# --- Tabla Comparativa ---
tabla_z <- data.frame(
  Metodo = c("MAS", "Sist. Normal (k=1)", "Sist. Inverso (k=1)", "Sist. Fraccionario"),
  Media_Retraso = round(c(x_mas, x_sist, x_inv, x_frac), 2),
  Desv_Estandar = round(c(s_mas, s_sist, s_inv, s_frac), 2),
  n = c(n_mas, n_sist_test, n_inv_test, n_frac_test),
  Z_Calculado = round(c(z_mas, z_sist, z_inv, z_frac), 4),
  P_Valor = round(c(p_mas, p_sist, p_inv, p_frac), 4),
  Decision = ifelse(c(p_mas, p_sist, p_inv, p_frac) < alpha, 
                    "Se rechaza H0", "No se rechaza H0")
)

cat("Valor crítico (Zc):", round(z_critico, 4), "\n")
## Valor crítico (Zc): 1.6449
cat("Nivel de significancia (α):", alpha, "\n\n")
## Nivel de significancia (α): 0.05
knitr::kable(tabla_z, col.names = c("Método", "Media (min)", "Desv. Est.", "n", 
                                      "Z Calculado", "P-Valor", "Decisión"),
             caption = "Prueba Z para cada método de muestreo")
Prueba Z para cada método de muestreo
Método Media (min) Desv. Est. n Z Calculado P-Valor Decisión
MAS 34.35 15.64 43 1.8239 0.0341 Se rechaza H0
Sist. Normal (k=1) 21.56 10.82 43 -5.1143 1.0000 No se rechaza H0
Sist. Inverso (k=1) 43.88 12.94 43 7.0368 0.0000 Se rechaza H0
Sist. Fraccionario 33.21 18.57 43 1.1334 0.1285 No se rechaza H0
  • Interpretación del estadístico Z: El valor \(Z\) calculado para cada muestra indica cuántas desviaciones estándar se aleja la media muestral observada del límite de tolerancia (30 minutos / 8:30 a.m.). Si este valor supera el cuantil crítico de \(1.645\), existe evidencia estadística suficiente para afirmar que el retraso no es producto del azar.
  • Criterio de decisión: Utilizando un nivel de significancia \(\alpha = 0.05\), el criterio nos impone rechazar la Hipótesis Nula si el estadístico \(Z\) excede el valor crítico de \(1.645\) en la curva normal. Todo suceso más allá de esta frontera denota evidencia fuerte de violación sistemática al reglamento.
# =====================================================
# GRÁFICA COMPARATIVA: LOS 4 VALORES Z EN LA CAMPANA
# =====================================================
x_vals <- seq(-4, 4, length.out = 1000)
df_norm <- data.frame(z = x_vals, densidad = dnorm(x_vals))

zona_rechazo <- df_norm %>% filter(z >= z_critico)

grafica_z <- ggplot(df_norm, aes(x = z, y = densidad)) +
  geom_line(color = "steelblue", linewidth = 1) +
  geom_area(data = zona_rechazo, fill = "red", alpha = 0.3) +
  # Líneas verticales para cada muestra
  geom_vline(xintercept = z_mas, color = "#E74C3C", linetype = "dashed", linewidth = 1) +
  geom_vline(xintercept = z_sist, color = "#2ECC71", linetype = "dashed", linewidth = 1) +
  geom_vline(xintercept = z_inv, color = "#3498DB", linetype = "dashed", linewidth = 1) +
  geom_vline(xintercept = z_frac, color = "#9B59B6", linetype = "dashed", linewidth = 1) +
  # Anotaciones
  annotate("text", x = z_mas + 0.3, y = 0.39, 
           label = paste0("MAS\nZ=", round(z_mas, 2)), color = "#E74C3C", fontface = "bold", size = 3.2) +
  annotate("text", x = z_sist + 0.3, y = 0.33, 
           label = paste0("Sist.\nZ=", round(z_sist, 2)), color = "#2ECC71", fontface = "bold", size = 3.2) +
  annotate("text", x = z_inv + 0.3, y = 0.27, 
           label = paste0("Inv.\nZ=", round(z_inv, 2)), color = "#3498DB", fontface = "bold", size = 3.2) +
  annotate("text", x = z_frac + 0.3, y = 0.21, 
           label = paste0("Frac.\nZ=", round(z_frac, 2)), color = "#9B59B6", fontface = "bold", size = 3.2) +
  annotate("text", x = 3.2, y = 0.03, 
           label = "Zona Rechazo \n(α = 0.05)", color = "darkred") +
  labs(
    title = "Prueba de Hipótesis: Comparación de Z por Método de Muestreo",
    subtitle = expression(paste(H[0], ": ", mu <= "8:30 vs ", H[1], ": ", mu > "8:30")),
    x = "Desviaciones Estándar (Estadístico Z)",
    y = "Densidad Probabilística de Normalidad"
  ) +
  theme_minimal()
  
print(grafica_z)


Conclusiones de la Investigación

Evaluando los resultados estadísticos e inferenciales frente a los tres objetivos específicos planteados al inicio del reporte, se concluye que:

  1. Estimación de la hora promedio de entrada (\(\bar{x}\)): Las tres muestras probabilísticas estiman medias de retraso superiores al límite de tolerancia de 30 minutos (8:30 a.m.). Al contrastar con la población completa (\(N=70\)), se verifica que el verdadero parámetro poblacional recae en las 08:32:47, confirmando el retroceso corporativo generalizado de atención del horario. La prueba Z-Test aplicada a cada muestra permite evaluar si esta diferencia es estadísticamente significativa al \(5\%\).

  2. Determinación de la proporción (\(p\)) de empleados con retraso mayor a 30 minutos: La aseveración directiva argumentando que “más de la mitad” incurre en esta falta disciplinaria (\(p > 0.50\)) ha sido corroborada como VERDADERA ante los datos y la población. El parámetro oficial obtenido sobre todos los funcionarios revela un 52.9% (\(p \approx 0.53\)) de ocurrencia.

  3. Comparación y validación entre los distintos métodos de muestreo probabilístico: Se implementaron cuatro técnicas muestrales: el MAS (selección puramente aleatoria), el Sistemático Normal con \(k=1\) (primeros \(n\) registros), el Sistemático Inverso con \(k=1\) (últimos \(n\) registros), y el Sistemático Fraccionario con \(k \approx 1.63\) (cobertura equidistante de toda la base). Al aplicar la prueba Z-Test individual a cada muestra, se observa que MAS, Sist. Inverso (k=1) rechazan la hipótesis nula (\(H_0\)), mientras que Sist. Normal (k=1), Sist. Fraccionario no alcanzan a rechazarla al nivel de significancia del \(5\%\), debido a la alta variabilidad interna de sus datos. Esta discrepancia entre métodos es precisamente lo que justifica el uso de múltiples técnicas de muestreo: cada una captura una perspectiva distinta de la población. No obstante, al verificar directamente con la población completa (\(N = 70\)), se confirma de forma definitiva que la media real de retraso es de 32.79 minutos (08:32:47), superando los 30 minutos de tolerancia, y que la proporción de empleados con retraso crítico es del 52.9%, lo cual respalda las afirmaciones del gerente más allá de cualquier margen de error muestral.


Veredicto Final: Con fundamento total sustentado por los diseños muestrales ejecutados y ratificados por la inferencia matemática de colas, el gerente posee la totalidad de los justificantes numéricos y probatorios requeridos para hacer efectivos los llamados de atención corporativos y tomar cartas directas sobre los correctivos en la plantilla laboral.