Clasificación de variables

Pregunta 1: Del dataset, identifique y clasifique las variables según su naturaleza (cualitativa o cuantitativa) y tipo (nominal, ordinal, discreta o continua).

clasificacion <- data.frame(
  Variable = c("Estado_Entrega", "Zona", "Tipo_Mercancia",
               "Numero_Paquetes", "Numero_Repartidores", "Tiempo_Horas", "Distancia_Km"),
  Naturaleza = c("Cualitativa", "Cualitativa", "Cualitativa",
                 "Cuantitativa", "Cuantitativa", "Cuantitativa", "Cuantitativa"),
  Tipo = c("Nominal", "Nominal", "Nominal",
           "Discreta", "Discreta", "Continua", "Continua")
)

kable(clasificacion, caption = "Tabla 1. Clasificación de variables de estudio",
      align = "l") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white") %>%
  column_spec(1, bold = TRUE)
Tabla 1. Clasificación de variables de estudio
Variable Naturaleza Tipo
Estado_Entrega Cualitativa Nominal
Zona Cualitativa Nominal
Tipo_Mercancia Cualitativa Nominal
Numero_Paquetes Cuantitativa Discreta
Numero_Repartidores Cuantitativa Discreta
Tiempo_Horas Cuantitativa Continua
Distancia_Km Cuantitativa Continua

Nota: La variable ID es únicamente un identificador del registro y no forma parte del análisis estadístico.


Importación del dataset

Pregunta 2: Importe el dataset en RStudio utilizando la librería readxl.

datos <- read_excel("Dataset_Entregas.xlsx")
datos <- as.data.frame(datos)

kable(datos, caption = "Tabla 2. Dataset de entregas de Speedy Swift",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white") %>%
  scroll_box(width = "100%")
Tabla 2. Dataset de entregas de Speedy Swift
ID Estado_Entrega Zona Tipo_Mercancia Numero_Paquetes Numero_Repartidores Tiempo_Horas Distancia_Km
1 A tiempo Norte Documentos 5 1 1.2 8.5
2 Anticipada Sur Electronicos 3 1 0.9 6.3
3 Tarde Centro Alimentos 7 2 2.8 15.4
4 Extraviada Este Documentos 2 1 3.5 10.2
5 A tiempo Oeste Ropa 6 2 1.7 12.1
6 Anticipada Norte Electronicos 4 1 1.0 7.8
7 Tarde Sur Alimentos 8 2 3.1 18.4
8 A tiempo Centro Ropa 5 1 1.5 9.6
9 Anticipada Este Documentos 3 1 0.8 5.9
10 Extraviada Oeste Electronicos 2 1 4.0 13.7
11 A tiempo Norte Alimentos 6 2 1.8 11.5
12 Anticipada Sur Ropa 4 1 1.1 8.1
13 Tarde Centro Documentos 7 2 2.9 16.8
14 A tiempo Este Electronicos 5 1 1.4 9.3
15 Anticipada Oeste Alimentos 3 1 0.9 6.8
16 Tarde Norte Ropa 8 2 3.3 17.6
17 A tiempo Sur Documentos 4 1 1.6 10.1
18 Extraviada Centro Electronicos 2 1 3.8 14.2
19 Anticipada Este Alimentos 5 1 1.0 7.4
20 A tiempo Oeste Ropa 6 2 1.9 12.8
21 Tarde Norte Documentos 7 2 2.7 15.9
22 Anticipada Sur Electronicos 3 1 0.8 5.7
23 A tiempo Centro Alimentos 5 1 1.5 9.8
24 Extraviada Este Ropa 2 1 4.2 13.9
25 Anticipada Oeste Documentos 4 1 1.1 7.2
26 A tiempo Norte Electronicos 6 2 1.7 11.7
27 Tarde Sur Alimentos 8 2 3.0 18.1
28 Anticipada Centro Ropa 3 1 0.9 6.4
29 A tiempo Este Documentos 5 1 1.3 8.9
30 Tarde Oeste Electronicos 7 2 2.8 16.2

Distribución de frecuencias - Estado_Entrega

Pregunta 3: Construya una tabla de distribución de frecuencias para la variable Estado_Entrega, incluyendo: Frecuencia absoluta, frecuencia relativa y frecuencia relativa porcentual.

tab_frec_cual <- table(Estado_Entrega = datos$Estado_Entrega)
tab_frec_cual2 <- as.data.frame(tab_frec_cual)
names(tab_frec_cual2) <- c("Estado de Entrega", "Frec. Absoluta")
tab_frec_cual2$`Frec. Relativa` <- round(tab_frec_cual2$`Frec. Absoluta` / sum(tab_frec_cual2$`Frec. Absoluta`), 3)
tab_frec_cual2$`Frec. Rel. Acum.` <- round(cumsum(tab_frec_cual2$`Frec. Relativa`), 3)
tab_frec_cual2$`Frec. Porcentual (%)` <- round(tab_frec_cual2$`Frec. Relativa` * 100, 3)
tab_frec_cual2$`Frec. Porc. Acum. (%)` <- round(cumsum(tab_frec_cual2$`Frec. Porcentual (%)`), 3)

total_fila <- data.frame(`Estado de Entrega` = "Total",
                          `Frec. Absoluta` = sum(tab_frec_cual2$`Frec. Absoluta`),
                          `Frec. Relativa` = round(sum(tab_frec_cual2$`Frec. Relativa`), 3),
                          `Frec. Rel. Acum.` = "",
                          `Frec. Porcentual (%)` = round(sum(tab_frec_cual2$`Frec. Porcentual (%)`), 3),
                          `Frec. Porc. Acum. (%)` = "",
                          check.names = FALSE)
tab_frec_cual3 <- rbind(tab_frec_cual2, total_fila)

kable(tab_frec_cual3, caption = "<b>Tabla 3.</b> Distribución de frecuencias - Estado_Entrega",
      align = "c", escape = FALSE) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center",
                font_size = 14) %>%
  row_spec(0, bold = TRUE, background = "#1A5276", color = "white",
           font_size = 14) %>%
  column_spec(1, bold = TRUE, color = "#2C3E50") %>%
  row_spec(nrow(tab_frec_cual3), bold = TRUE, background = "#D6EAF8",
           color = "#1A5276", font_size = 14)
Tabla 3. Distribución de frecuencias - Estado_Entrega
Estado de Entrega Frec. Absoluta Frec. Relativa Frec. Rel. Acum. Frec. Porcentual (%) Frec. Porc. Acum. (%)
A tiempo 10 0.333 0.333 33.3 33.3
Anticipada 9 0.300 0.633 30.0 63.3
Extraviada 4 0.133 0.766 13.3 76.6
Tarde 7 0.233 0.999 23.3 99.9
Total 30 0.999 99.9

Vector tiempo y su estructura

Pregunta 4: Cree en RStudio el vector denominado tiempo utilizando los datos de la variable Tiempo_Horas.

tiempo <- datos$Tiempo_Horas

Pregunta 5: Utilice una función de R para mostrar la estructura del objeto creado e interprete el resultado obtenido.

str(tiempo)
##  num [1:30] 1.2 0.9 2.8 3.5 1.7 1 3.1 1.5 0.8 4 ...

Interpretación: Lo que nos muestra str() es que el vector tiempo es numérico (numeric) y contiene 30 observaciones. Cada valor representa el tiempo de entrega en horas de un pedido. Es una variable cuantitativa continua, lo que significa que puede tomar cualquier valor dentro de un rango (no solo números enteros). Esto es importante porque nos permite aplicar técnicas estadísticas como la fórmula de Sturges para agrupar los datos en intervalos.


Mínimo, máximo y rango

Pregunta 6: Utilizando la variable Tiempo_Horas, determine: Valor mínimo, valor máximo y rango.

rango_df <- data.frame(
  Medida = c("Valor Mínimo (Xmin)", "Valor Máximo (Xmax)", "Rango (Xmax - Xmin)"),
  Valor = c(round(min(tiempo), 3), round(max(tiempo), 3), round(max(tiempo) - min(tiempo), 3))
)

kable(rango_df, caption = "Tabla 4. Medidas de posición - Tiempo_Horas",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white") %>%
  row_spec(3, bold = TRUE, background = "#ECF0F1")
Tabla 4. Medidas de posición - Tiempo_Horas
Medida Valor
Valor Mínimo (Xmin) 0.8
Valor Máximo (Xmax) 4.2
Rango (Xmax - Xmin) 3.4

Interpretación: El tiempo de entrega más rápido fue de 0.8 horas y el más lento de 4.2 horas. La diferencia entre ambos (el rango) es de 3.4 horas, lo que nos da una idea de cuánto varían los tiempos de entrega. Un rango de 3.4 horas es bastante amplio, lo que indica que hay entregas muy rápidas y otras que tardan mucho más.


Frecuencias agrupadas (Función APDA)

Pregunta 7: Construya una tabla de frecuencias agrupadas para los tiempos de entrega.

resultado <- APDA(tiempo)

tabla_con_total <- resultado$tabla
names(tabla_con_total) <- c("Lim. Inferior", "Lim. Superior", "Marca de Clase (Xi)",
                             "Frec. Absoluta", "Frec. Abs. Acum.",
                             "Frec. Relativa", "Frec. Rel. Acum.",
                             "Frec. Porcentual (%)", "Frec. Porc. Acum. (%)")

total_apda <- data.frame(`Lim. Inferior` = "", `Lim. Superior` = "", `Marca de Clase (Xi)` = "Total",
                         `Frec. Absoluta` = sum(resultado$tabla$f_i), `Frec. Abs. Acum.` = "",
                         `Frec. Relativa` = round(sum(resultado$tabla$h_i), 3), `Frec. Rel. Acum.` = "",
                         `Frec. Porcentual (%)` = round(sum(resultado$tabla$`h_i_Porc`), 3),
                         `Frec. Porc. Acum. (%)` = "", check.names = FALSE)
tabla_final <- rbind(tabla_con_total, total_apda)

kable(tabla_final, caption = "<b>Tabla 5.</b> Distribución de frecuencias agrupadas - Tiempo_Horas (Sturges)",
      align = "c", escape = FALSE) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center",
                font_size = 14) %>%
  row_spec(0, bold = TRUE, background = "#1A5276", color = "white",
           font_size = 14) %>%
  column_spec(1:3, bold = TRUE, color = "#2C3E50") %>%
  row_spec(nrow(tabla_final), bold = TRUE, background = "#D6EAF8",
           color = "#1A5276", font_size = 14)
Tabla 5. Distribución de frecuencias agrupadas - Tiempo_Horas (Sturges)
Lim. Inferior Lim. Superior Marca de Clase (Xi) Frec. Absoluta Frec. Abs. Acum. Frec. Relativa Frec. Rel. Acum. Frec. Porcentual (%) Frec. Porc. Acum. (%)
0.8 1.367 1.083 11 11 0.367 0.367 36.667 36.667
1.367 1.933 1.65 8 19 0.267 0.633 26.667 63.333
1.933 2.5 2.217 0 19 0.000 0.633 0.000 63.333
2.5 3.067 2.783 5 24 0.167 0.8 16.667 80
3.067 3.633 3.35 3 27 0.100 0.9 10.000 90
3.633 4.2 3.917 3 30 0.100 1 10.000 100
Total 30 1.001 100.001

Nota: Se utilizó la fórmula de Sturges: \(k = 1 + 3.3 \cdot \log_{10}(n)\) para determinar el número de intervalos. Con \(n = 30\), se obtienen \(k = 6\) intervalos de amplitud \(a = 0.567\).

Interpretación: La tabla nos muestra cómo se distribuyen los tiempos de entrega agrupados en intervalos. El intervalo con más entregas es [0.8, 1.367) horas con 11 paquetes. A medida que aumenta el tiempo de entrega, las frecuencias van disminuyendo, lo que confirma que la mayoría de entregas se hacen en tiempos cortos.


Gráfico de barras e histograma

Pregunta 8: De la variable tiempos de entrega elabore: Un gráfico de barras y un histograma.

orden_estado <- names(sort(table(datos$Estado_Entrega), decreasing = TRUE))
datos$Estado_Entrega <- factor(datos$Estado_Entrega, levels = orden_estado)

p1 <- ggplot(datos, aes(x = Estado_Entrega, fill = Estado_Entrega)) +
  geom_bar(width = 0.6, show.legend = FALSE) +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, fontface = "bold") +
  scale_fill_manual(values = c("Anticipada" = "#27AE60", "A tiempo" = "#2980B9",
                                "Tarde" = "#E67E22", "Extraviada" = "#E74C3C")) +
  labs(title = "Gráfico de barras - Estado de Entrega",
       x = "Estado de Entrega", y = "Frecuencia") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))

p2 <- ggplot(datos, aes(x = Tiempo_Horas)) +
  geom_histogram(breaks = resultado$tabla$LimSup, fill = "#2980B9", color = "white", alpha = 0.85, closed = "left") +
  geom_vline(aes(xintercept = mean(tiempo)), color = "#E74C3C", linetype = "dashed", linewidth = 1) +
  geom_vline(aes(xintercept = median(tiempo)), color = "#27AE60", linetype = "dashed", linewidth = 1) +
  annotate("text", x = mean(tiempo) + 0.05, y = Inf, label = paste("Media =", round(mean(tiempo), 3)),
           vjust = 2, hjust = 0, color = "#E74C3C", fontface = "bold", size = 3.5) +
  annotate("text", x = median(tiempo) - 0.05, y = Inf, label = paste("Mediana =", round(median(tiempo), 3)),
           vjust = 3.5, hjust = 1, color = "#27AE60", fontface = "bold", size = 3.5) +
  scale_x_continuous(breaks = resultado$tabla$LimInf) +
  labs(title = "Histograma - Tiempo de Entrega (horas)",
       x = "Tiempo (horas)", y = "Frecuencia") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))

grid.arrange(p1, p2, ncol = 2)


Análisis de la distribución

Pregunta 9: Analice la distribución observada en el histograma: ¿La distribución es simétrica o asimétrica? Justifique su respuesta.

Análisis: La distribución del histograma presenta una asimetría positiva (a la derecha). Esto se evidencia porque: (1) la media (2.007) es mayor que la mediana (1.65), y (2) la cola de la distribución se extiende hacia la derecha. La mayoría de entregas se realizan en tiempos cortos, pero hay algunas que tardan bastante o se extraviaron, generando valores atípicos altos que jalan la distribución hacia la derecha.


Intervalo con mayor frecuencia

Pregunta 10: Identifique el intervalo de tiempo en horas, con mayor frecuencia e interprete el resultado en el contexto del problema.

u <- which.max(resultado$tabla$f_i)
fila_max <- resultado$tabla[u, ]

cat("Intervalo con mayor frecuencia: [", fila_max$LimInf, ",", fila_max$LimSup, ")\n")
## Intervalo con mayor frecuencia: [ 0.8 , 1.367 )
cat("Marca de clase (Xi):", fila_max$Xi, "\n")
## Marca de clase (Xi): 1.083
cat("Frecuencia absoluta:", fila_max$f_i, "entregas\n")
## Frecuencia absoluta: 11 entregas
cat("Frecuencia relativa:", fila_max$h_i, "\n")
## Frecuencia relativa: 0.367
cat("Frecuencia porcentual:", fila_max$h_i_Porc, "%\n")
## Frecuencia porcentual: 36.667 %

Interpretación: El intervalo de mayor frecuencia es [0.8, 1.367) horas, con 11 entregas (36.667% del total). Esto indica que la mayoría de los paquetes se entregan en ese rango de tiempo, lo cual es una buena señal para la empresa porque significa que sus tiempos de entrega son en general bastante eficientes.


Medidas estadísticas - Tiempo_Horas

Pregunta 11: De la variable, Tiempo_Horas. Determine e interprete: Media aritmética, Mediana, Moda, Desviación estándar y el Coeficiente de variación.

stats_completos <- data.frame(
  Medida = c("Media Aritmética (X̄)", "Mediana (Me)", "Moda (Mo)",
             "Desviación Estándar (S)", "Coef. de Variación (CV%)"),
  Valor = c(round(mean(tiempo), 3), round(median(tiempo), 3),
            round(resultado$resumen$Moda, 3), round(sd(tiempo), 3),
            round(resultado$resumen$CV, 3))
)

kable(stats_completos, caption = "Tabla 6. Medidas estadísticas - Tiempo_Horas",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")
Tabla 6. Medidas estadísticas - Tiempo_Horas
Medida Valor
Media Aritmética (X̄) 2.007
Mediana (Me) 1.650
Moda (Mo) 0.800
Desviación Estándar (S) 1.072
Coef. de Variación (CV%) 53.416

Interpretación:

  • Media (X̄ = 2.007): En promedio, cada entrega tarda 2.007 horas. Es el valor central de todos los tiempos.
  • Mediana (Me = 1.65): La mitad de las entregas se hacen en menos de 1.65 horas. Al ser menor que la media, confirma la asimetría positiva.
  • Moda (Mo = 0.8): El tiempo de entrega que más se repite es de 0.8 horas, calculada por interpolación dentro del intervalo modal.
  • Desviación Estándar (S = 1.072): Los tiempos de entrega se desvían en promedio 1.072 horas respecto a la media. Un valor alto indica bastante variabilidad.
  • CV = 53.416%: La variabilidad es del 53.416% respecto a la media, lo que indica una dispersión moderada-alta en los tiempos.

Vector numero_paquetes

Pregunta 12: Cree en RStudio el vector denominado numero_paquetes.

numero_paquetes <- datos$Numero_Paquetes

Interpretación: Se creó el vector numero_paquetes con los datos de la columna Numero_Paquetes del dataset. Esta variable es cuantitativa discreta, ya que solo toma valores enteros (no puede haber 3.5 paquetes). Vamos a analizar su comportamiento estadístico en la siguiente pregunta.


Medidas estadísticas - Numero_Paquetes

Pregunta 13: Del vector denominado numero_paquetes y determine e interprete: Media aritmética, Mediana, Moda, Desviación estándar y el Coeficiente de variación.

media_paq <- mean(numero_paquetes)
mediana_paq <- median(numero_paquetes)
moda_paq <- as.numeric(names(which.max(table(numero_paquetes))))
de_paq <- sd(numero_paquetes)
cv_paq <- (de_paq / media_paq) * 100

stats_paq <- data.frame(
  Medida = c("Media Aritmética (X̄)", "Mediana (Me)", "Moda (Mo)",
             "Desviación Estándar (S)", "Coef. de Variación (CV%)"),
  Valor = c(round(media_paq, 3), round(mediana_paq, 3), moda_paq,
            round(de_paq, 3), round(cv_paq, 3))
)

kable(stats_paq, caption = "Tabla 7. Medidas estadísticas - Numero_Paquetes",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")
Tabla 7. Medidas estadísticas - Numero_Paquetes
Medida Valor
Media Aritmética (X̄) 4.833
Mediana (Me) 5.000
Moda (Mo) 5.000
Desviación Estándar (S) 1.913
Coef. de Variación (CV%) 39.587

Interpretación:

  • Media (X̄ = 4.833): En promedio, cada envío contiene 4.833 paquetes.
  • Mediana (Me = 5): La mitad de los envíos tienen 5 paquetes o menos.
  • Moda (Mo = moda_paq): El número de paquetes que más se repite es moda_paq (aparece 6 veces). Es el valor más frecuente.
  • Desviación Estándar (S = 1.913): Los paquetes por envío se desvían en promedio 1.913 unidades respecto a la media.
  • CV = 39.587%: La variabilidad es del 39.587% respecto a la media. Comparado con Tiempo_Horas, esta variable es mucho más estable.

Comparación de variabilidad

Pregunta 14: Compare los resultados obtenidos para ambas variables y explique cuál presenta mayor variabilidad.

comparacion <- data.frame(
  Medida = c("Media (X̄)", "Mediana (Me)", "Moda (Mo)", "Desv. Estándar (S)", "CV (%)"),
  Tiempo_Horas = c(round(mean(tiempo), 3), round(median(tiempo), 3),
                    round(resultado$resumen$Moda, 3), round(sd(tiempo), 3),
                    round(resultado$resumen$CV, 3)),
  Numero_Paquetes = c(round(media_paq, 3), round(mediana_paq, 3),
                      moda_paq, round(de_paq, 3), round(cv_paq, 3))
)

kable(comparacion, caption = "Tabla 8. Comparación de variabilidad entre variables",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white") %>%
  row_spec(5, bold = TRUE, background = "#FDEBD0") %>%
  column_spec(1, bold = TRUE)
Tabla 8. Comparación de variabilidad entre variables
Medida Tiempo_Horas Numero_Paquetes
Media (X̄) 2.007 4.833
Mediana (Me) 1.650 5.000
Moda (Mo) 0.800 5.000
Desv. Estándar (S) 1.072 1.913
CV (%) 53.416 39.587

Conclusión: La variable Tiempo_Horas tiene un CV de 53.416% y Numero_Paquetes un CV de 39.587%. Esto indica que los tiempos de entrega son más irregulares que la cantidad de paquetes por envío. Mientras que el número de paquetes se mantiene relativamente estable, los tiempos varían bastante debido a factores como el tráfico, la distancia y el tipo de mercancía.


Gráfico de barras - Estado_Entrega

Pregunta 15: Elabore un gráfico de barras para representar la distribución de las entregas según la variable Estado_Entrega.

ggplot(datos, aes(x = Estado_Entrega, fill = Estado_Entrega)) +
  geom_bar(width = 0.6, show.legend = FALSE) +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, fontface = "bold", size = 4) +
  scale_fill_manual(values = c("Anticipada" = "#27AE60", "A tiempo" = "#2980B9",
                                "Tarde" = "#E67E22", "Extraviada" = "#E74C3C")) +
  labs(title = "Distribución de Entregas según Estado",
       x = "Estado de Entrega", y = "Cantidad") +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))


Cumplimiento del objetivo de puntualidad

Pregunta 16: La empresa tiene como objetivo que el 99% de las entregas sean realizadas de manera anticipada o a tiempo. ¿Se cumple dicho objetivo? Sustente su respuesta mediante cálculos.

entregas_ok <- sum(datos$Estado_Entrega %in% c("Anticipada", "A tiempo"))
total <- nrow(datos)
porcentaje_ok <- (entregas_ok / total) * 100

tabla_objetivo <- data.frame(
  Concepto = c("Total de entregas", "Entregas a tiempo / anticipadas",
               "Porcentaje alcanzado", "Meta de la empresa", "¿Se cumple?"),
  Valor = c(total, entregas_ok, paste0(round(porcentaje_ok, 3), "%"),
            "99%", ifelse(porcentaje_ok >= 99, "SÍ", "NO"))
)

kable(tabla_objetivo, caption = "Tabla 10. Evaluación del objetivo de puntualidad",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white") %>%
  row_spec(5, bold = TRUE, background = ifelse(porcentaje_ok >= 99, "#D5F5E3", "#FADBD8"))
Tabla 10. Evaluación del objetivo de puntualidad
Concepto Valor
Total de entregas 30
Entregas a tiempo / anticipadas 19
Porcentaje alcanzado 63.333%
Meta de la empresa 99%
¿Se cumple? NO

Conclusión: De las 30 entregas, solo entregas_ok fueron anticipadas o a tiempo, lo que nos da un 63.333%. La empresa quería llegar al 99%, así que lamentablemente no se cumple la meta. Las total - entregas_ok entregas restantes (tardías y extraviadas) son las que impiden alcanzar el objetivo.


Análisis de entregas extraviadas

Pregunta 17: Analice la presencia de entregas extraviadas y determine si la empresa cumple su segundo objetivo de desempeño.

extraviadas <- sum(datos$Estado_Entrega == "Extraviada")
pct_extraviadas <- (extraviadas / total) * 100

tabla_extrav <- data.frame(
  Concepto = c("Total de entregas", "Entregas extraviadas",
               "Porcentaje de extravío", "Meta de la empresa", "¿Se cumple?"),
  Valor = c(total, extraviadas, paste0(round(pct_extraviadas, 3), "%"),
            "0%", "NO")
)

kable(tabla_extrav, caption = "Tabla 11. Evaluación de entregas extraviadas",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white") %>%
  row_spec(5, bold = TRUE, background = "#FADBD8")
Tabla 11. Evaluación de entregas extraviadas
Concepto Valor
Total de entregas 30
Entregas extraviadas 4
Porcentaje de extravío 13.333%
Meta de la empresa 0%
¿Se cumple? NO

Análisis: Se extraviaron extraviadas paquetes, que representan el 13.333% del total. La empresa tenía como objetivo que ningún paquete se perdiera (0%), y claramente no se cumplió. Extraviar un paquete no solo es un problema logístico, sino que también afecta directamente la confianza del cliente en el servicio.


Conclusión general

Pregunta 18: Redacte una conclusión general sobre el desempeño del servicio de reparto durante el mes evaluado.

Después de analizar todos los datos, queda claro que el servicio de reparto de Speedy Swift tuvo un desempeño por debajo de lo esperado durante el mes evaluado. El 63.333% de entregas oportunas no alcanza la meta del 99%. Además, el extravío de extraviadas paquetes va directo contra su segundo objetivo de cero extravíos. Los tiempos de entrega muestran una variabilidad considerable (CV = 53.416%), con una distribución asimétrica positiva que evidencia la presencia de entregas tardías que elevan el promedio. Las zonas con más problemas son aquellas donde se concentran las entregas tardías y extraviadas.


Propuestas de mejora

Pregunta 19: Proponga al menos dos acciones de mejora que permitan incrementar el porcentaje de entregas oportunas y reducir la pérdida de paquetes.

  1. Sistema de rastreo en tiempo real: Si cada paquete tuviera GPS y el cliente recibiera notificaciones automáticas, se podrían anticipar los retrasos y reducir considerablemente los extravíos. Muchas empresas de reparto ya usan esto y funciona muy bien.

  2. Revisar la asignación de repartidores por zona: Viendo los datos, hay zonas donde se acumulan más entregas tardías. Podría valer la pena aumentar repartidores en esas zonas o reorganizar las rutas para que sean más eficientes.

  3. Protocolos de verificación más estrictos: Implementar un sistema de doble verificación al momento de la entrega (código + firma) ayudaría a reducir errores y extravíos.


Análisis reproducible en R Markdown

Pregunta 20: Elabore un documento en R Markdown que genere una salida en formato HTML o Word, con encabezado YAML (título, autor y fecha), configure el chunk setup, incluya el análisis realizado y explique brevemente el concepto e importancia del análisis reproducible.

Este documento fue elaborado en R Markdown con las siguientes características:

  • Encabezado YAML: Título, autor y fecha de generación automática.
  • Chunk setup: Configurado con echo = TRUE, warning = FALSE y message = FALSE.
  • Función APDA: Implementada para el análisis de distribución por intervalos de la variable continua Tiempo_Horas, usando la fórmula de Sturges para el número de intervalos y cálculo de la moda por interpolación.

¿Qué es el análisis reproducible y por qué es importante?

El análisis reproducible significa que todo el proceso queda registrado: los datos, el código y las conclusiones. Cualquier persona podría repetir exactamente lo que se hizo y obtener los mismos resultados.

  • Transparencia: Cada paso está documentado y puede ser verificado.
  • Replicabilidad: Con correr el mismo código se obtienen los mismos resultados.
  • Eficiencia: No hay que copiar y pegar resultados manualmente.
  • Colaboración: Facilita el trabajo en equipo.

Anexo: Dataset completo

kable(datos, caption = "Anexo. Dataset completo de entregas - Speedy Swift",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE,
                position = "center") %>%
  row_spec(0, bold = TRUE, background = "#2C3E50", color = "white") %>%
  scroll_box(width = "100%")
Anexo. Dataset completo de entregas - Speedy Swift
ID Estado_Entrega Zona Tipo_Mercancia Numero_Paquetes Numero_Repartidores Tiempo_Horas Distancia_Km
1 A tiempo Norte Documentos 5 1 1.2 8.5
2 Anticipada Sur Electronicos 3 1 0.9 6.3
3 Tarde Centro Alimentos 7 2 2.8 15.4
4 Extraviada Este Documentos 2 1 3.5 10.2
5 A tiempo Oeste Ropa 6 2 1.7 12.1
6 Anticipada Norte Electronicos 4 1 1.0 7.8
7 Tarde Sur Alimentos 8 2 3.1 18.4
8 A tiempo Centro Ropa 5 1 1.5 9.6
9 Anticipada Este Documentos 3 1 0.8 5.9
10 Extraviada Oeste Electronicos 2 1 4.0 13.7
11 A tiempo Norte Alimentos 6 2 1.8 11.5
12 Anticipada Sur Ropa 4 1 1.1 8.1
13 Tarde Centro Documentos 7 2 2.9 16.8
14 A tiempo Este Electronicos 5 1 1.4 9.3
15 Anticipada Oeste Alimentos 3 1 0.9 6.8
16 Tarde Norte Ropa 8 2 3.3 17.6
17 A tiempo Sur Documentos 4 1 1.6 10.1
18 Extraviada Centro Electronicos 2 1 3.8 14.2
19 Anticipada Este Alimentos 5 1 1.0 7.4
20 A tiempo Oeste Ropa 6 2 1.9 12.8
21 Tarde Norte Documentos 7 2 2.7 15.9
22 Anticipada Sur Electronicos 3 1 0.8 5.7
23 A tiempo Centro Alimentos 5 1 1.5 9.8
24 Extraviada Este Ropa 2 1 4.2 13.9
25 Anticipada Oeste Documentos 4 1 1.1 7.2
26 A tiempo Norte Electronicos 6 2 1.7 11.7
27 Tarde Sur Alimentos 8 2 3.0 18.1
28 Anticipada Centro Ropa 3 1 0.9 6.4
29 A tiempo Este Documentos 5 1 1.3 8.9
30 Tarde Oeste Electronicos 7 2 2.8 16.2