Como parte del curso de Estadística / Métodos Cuantitativos del programa de Ingeniería Industrial, se nos propuso una situación problema relacionada con el consumo de combustible de un vehículo de carga. La idea del taller es aplicar el modelo de regresión lineal simple para describir la relación entre dos variables cuantitativas, estimar sus coeficientes “a mano” (siguiendo las fórmulas vistas en clase) y luego comprobar esos resultados usando el software estadístico R, a través de RStudio.
Este documento se elaboró con R Markdown, lo que nos
permitió combinar en un solo archivo el texto explicativo, las
ecuaciones, el código en R y los resultados/gráficos que dicho código
produce, generando al final un reporte en formato .html
autocontenido (no necesita ningún archivo externo para
visualizarse).
Una empresa de transporte de carga está interesada en entender cómo se comporta el consumo de combustible de sus camiones (medido en litros por cada 100 kg transportados, L/100kg) en función de la carga que llevan (medida en toneladas). Para ello se tomó una muestra de \(n = 26\) viajes, registrando en cada uno la carga transportada (\(X\)) y el consumo de combustible asociado (\(Y\)).
Se busca determinar si existe una relación lineal entre estas dos variables y, en caso de que así sea, estimar el modelo:
Ŷᵢ = β̂₀ + β̂₁ Xᵢ
donde:
Estimar los coeficientes de regresión (\(\hat{\beta}_0\) y \(\hat{\beta}_1\)) del modelo lineal simple que relaciona el consumo de combustible con la carga transportada, comparando el cálculo manual (fórmulas) con el cálculo hecho en R.
lm().El modelo de regresión lineal simple busca la recta que mejor se ajusta a una nube de puntos, minimizando la suma de los errores al cuadrado (método de mínimos cuadrados ordinarios). En Excel, estas fórmulas se armaron celda por celda: primero se calculó la desviación de cada \(X_i\) y \(Y_i\) respecto a su media, luego el producto cruzado de esas desviaciones y el cuadrado de la desviación de \(X\). La siguiente captura muestra exactamente las fórmulas que quedaron escritas en cada columna de la hoja de cálculo:
Con la suma de la columna de productos cruzados
(SUMA (xi-x_barra)(yi-y_barra)) y la suma de la columna de
cuadrados (SUMA (xi-x_barra)^2) se obtiene la pendiente
\(\hat{\beta}_1\) (dividiendo la
primera suma entre la segunda), y con esa pendiente y las medias \(\bar{X}\), \(\bar{Y}\) se obtiene el intercepto \(\hat{\beta}_0\).
Los datos corresponden a los 26 registros del taller (carga en toneladas y consumo en L/100kg), tal como se encontraban en el archivo de Excel entregado. A continuación se cargan en R:
# Vector de la variable independiente (X): carga transportada, en toneladas
carga <- c(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30)
# Vector de la variable dependiente (Y): consumo de combustible, en L/100kg
consumo <- c(21.8, 23.1, 24.4, 25.2, 26.6, 28.1, 28.7, 30.3, 31.2, 32.8,
33.4, 35.1, 35.8, 37.5, 38.0, 39.6, 40.9, 41.7, 43.0, 44.3,
45.1, 46.8, 47.4, 49.2, 50.0, 51.6)
# Se guardan los datos en un data.frame, que es la forma "ordenada"
# de trabajar datos en R
datos <- data.frame(obs = 1:length(carga), carga, consumo)
# Vemos las primeras filas para revisar que todo haya quedado bien
head(datos)## carga consumo
## Min. : 5.00 Min. :21.80
## 1st Qu.:11.25 1st Qu.:29.10
## Median :17.50 Median :36.65
## Mean :17.50 Mean :36.60
## 3rd Qu.:23.75 3rd Qu.:43.98
## Max. :30.00 Max. :51.60
Antes de ajustar cualquier modelo, siempre es buena práctica visualizar los datos para ver si tiene sentido pensar en una relación lineal.
library(ggplot2)
ggplot(datos, aes(x = carga, y = consumo)) +
geom_point(color = "#2C3E50", size = 2.5) +
labs(title = "Consumo de combustible vs. Carga transportada",
x = "Carga (toneladas)",
y = "Consumo (L/100kg)") +
theme_minimal(base_size = 13)Como se observa en el gráfico, los puntos siguen un patrón bastante lineal y creciente: a mayor carga transportada, mayor es el consumo de combustible. Esto nos da un primer indicio de que un modelo de regresión lineal simple es una buena opción para describir estos datos.
Antes de usar R, replicamos el procedimiento que se realizó en Excel para entender bien de dónde salen los números. Para esto se calculan las desviaciones de cada variable respecto a su media, sus productos cruzados y sus cuadrados.
n <- length(carga)
X_barra <- mean(carga)
Y_barra <- mean(consumo)
# Desviaciones respecto a la media
dev_x <- carga - X_barra
dev_y <- consumo - Y_barra
# Productos cruzados y cuadrados (igual que las columnas del Excel)
prod_cruzado <- dev_x * dev_y
dev_x2 <- dev_x^2
SCxy <- sum(prod_cruzado) # SUMA (Xi - Xbarra)(Yi - Ybarra)
SCxx <- sum(dev_x2) # SUMA (Xi - Xbarra)^2
# Estimación de los coeficientes con las fórmulas de mínimos cuadrados
beta1_manual <- SCxy / SCxx
beta0_manual <- Y_barra - beta1_manual * X_barra
data.frame(
X_barra, Y_barra, SCxy, SCxx,
Beta1_estimado = round(beta1_manual, 4),
Beta0_estimado = round(beta0_manual, 4)
)Con esto obtenemos manualmente en R los mismos resultados que ya habíamos calculado en Excel. A continuación se muestra la captura de pantalla de la hoja de cálculo original, con la tabla completa de los 26 datos, las sumas y el resultado final de \(\hat{\beta}_0\) y \(\hat{\beta}_1\):
Como se observa en la parte inferior de la hoja, en Excel se obtuvo:
Estos valores coinciden con los que calculamos manualmente en R, lo
cual es una buena señal antes de pasar a la función
lm().
En R, ajustar un modelo de regresión lineal simple es mucho más
directo gracias a la función lm() (linear model).
Esta función recibe una fórmula del tipo Y ~ X (que se lee
“Y en función de X”) y el data.frame donde están los datos.
modelo <- lm(consumo ~ carga, data = datos)
# Mostramos únicamente los coeficientes estimados
coef(modelo)## (Intercept) carga
## 16.020 1.176
##
## Call:
## lm(formula = consumo ~ carga, data = datos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.372 -0.207 0.010 0.199 0.320
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 16.020000 0.117534 136.3 <2e-16 ***
## carga 1.176000 0.006173 190.5 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2361 on 24 degrees of freedom
## Multiple R-squared: 0.9993, Adjusted R-squared: 0.9993
## F-statistic: 3.629e+04 on 1 and 24 DF, p-value: < 2.2e-16
El resumen de summary() nos entrega, entre otras
cosas:
comparacion <- data.frame(
Coeficiente = c("Beta0 (Intercepto)", "Beta1 (Pendiente)"),
Manual = c(round(beta0_manual, 4), round(beta1_manual, 4)),
R_lm = c(round(coef(modelo)[1], 4), round(coef(modelo)[2], 4))
)
comparacionComo se esperaba, los coeficientes calculados manualmente y los que entrega R son prácticamente iguales (las pequeñas diferencias, si las hay, se deben solo al redondeo). Esto nos da confianza de que tanto el procedimiento manual como el código en R están bien planteados.
De acuerdo con los resultados anteriores (los mismos que arroja la hoja de Excel), el modelo de regresión lineal simple ajustado queda con \(\hat{\beta}_0 = 16.02\) y \(\hat{\beta}_1 = 1.176\):
Es decir:
Consumo estimado (L/100kg) = 16.02 + 1.176 × Carga (toneladas)
ggplot(datos, aes(x = carga, y = consumo)) +
geom_point(color = "#2C3E50", size = 2.5) +
geom_smooth(method = "lm", se = TRUE, color = "#E74C3C", fill = "#F1948A") +
labs(title = "Modelo de regresión lineal ajustado",
subtitle = expression(hat(Y) == 16.02 + 1.176~X),
x = "Carga (toneladas)",
y = "Consumo (L/100kg)") +
theme_minimal(base_size = 13)La línea roja corresponde al modelo ajustado y la banda sombreada es el intervalo de confianza del 95% para la recta de regresión. Se observa que los puntos están muy cerca de la línea, lo que confirma visualmente el buen ajuste que ya habíamos visto en el \(R^2\).
El modelo muestra que por cada tonelada adicional de carga, el consumo de combustible aumenta en promedio 1,176L por cada 100 km. El intercepto de 16,02 representa el consumo estimado sin carga. Así, el modelo permite estimar el consumo según la carga transportada.
Por trazabilidad y buenas prácticas, se incluye la información de la sesión de R utilizada para generar este informe.
## R version 4.5.1 (2025-06-13 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=Spanish_United States.utf8
## [2] LC_CTYPE=Spanish_United States.utf8
## [3] LC_MONETARY=Spanish_United States.utf8
## [4] LC_NUMERIC=C
## [5] LC_TIME=Spanish_United States.utf8
##
## time zone: America/Bogota
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] ggplot2_4.0.3
##
## loaded via a namespace (and not attached):
## [1] vctrs_0.7.3 nlme_3.1-168 cli_3.6.6 knitr_1.51
## [5] rlang_1.3.0 xfun_0.60 S7_0.2.2 jsonlite_2.0.0
## [9] glue_1.8.1 labeling_0.4.3 htmltools_0.5.9 sass_0.4.10
## [13] scales_1.4.0 rmarkdown_2.31 grid_4.5.1 evaluate_1.0.5
## [17] jquerylib_0.1.4 fastmap_1.2.0 yaml_2.3.12 lifecycle_1.0.5
## [21] compiler_4.5.1 RColorBrewer_1.1-3 mgcv_1.9-3 lattice_0.22-7
## [25] farver_2.1.2 digest_0.6.39 R6_2.6.1 splines_4.5.1
## [29] Matrix_1.7-3 bslib_0.11.0 tools_4.5.1 withr_3.0.3
## [33] gtable_0.3.6 cachem_1.1.0