Variable Cualitativa Ordinal-Puntuación_GHG

La variable GHG Score representa una calificación del nivel de emisiones de gases de efecto invernadero de los vehículos, en una escala del 0 al 10. Un mayor puntaje indica menos emisiones contaminantes. Por tratarse de valores numéricos enteros con un orden natural, se exploraron modelos probabilísticos como la binomial y la Poisson para analizar su comportamiento.

1 Cargar datos

setwd("C:/Users/Usuario/Documents/Trabajo Estadistica/PROYECTO/")
datos <- read.csv("database.csv", header = TRUE, sep = ",", dec = ".")

Verificamos que rstudio nos lea correctamente los datos:

str(datos)
## 'data.frame':    38113 obs. of  81 variables:
##  $ Vehicle.ID                         : int  26587 27705 26561 27681 27550 28426 27549 28425 27593 28455 ...
##  $ Year                               : int  1984 1984 1984 1984 1984 1984 1984 1984 1984 1984 ...
##  $ Make                               : chr  "Alfa Romeo" "Alfa Romeo" "Alfa Romeo" "Alfa Romeo" ...
##  $ Model                              : chr  "GT V6 2.5" "GT V6 2.5" "Spider Veloce 2000" "Spider Veloce 2000" ...
##  $ Class                              : chr  "Minicompact Cars" "Minicompact Cars" "Two Seaters" "Two Seaters" ...
##  $ Drive                              : chr  "" "" "" "" ...
##  $ Transmission                       : chr  "Manual 5-Speed" "Manual 5-Speed" "Manual 5-Speed" "Manual 5-Speed" ...
##  $ Transmission.Descriptor            : chr  "" "" "" "" ...
##  $ Engine.Index                       : int  9001 9005 9002 9006 1830 1880 1831 1881 1524 1574 ...
##  $ Engine.Descriptor                  : chr  "(FFS)" "(FFS) CA model" "(FFS)" "(FFS) CA model" ...
##  $ Engine.Cylinders                   : int  6 6 4 4 4 4 6 6 6 6 ...
##  $ Engine.Displacement                : num  2.5 2.5 2 2 2.5 2.5 4.2 4.2 4.2 4.2 ...
##  $ Turbocharger                       : logi  NA NA NA NA NA NA ...
##  $ Supercharger                       : chr  "" "" "" "" ...
##  $ Fuel.Type                          : chr  "Regular" "Regular" "Regular" "Regular" ...
##  $ Fuel.Type.1                        : chr  "Regular Gasoline" "Regular Gasoline" "Regular Gasoline" "Regular Gasoline" ...
##  $ Fuel.Type.2                        : chr  "" "" "" "" ...
##  $ City.MPG..FT1.                     : int  17 17 18 18 18 18 13 13 15 15 ...
##  $ Unrounded.City.MPG..FT1.           : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ City.MPG..FT2.                     : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Unrounded.City.MPG..FT2.           : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ City.Gasoline.Consumption..CD.     : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ City.Electricity.Consumption       : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ City.Utility.Factor                : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Highway.MPG..FT1.                  : int  24 24 25 25 17 17 13 13 20 19 ...
##  $ Unrounded.Highway.MPG..FT1.        : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Highway.MPG..FT2.                  : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Unrounded.Highway.MPG..FT2.        : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Highway.Gasoline.Consumption..CD.  : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Highway.Electricity.Consumption    : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Highway.Utility.Factor             : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Unadjusted.City.MPG..FT1.          : num  21 21 23 23 22 22 16 16 19 19 ...
##  $ Unadjusted.Highway.MPG..FT1.       : num  34 34 35 35 24 24 18 18 27 26 ...
##  $ Unadjusted.City.MPG..FT2.          : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Unadjusted.Highway.MPG..FT2.       : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Combined.MPG..FT1.                 : int  20 20 21 21 17 17 13 13 17 17 ...
##  $ Unrounded.Combined.MPG..FT1.       : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Combined.MPG..FT2.                 : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Unrounded.Combined.MPG..FT2.       : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Combined.Electricity.Consumption   : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Combined.Gasoline.Consumption..CD. : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Combined.Utility.Factor            : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Annual.Fuel.Cost..FT1.             : int  1750 1750 1650 1650 2050 2050 2700 2700 2050 2050 ...
##  $ Annual.Fuel.Cost..FT2.             : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Gas.Guzzler.Tax                    : chr  "" "" "" "" ...
##  $ Save.or.Spend..5.Year.             : int  -2000 -2000 -1500 -1500 -3500 -3500 -6750 -6750 -3500 -3500 ...
##  $ Annual.Consumption.in.Barrels..FT1.: num  16.5 16.5 15.7 15.7 19.4 ...
##  $ Annual.Consumption.in.Barrels..FT2.: num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Tailpipe.CO2..FT1.                 : int  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
##  $ Tailpipe.CO2.in.Grams.Mile..FT1.   : num  444 444 423 423 523 ...
##  $ Tailpipe.CO2..FT2.                 : int  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
##  $ Tailpipe.CO2.in.Grams.Mile..FT2.   : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Fuel.Economy.Score                 : int  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
##  $ GHG.Score                          : int  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
##  $ GHG.Score..Alt.Fuel.               : int  -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
##  $ My.MPG.Data                        : chr  "N" "N" "N" "N" ...
##  $ X2D.Passenger.Volume               : int  74 74 0 0 0 0 0 0 0 0 ...
##  $ X2D.Luggage.Volume                 : int  7 7 0 0 0 0 0 0 0 0 ...
##  $ X4D.Passenger.Volume               : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ X4D.Luggage.Volume                 : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Hatchback.Passenger.Volume         : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Hatchback.Luggage.Volume           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Start.Stop.Technology              : chr  "" "" "" "" ...
##  $ Alternative.Fuel.Technology        : chr  "" "" "" "" ...
##  $ Electric.Motor                     : chr  "" "" "" "" ...
##  $ Manufacturer.Code                  : chr  "" "" "" "" ...
##  $ Gasoline.Electricity.Blended..CD.  : chr  "False" "False" "False" "False" ...
##  $ Vehicle.Charger                    : chr  "" "" "" "" ...
##  $ Alternate.Charger                  : chr  "" "" "" "" ...
##  $ Hours.to.Charge..120V.             : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Hours.to.Charge..240V.             : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Hours.to.Charge..AC.240V.          : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Composite.City.MPG                 : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Composite.Highway.MPG              : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Composite.Combined.MPG             : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Range..FT1.                        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ City.Range..FT1.                   : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Highway.Range..FT1.                : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Range..FT2.                        : chr  "" "" "" "" ...
##  $ City.Range..FT2.                   : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Highway.Range..FT2.                : num  0 0 0 0 0 0 0 0 0 0 ...

1.1 Cargar librerias

library(knitr)
## Warning: package 'knitr' was built under R version 4.4.3
library(kableExtra)
## Warning: package 'kableExtra' was built under R version 4.4.3

1.2 Extraemos la variable

# Extraer y limpiar la variable
Puntuacion <- datos$GHG.Score
Puntuacion <- Puntuacion[!is.na(Puntuacion) & Puntuacion != -1 & Puntuacion != ""]

2 Tabla de Distribución De Frecuencias

TDFpuntuacion <- table(Puntuacion)
Tabla <- as.data.frame(TDFpuntuacion)
colnames(Tabla) <- c("Puntaje", "Frecuencia Absoluta (ni)")
Tabla$`Frecuencia Relativa (%)` <- round(
  Tabla$`Frecuencia Absoluta (ni)` / sum(Tabla$`Frecuencia Absoluta (ni)`) * 100,
  2
)
# Convertir puntaje a carácter
Tabla$Puntaje <- as.character(Tabla$Puntaje)

2.1 Crear fila de totales

# Agregar fila de totales
fila_total <- data.frame(
  Puntaje = "Total",
  `Frecuencia Absoluta (ni)` = sum(Tabla$`Frecuencia Absoluta (ni)`),
  `Frecuencia Relativa (%)` = round(sum(Tabla$`Frecuencia Relativa (%)`), 2),
  check.names = FALSE
)
Tabla <- rbind(Tabla, fila_total)

2.2 Unir fila total a la tabla

kable(Tabla, format = "html", caption = "Tabla Nº1: Distribución de Frecuencia del GHG Score") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  column_spec(1, bold = TRUE)
Tabla Nº1: Distribución de Frecuencia del GHG Score
Puntaje Frecuencia Absoluta (ni) Frecuencia Relativa (%)
1 129 2.11
2 294 4.80
3 513 8.38
4 1151 18.81
5 1558 25.46
6 953 15.57
7 815 13.32
8 435 7.11
9 97 1.58
10 175 2.86
Total 6120 100.00

3 Gráficas de distribución de frecuencia

# Ajustar márgenes para etiquetas largas
par(mar = c(8, 4, 3, 2))

# Gráfico de barras - Frecuencia Absoluta
barplot(
  height = Tabla$`Frecuencia Absoluta (ni)`[-nrow(Tabla)],
  names.arg = Tabla$Puntaje[-nrow(Tabla)],
  main = "Gráfica Nº1: Distribución del GHG Score",
  xlab = "Puntuación",
  ylab = "Frecuencia Absoluta",
  col = "lightsteelblue",
  las = 3,
  cex.names = 0.8,
  cex.axis = 0.9,
  cex.main = 1.2,
  border = "black"
)

4 Conjetura del modelo

Se asumió que el GHG Score podría seguir una distribución binomial, considerando que sus valores van de 1 a 10. Se estimó la probabilidad p como el promedio relativo (mean / n), y con eso se calcularon las frecuencias esperadas bajo ese modelo. Esto se hizo para ver si los puntajes de eficiencia ambiental se distribuyen como en una serie de ensayos con éxito/fracaso.

4.1 Modelo Binomial

ghg <- as.numeric(Puntuacion)
Fo <- table(ghg)
Fo_df <- as.data.frame(Fo)
colnames(Fo_df) <- c("X", "ni")
Fo_df$X <- as.numeric(as.character(Fo_df$X))

4.1.1 Test de Pearson

Mide el grado de correlación entre la frecuencia observada y la frecuencia esperada.

n_bin <- 10
p_bin <- mean(ghg) / n_bin
p_bin
## [1] 0.5257516
Fo_df$esperados <- dbinom(Fo_df$X, size = n_bin, prob = p_bin) * sum(Fo_df$ni)
Fo_df$esperados
##  [1]   39.046728  194.792371  575.858079 1117.193244 1486.224221 1373.023203
##  [7]  869.790411  361.593547   89.080561    9.875469
barplot(
  rbind(Fo_df$ni, Fo_df$esperados),
  beside = TRUE,
  col = c("darkblue", "tomato"),
  legend = c("Observada", "Esperada"),
  names.arg = Fo_df$X,
  main = "Gráfica Nº2: 
  Distribución Binomial Ajustada al GHG Score",
  xlab = "Puntuación",
  ylab = "Frecuencia",
  ylim = c(0, max(c(Fo_df$ni, Fo_df$esperados)) * 1.2)
)

correlacion_bin <- cor(Fo_df$ni, Fo_df$esperados)
cat("Correlación Observado vs Esperado (Binomial):", round(correlacion_bin, 3), "\n")
## Correlación Observado vs Esperado (Binomial): 0.961
# Gráfico de correlación - Binomial
plot(Fo_df$esperados, Fo_df$ni,
     main = "Gráfica Nº3:
     Correlación Binomial: Frecuencia Teórica vs Experimental",
     xlab = "Teórica (Binomial)",
     ylab = "Experimental",
     pch = 19, col = "blue")
abline(lm(ni ~ esperados, data = Fo_df), col = "red", lwd = 2)
text(x = min(Fo_df$esperados), y = max(Fo_df$ni),
     labels = paste("r =", round(correlacion_bin, 3)),
     pos = 4, col = "darkblue", cex = 0.9)

Se compararon las frecuencias observadas y las esperadas con un gráfico de barras y uno de dispersión. La correlación fue moderada (r ≈ 0.961), lo que indica cierta relación. Se hizo esto para cuantificar visual y numéricamente qué tan bien representa el modelo binomial los datos reales.

4.1.2 Chi-cuadrado

El test de Chi-Cuadrado utiliza dos parámetros: grados de libertad (se refiere al número de valores libres de variar dentro de intervalos de la variable, (k-1), y nivel de significancia. Para validar el modelo, se compara el valor de chi-cuadrado calculado con el umbral de aceptación de chi-cuadrado correspondiente a los grados de libertad y el nivel de significancia deseado.

Si el valor de chi-cuadrado calculado es mayor que el umbral de aceptación, se rechaza el modelo, indicando que hay una diferencia significativa.

x2_bin <- sum(((Fo_df$ni - Fo_df$esperados)^2) / Fo_df$esperados)
gl_bin <- length(Fo_df$X) - 1
vc_bin <- qchisq(0.95, df = gl_bin)

cat("Chi-cuadrado Binomial:", round(x2_bin, 3), "\n")
## Chi-cuadrado Binomial: 3177.647
cat("Valor crítico (0.95):", round(vc_bin, 3), "\n")
## Valor crítico (0.95): 16.919
if (x2_bin < vc_bin) {
  cat("No se rechaza H0: El modelo binomial se ajusta bien a los datos.\n")
} else {
  cat("Se rechaza H0: El modelo binomial no se ajusta a los datos.\n")
}
## Se rechaza H0: El modelo binomial no se ajusta a los datos.

Al aplicar la prueba de chi-cuadrado para contrastar si la distribución observada difiere significativamente de la esperada bajo el modelo binomial. El resultado fue un valor de chi-cuadrado ≈ 3177.647, muy superior al valor crítico (≈ 16.919), lo que indica que el modelo binomial no se ajusta bien a los datos.

4.2 Modelo Poisson

lambda <- mean(ghg)
lambda
## [1] 5.257516
Fo_df$esperados <- dpois(Fo_df$X, lambda) * sum(Fo_df$ni)
Fo_df$esperados
##  [1]  167.5798  440.5268  772.0257 1014.7344 1066.9965  934.9586  702.2229
##  [8]  461.4935  269.5900  141.7374

4.2.1 Test de Pearson

Fo_df$esperados <- dpois(Fo_df$X, lambda) * sum(Fo_df$ni)
Fo_df$esperados
##  [1]  167.5798  440.5268  772.0257 1014.7344 1066.9965  934.9586  702.2229
##  [8]  461.4935  269.5900  141.7374
barplot(
  rbind(Fo_df$ni, Fo_df$esperados),
  beside = TRUE,
  col = c("darkgreen", "orange"),
  legend = c("Observada", "Esperada"),
  names.arg = Fo_df$X,
  main = "Gráfica Nº4:
  Distribución Poisson Ajustada al GHG Score",
  xlab = "Puntuación",
  ylab = "Frecuencia",
  ylim = c(0, max(c(Fo_df$ni, Fo_df$esperados)) * 1.2)
)

correlacion_pois <- cor(Fo_df$ni, Fo_df$esperados)
cat("Correlación Observado vs Esperado (Poisson):", round(correlacion_pois, 3), "\n")
## Correlación Observado vs Esperado (Poisson): 0.933
# Gráfico de correlación - Poisson
plot(Fo_df$esperados, Fo_df$ni,
     main = "Gráfica Nº5:
     Correlación Poisson: Frecuencia Teórica vs Experimental",
     xlab = "Teórica (Poisson)",
     ylab = "Experimental",
     pch = 19, col = "darkgreen")
abline(lm(ni ~ esperados, data = Fo_df), col = "red", lwd = 2)
text(x = min(Fo_df$esperados), y = max(Fo_df$ni),
     labels = paste("r =", round(correlacion_pois, 3)),
     pos = 4, col = "darkgreen", cex = 0.9)

La correlación no mejoró a ≈ 0.933, lo que indica un ajuste algo más cercano. Sin embargo, no es suficiente por sí solo para validar el modelo.

4.2.2 Chi-cuadrado

x2_pois <- sum(((Fo_df$ni - Fo_df$esperados)^2) / Fo_df$esperados)
gl_pois <- length(Fo_df$X) - 1
vc_pois <- qchisq(0.95, df = gl_pois)

cat("Chi-cuadrado Poisson:", round(x2_pois, 3), "\n")
## Chi-cuadrado Poisson: 527.05
cat("Valor crítico (0.95):", round(vc_pois, 3), "\n")
## Valor crítico (0.95): 16.919
if (x2_pois < vc_pois) {
  cat("No se rechaza H0: El modelo Poisson se ajusta bien a los datos.\n")
} else {
  cat("Se rechaza H0: El modelo Poisson no se ajusta a los datos.\n")
}
## Se rechaza H0: El modelo Poisson no se ajusta a los datos.

El estadístico de chi-cuadrado volvió a ser muy alto (≈ 527.05), y el valor crítico también (≈ 16.919). Aun así, el resultado muestra que el modelo de Poisson tampoco se ajusta bien.

5 Agrupación 1

Dado que los modelos no ajustaban bien al trabajar con cada valor individual (muchos valores con frecuencia baja o dispersa), se agruparon los valores del GHG Score en rangos: 1–2, 3–4, 5–6, 7–8 y 9–10. Esto se hizo para reducir la dispersión y estabilizar las frecuencias esperadas, facilitando el uso del chi-cuadrado.

Fo_df$grupo <- cut(Fo_df$X,
                   breaks = c(0, 2, 4, 6, 8, 10),
                   labels = c("1-2", "3-4", "5-6", "7-8", "9-10"),
                   include.lowest = TRUE, right = TRUE)
Fo_df_agregado <- aggregate(cbind(ni, esperados) ~ grupo, data = Fo_df, sum)
barplot(
  height = rbind(Fo_df_agregado$ni, Fo_df_agregado$esperados),
  beside = TRUE,
  col = c("steelblue", "salmon"),
  names.arg = Fo_df_agregado$grupo,
  legend = c("Observada", "Esperada"),
  main = "Gráfica Nº6:
  Frecuencias Observadas vs Esperadas por Grupo (GHG Score)",
  xlab = "Grupo de Puntuación",
  ylab = "Frecuencia",
  ylim = c(0, max(c(Fo_df_agregado$ni, Fo_df_agregado$esperados)) * 1.2),
  args.legend = list(x = "topright", bty = "n")
)

cor_grupo <- cor(Fo_df_agregado$ni, Fo_df_agregado$esperados)
cat("Correlación Observado vs Esperado (agrupado):", round(cor_grupo, 3), "\n")
## Correlación Observado vs Esperado (agrupado): 0.974
# Gráfico de dispersión Observado vs Esperado (agrupado)
plot(Fo_df_agregado$esperados, Fo_df_agregado$ni,
     pch = 19, col = "darkblue",
     xlab = "Frecuencia Esperada (agrupada)",
     ylab = "Frecuencia Observada (agrupada)",
     main = "Gráfica Nº7:
     Correlación Observado vs Esperado (Grupos)")
abline(lm(ni ~ esperados, data = Fo_df_agregado), col = "red", lwd = 2)
text(x = min(Fo_df_agregado$esperados), y = max(Fo_df_agregado$ni),
     labels = paste("r =", round(cor_grupo, 3)),
     pos = 4, col = "darkblue", cex = 0.9)

5.1 Chi-Cuadrado

x2_grupo <- sum((Fo_df_agregado$ni - Fo_df_agregado$esperados)^2 / Fo_df_agregado$esperados)
gl_grupo <- nrow(Fo_df_agregado) - 1
vc_grupo <- qchisq(0.95, df = gl_grupo)
cat("Chi-cuadrado (agrupado):", round(x2_grupo, 3), "\n")
## Chi-cuadrado (agrupado): 247.809
cat("Valor crítico (0.95):", round(vc_grupo, 3), "\n")
## Valor crítico (0.95): 9.488
if (x2_grupo < vc_grupo) {
  cat("No se rechaza H0: El modelo se ajusta bien a los datos agrupados.\n")
} else {
  cat("Se rechaza H0: El modelo no se ajusta incluso agrupando.\n")
}
## Se rechaza H0: El modelo no se ajusta incluso agrupando.

Al aplicar la prueba de chi-cuadrado con los datos agrupados. Aunque el estadístico fue menor (≈ 247.809), aún fue mucho mayor que el valor crítico para 4 grados de libertad (≈ 9.488), por lo que incluso agrupando, el modelo no se ajusta bien. Sin embargo, la mejora en la correlación sugiere que el agrupamiento fue un paso útil para suavizar los datos.

6 Conclusión

Se analizó el GHG Score en Ann Arbor, Michigan, utilizando modelos binomial y Poisson. Aunque el modelo de Poisson presentó mejor ajuste general (r = 0.933, λ = 5.26), ambos modelos fueron rechazados mediante la prueba chi-cuadrado. Posteriormente, se agruparon las puntuaciones en intervalos, lo que mejoró la correlación a r = 0.974, aunque el modelo continuó sin ajustarse completamente a los datos.