El presente trabajo tiene como objetivo realizar un análisis exploratorio de la base de datos suministrada, la cual contiene información relacionada con distintos aspectos de la logística de transporte. A partir de esta información se busca identificar las características principales de los datos, revisar su calidad y comprender mejor el comportamiento de las variables. Para ello, se desarrollan etapas que incluyen la contextualización de las variables, la descripción general de la base, el análisis según el tipo de variable, la revisión de valores faltantes y la detección de posibles valores atípicos.

1. Contextualización de la base de datos y variables

En esta sección presentamos la base de datos utilizada para el taller y describimos cada variable de forma clara y operacional. El análisis fue orientado a obtener información práctica para la gestión logística: identificar rutas con mayores costos, evaluar tiempos de entrega y detectar patrones inusuales que requieran intervención.

1.1 Origen y objetivo de la base de datos

La base de datos proviene de un conjunto de registros de operaciones logísticas con 100 observaciones. Cada fila representa un recorrido o servicio efectuado por la empresa durante el periodo de estudio. El objetivo de este análisis es explorar la distribución de kilómetros recorridos, tiempos de entrega y costos operativos por ruta, y a partir de ello realizar inferencias muestrales sobre costos y proporciones de presencia en una ruta específica.

# Cargar datos
datos <- read_csv(params$data_file, show_col_types = FALSE) %>% clean_names()
# Mostrar primeras filas
datos %>% slice_head(n = 8)
## # A tibble: 8 × 4
##   ruta       km_recorridos tiempo_entrega_horas costos_operativos
##   <chr>              <dbl>                <dbl>             <dbl>
## 1 Ruta Sur            1796                 17.2            17459.
## 2 Ruta Norte          4856                 29.8             9828.
## 3 Ruta Sur            2909                 13.3            11964.
## 4 Ruta Oeste          3643                 12.7            18626.
## 5 Ruta Este           4753                 23.1            12812.
## 6 Ruta Oeste          4354                  1.1            19844.
## 7 Ruta Oeste          3956                 46.8             9429.
## 8 Ruta Oeste          2001                 45.5            12759.

1.2 Descripción operacional de las variables

A continuación describimos cada variable, qué mide y sus unidades, con un breve comentario sobre su utilidad para la toma de decisiones:

Descripción de variables
variable tipo descripcion comentario
ruta Categórica (texto) Identifica la ruta o zona correspondiente al recorrido (ej: ‘Ruta Sur’, ‘Ruta Norte’, etc.). Útil para segmentar desempeño por zona. Variable que usaremos para recodificar una binaria (ej. es_ruta_sur).
km_recorridos Numérica (entera, km) Distancia total recorrida en kilómetros para el servicio. Indicador clave para estimar consumo de combustible y desgaste de flota. Se evaluará su distribución y presencia de valores atípicos.
tiempo_entrega_horas Numérica (continuo, horas) Tiempo total de entrega medido en horas. Permite analizar eficiencia y cumplimiento de ventanas de servicio. Relacionaremos con kilómetros y costos para entender eficiencia.
costos_operativos Numérica (continuo, monetary units) Costos operativos asociados al recorrido (transporte, combustible, peajes, mantenimiento). Métrica principal para evaluar rentabilidad y eficiencia. Se utilizará como variable continua para el análisis de media muestral.

2. Características generales de la base de datos

En este punto se presentan las dimensiones exactas, nombres y tipos de variables encontrados en la base de datos. Esta información es de suma importancia para la documentación del trabajo.

# Dimensiones
dims <- dim(datos)
n_filas <- dims[1]; n_columnas <- dims[2]

# Tabla de resumen con nombres y tipos (sin repetir información)
tabla_tipos <- tibble(
  Variable = names(datos),
  Tipo = sapply(datos, function(x) class(x)[1]),
  Ejemplo = sapply(datos, function(x) as.character(head(na.omit(x),1))[1])
)

# Mostrar resultados
tibble(Clave = c("Número de filas", "Número de columnas"),
       Valor = c(n_filas, n_columnas)) %>%
  kable() %>% kable_styling(full_width = FALSE) %>% row_spec(0, background = "#F7F7F7")
Clave Valor
Número de filas 100
Número de columnas 4
tabla_tipos %>% kable(caption = "Nombres de variables y tipos detectados") %>%
  kable_styling(full_width = FALSE) %>% row_spec(0, bold = TRUE, background = "#E8F6EF")
Nombres de variables y tipos detectados
Variable Tipo Ejemplo
ruta character Ruta Sur
km_recorridos numeric 1796
tiempo_entrega_horas numeric 17.2
costos_operativos numeric 17458.55

La base contiene exactamente 100 observaciones y 4 variables.

3. Análisis de variables según su tipo

En esta sección hacemos un análisis separado para variables numéricas y categóricas. Primero aclaramos cuáles son y qué representan.

3.1 Variables numéricas (qué son y cuáles): Km Recorridos, Tiempo de Entrega en Horas, Costos Operativos.

Estas variables cuantifican magnitudes continuas o discretas (km enteros) relacionadas con la operación logística. A continuación presentamos medidas resumen, gráficos y una explicación interpretativa de cada resultado.

library(psych)

datos_num <- datos %>%
  select(km_recorridos, tiempo_entrega_horas, costos_operativos) %>%
  rename(
    "Kilómetros recorridos" = km_recorridos,
    "Tiempo de entrega (horas)" = tiempo_entrega_horas,
    "Costos operativos" = costos_operativos
  )

describe(datos_num)
##                           vars   n     mean      sd  median  trimmed     mad
## Kilómetros recorridos        1 100  2575.72 1385.56  2729.0  2568.32 1651.62
## Tiempo de entrega (horas)    2 100    25.54   14.89    25.9    25.83   19.57
## Costos operativos            3 100 11048.70 5736.23 10407.5 11031.21 8318.61
##                               min      max    range  skew kurtosis     se
## Kilómetros recorridos      166.00  4948.00  4782.00  0.03    -1.09 138.56
## Tiempo de entrega (horas)    1.10    47.60    46.50 -0.04    -1.28   1.49
## Costos operativos         1008.57 19844.28 18835.71 -0.01    -1.35 573.62

La tabla de variables numéricas muestra que, en promedio, los recorridos son de 2.575 km, el tiempo de entrega es de unas 25,5 horas y los costos operativos alcanzan 11.048. Estos valores reflejan las características generales de las operaciones y permiten tener una idea del nivel de distancia, tiempo y gasto involucrado en los envíos.

datos %>%
  pivot_longer(cols = c(km_recorridos, tiempo_entrega_horas, costos_operativos),
               names_to = "variable", values_to = "valor") %>%
  ggplot(aes(x = valor)) +
  geom_histogram(bins = 20, fill = "skyblue", color = "black") +
  facet_wrap(~variable, scales = "free") +
  theme_minimal()

3.2 Variables categóricas (qué son y cuáles): Ruta.

La variable ruta identifica la zona de operación; es esencial para segmentar los resultados. A continuación mostramos frecuencias y una explicación interpretativa por categoría.

tabla_ruta <- datos %>% count(ruta, name = "freq") %>% mutate(prop = freq / sum(freq))
tabla_ruta %>% arrange(desc(freq)) %>% kable(caption = "Frecuencia por ruta") %>%
  kable_styling(full_width = FALSE) %>% row_spec(0, background = "#FDEBD0")
Frecuencia por ruta
ruta freq prop
Ruta Oeste 30 0.30
Ruta Sur 29 0.29
Ruta Norte 21 0.21
Ruta Este 20 0.20

Al observar qué rutas concentran más servicios se puede priorizar auditorías de eficiencia o campañas para optimizar costos en las rutas más frecuentes.

4. Revisión de valores faltantes (NA)

faltantes <- sapply(datos, function(x) sum(is.na(x)))
tibble(variable = names(faltantes), n_na = as.integer(faltantes), prop_na = n_na / nrow(datos)) %>%
  arrange(desc(prop_na)) %>%
  kable(caption = "Conteo de valores faltantes por variable") %>%
  kable_styling(full_width = FALSE) %>% row_spec(0, background = "#F7EEF8")
Conteo de valores faltantes por variable
variable n_na prop_na
ruta 0 0
km_recorridos 0 0
tiempo_entrega_horas 0 0
costos_operativos 0 0

Luego de un análisis se puede decir que no existen valores faltantes, es decir, todas las variables están completas y listas para su análisis. Esto indica que la base de datos está completa, lo cual facilita la realización de análisis estadísticos y modelos posteriores sin necesidad de imputación de datos.

5. Detección de valores atípicos

A continuación presentamos boxplots para identificar outliers en las variables numéricas. Después de se explica el significado y cómo interpretar los posibles outliers.

# Definir las variables numéricas antes de pivot_longer
vars_num <- names(datos)[sapply(datos, is.numeric)]

datos %>%
  pivot_longer(all_of(vars_num), names_to = "variable", values_to = "valor") %>%
  ggplot(aes(x = variable, y = valor)) +
  geom_boxplot()

Interpretación detallada sobre boxplots y outliers:

El boxplot muestra la mediana (línea central), el primer y tercer cuartil (caja) y los “bigotes” que suelen extenderse hasta 1.5×IQR desde los cuartiles. Los puntos fuera de los bigotes se consideran outliers potenciales. Un outlier puede deberse a errores de registro, un caso extremo válido (por ejemplo, un servicio muy largo) o a variabilidad natural. Para costos_operativos, outliers altos indicarían recorridos con costos anómalamente altos, por lo tanto, se debe priorizar la investigación para confirmar si corresponde a mayor distancia, peajes, o errores contables.

6. Aplicación de Distribuciones Muestrales (media y proporción)

Antes de calcular las distribuciones muestrales explicamos la elección de variables y parámetros.

6.1 Justificación de las variables y tamaño muestral

  • Variable continua elegida para media: costos_operativos. Justificación: Los costos son la métrica central para toma de decisiones en logística; conocer su promedio y su variabilidad ayuda a estimar presupuestos y detectar rutas no rentables. Además, es una variable continua y adecuada para análisis de medias.
  • Variable dicotómica para proporción: es_ruta_sur definida como 1 si ruta == “Ruta Sur”, 0 en otro caso. Justificación: Interesa conocer la proporción de servicios que se realizan en una ruta específica para priorizar recursos o aplicar políticas regionales.
  • Tamaño poblacional N: 100 (total de observaciones). En este caso N = 100.
  • Tamaño muestral n: optamos por n = 30. Justificación: n = 30 es un umbral práctico que suele justificar la aproximación normal del estimador de media, además es un tamaño reproducible para prácticas
# Preparar variables
datos <- datos %>% mutate(es_ruta_sur = if_else(str_to_lower(ruta) == "ruta sur", 1, 0))
var_cont <- "costos_operativos"
var_bin <- "es_ruta_sur"
N <- nrow(datos)
n <- 30
x <- datos[[var_cont]]
pvar <- datos[[var_bin]]
list(N=N, n=n, var_cont=var_cont, var_bin=var_bin)
## $N
## [1] 100
## 
## $n
## [1] 30
## 
## $var_cont
## [1] "costos_operativos"
## 
## $var_bin
## [1] "es_ruta_sur"

6.2 Media muestral (costos_operativos)

mu_hat <- mean(x, na.rm = TRUE)
s_hat <- sd(x, na.rm = TRUE)
SE_xbar <- s_hat / sqrt(n) * sqrt((N - n) / (N - 1))  # FPC
tibble(mu_hat = mu_hat, s_hat = s_hat, SE_xbar = SE_xbar)
## # A tibble: 1 × 3
##   mu_hat s_hat SE_xbar
##    <dbl> <dbl>   <dbl>
## 1 11049. 5736.    881.

Explicación del procedimiento:
1. Estimamos la media y desviación estándar de la variable en la población completa (mu_hat y s_hat).
2. Calculamos el error estándar de la media para muestras de tamaño n, aplicando la corrección por población finita (FPC) porque extraemos sin reemplazo de una población relativamente pequeña: \(SE_{\bar X}=\dfrac{s}{\sqrt{n}}\sqrt{\dfrac{N-n}{N-1}}\).
3. Asumimos la aproximación normal: \(\bar X \approx \mathcal{N}(\hat{\mu}, SE_{\bar X}^2)\).

Elegimos umbrales contextualizados para responder probabilidades: - (c\) = la media observada \(\hat{\mu}\) (probabilidad de obtener una muestra con media mayor que la observada). - (a\) y (b\) = percentiles 40 y 60 de costos_operativos (rango central moderado).

c <- mu_hat
a <- quantile(x, 0.4, na.rm = TRUE)
b <- quantile(x, 0.6, na.rm = TRUE)

p_mayor_c <- 1 - pnorm(c, mean = mu_hat, sd = SE_xbar)
p_entre_ab <- pnorm(b, mean = mu_hat, sd = SE_xbar) - pnorm(a, mean = mu_hat, sd = SE_xbar)

tibble(umbral_c = c, a = a, b = b, `P(Xbar > c)` = p_mayor_c, `P(a < Xbar < b)` = p_entre_ab)
## # A tibble: 1 × 5
##   umbral_c     a      b `P(Xbar > c)` `P(a < Xbar < b)`
##      <dbl> <dbl>  <dbl>         <dbl>             <dbl>
## 1   11049. 9433. 13244.           0.5             0.960

Interpretación: Si P(X̄ > c) es cercana a 0.5 es esperable; valores extremos (muy cercanos a 0 o 1) indican que observar una media así con n=30 es muy improbable, lo que sugiere que la media poblacional real sería diferente o que la variabilidad es baja/alta. Para la gestión: si la probabilidad de que la media muestral supere cierto umbral es alta, la empresa debe preparar presupuesto adicional para cubrir esos costos promedio.

6.3 Proporción muestral (es_ruta_sur)

p_hat <- mean(pvar, na.rm = TRUE)
SE_phat <- sqrt(p_hat * (1 - p_hat) / n) * sqrt((N - n) / (N - 1))
tibble(p_hat = p_hat, SE_phat = SE_phat)
## # A tibble: 1 × 2
##   p_hat SE_phat
##   <dbl>   <dbl>
## 1  0.29  0.0697

Explicación del procedimiento:
1. Calculamos la proporción poblacional aproximada (\hat p\) (fracción de observaciones en Ruta Sur).
2. Calculamos el error estándar con FPC: \(SE_{\hat p}=\sqrt{\dfrac{\hat p(1-\hat p)}{n}}\sqrt{\dfrac{N-n}{N-1}}\).
3. Aproximamos la distribución muestral por normal: \(\hat p \approx \mathcal{N}(\hat p, SE_{\hat p}^2)\).

Evaluamos probabilidades de interés: (P(\hat p > 0.5)\) y (P(0.4 < \hat p < 0.6)\).

c_prop <- 0.5; a_prop <- 0.4; b_prop <- 0.6
p_mayor_c_prop <- 1 - pnorm(c_prop, mean = p_hat, sd = SE_phat)
p_entre_ab_prop <- pnorm(b_prop, mean = p_hat, sd = SE_phat) - pnorm(a_prop, mean = p_hat, sd = SE_phat)
tibble(umbral_c = c_prop, a = a_prop, b = b_prop, `P(phat > c)` = p_mayor_c_prop, `P(a < phat < b)` = p_entre_ab_prop)
## # A tibble: 1 × 5
##   umbral_c     a     b `P(phat > c)` `P(a < phat < b)`
##      <dbl> <dbl> <dbl>         <dbl>             <dbl>
## 1      0.5   0.4   0.6       0.00129            0.0572

Interpretación: Estas probabilidades informan qué tan plausible es que una muestra de tamaño n muestre una proporción de servicios en Ruta Sur mayor al 50% (u otra banda). Si es improbable, no se esperaría que Ruta Sur concentre más de la mitad de los servicios, y la organización puede decidir asignar recursos en función de esta evidencia.

7. Recomendaciones y conclusiones.

A partir de la información de la base de datos y las distribuciones muestrales, se puede evidenciar que los datos están completos, sin valores faltantes, lo que facilita el análisis. Se recomenda revisar los outliers de costos para determinar si corresponden a recorridos válidos o requieren ajustes, así como optimizar las rutas con tiempos de entrega elevados teniendo en cuenta congestión y horarios pico. También conviene monitorear la proporción por ruta para evaluar concentración de recursos y riesgo operativo, mejorar la calidad de los datos documentando fechas y estandarizando categorías, y, en decisiones críticas, considerar muestras más grandes o análisis adicionales.