Este tutorial cubre los fundamentos de la Regresión Lineal Simple (RLS), una técnica esencial para modelar y predecir la relación entre dos variables cuantitativas. Seguiremos los objetivos de aprendizaje de la asignatura de Bioestadística para estudiantes de medicina de la Universidad Dr. José Matías Delgado.
Objetivos de Aprendizaje:
Explicar cómo se utiliza una variable cuantitativa explicativa (\(X\)) para predecir el valor de una variable de respuesta (\(Y\)).
Formular la ecuación de la línea de regresión.
Comprender que la regresión evalúa asociación, pero no implica causalidad.
La regresión lineal simple (RLS) nos permite predecir el valor de una variable de respuesta (dependiente, \(Y\)) basándonos en el valor de una variable explicativa (independiente, \(X\)).
Buscamos encontrar la línea recta que “mejor” se ajuste a la nube de puntos en un diagrama de dispersión.
El modelo poblacional (teórico) se escribe:
\[Y = \beta_0 + \beta_1X + \epsilon\]
Donde:
\(Y\): Variable de respuesta.
\(X\): Variable explicativa.
\(\beta_0\) (Beta-cero): El intercepto poblacional (valor esperado de \(Y\) cuando \(X=0\)).
\(\beta_1\) (Beta-uno): La pendiente poblacional (cambio promedio en \(Y\) por cada aumento de 1 unidad en \(X\)).
\(\epsilon\) (Épsilon): El error aleatorio.
Como no podemos conocer los \(\beta\) poblacionales, los estimamos a partir de la muestra. La ecuación estimada es:
\[\hat{y} = b_0 + b_1x\]
Donde:
\(\hat{y}\) (“y-sombrero”): El valor predicho de \(Y\) para un valor dado de \(x\).
\(b_0\): La estimación muestral del intercepto.
\(b_1\): La estimación muestral de la pendiente.
El residuo (\(e_i\)) es la diferencia entre el valor real observado (\(y_i\)) y el valor predicho (\(\hat{y}_i\)). Es el error de nuestra predicción para cada punto.
La “mejor” línea es aquella que minimiza los errores de predicción. El método de mínimos cuadrados ordinarios (MCO) encuentra la línea que minimiza la suma de los residuos al cuadrado (\(\sum e_i^2\)).
Las fórmulas para los estimadores \(b_1\) y \(b_0\) son:
Cálculo de la Pendiente (\(b_1\)): \[b_1 = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})}{\sum (x_i - \bar{x})^2}\] Alternativa (usando correlación \(R\)): \(b_1 = R \left( \frac{s_y}{s_x} \right)\)
Cálculo del Intercepto (\(b_0\)): La línea siempre pasa por el punto de las medias \((\bar{x}, \bar{y})\): \[b_0 = \bar{y} - b_1\bar{x}\]
Un cardiólogo quiere predecir la Presión Arterial Sistólica (PAS) (\(Y\)) de sus pacientes en función de su Índice de Masa Corporal (IMC) (\(X\)).
Simulamos los datos, visualizamos la relación y corremos el modelo
con la función lm() (linear model).
# 0. Simular datos para el ejemplo
set.seed(123) # Para reproducibilidad
N <- 50
imc <- rnorm(N, mean = 28, sd = 4)
# Suponemos una relación: PAS = 80 + 1.8*IMC + error
pas <- 80 + 1.8 * imc + rnorm(N, mean = 0, sd = 8)
datos_clinicos <- data.frame(imc, pas)
# 1. Visualizar la relación
plot(datos_clinicos$imc, datos_clinicos$pas,
main = "Diagrama de Dispersión: IMC vs. PAS",
xlab = "Índice de Masa Corporal (IMC)",
ylab = "Presión Arterial Sistólica (PAS)",
pch = 19, col = "blue")
# 2. Correr el modelo de Regresión Lineal Simple (Y ~ X)
modelo_pas_imc <- lm(pas ~ imc, data = datos_clinicos)
# 3. Añadir la línea de regresión al gráfico
abline(modelo_pas_imc, col = "red", lwd = 2)
Diagrama de dispersión de PAS vs. IMC con línea de regresión.
Usamos la función summary() para ver los resultados
detallados del modelo.
# 4. Ver los resultados del modelo
summary(modelo_pas_imc)
##
## Call:
## lm(formula = pas ~ imc, data = datos_clinicos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -19.7154 -3.8898 -0.2164 3.9524 16.2047
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 83.1453 8.0055 10.386 7.22e-14 ***
## imc 1.7298 0.2821 6.131 1.58e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.314 on 48 degrees of freedom
## Multiple R-squared: 0.4392, Adjusted R-squared: 0.4275
## F-statistic: 37.59 on 1 and 48 DF, p-value: 1.579e-07
Basado en la salida Coefficients:
El \(R^2\) (o
Multiple R-squared) nos dice qué porcentaje de la
variabilidad total en la variable de respuesta (\(Y\)) es explicado por el modelo lineal (es
decir, por la variable \(X\)).
Queremos saber si la relación que observamos es “real” (estadísticamente significativa) o pudo ocurrir solo por azar. Para ello, hacemos una prueba de hipótesis sobre la pendiente \(\beta_1\):
Volvemos a ver los resultados del
summary(modelo_pas_imc) del módulo anterior:
Multiple R-squared: 0.581.Pr(>|t|)) para el coeficiente
imc.1.91e-10 (o \(1.91 \times 10^{-10}\)), que es un número
extremadamente pequeño (casi cero).Para que nuestras inferencias (p-valores e intervalos de confianza) sean válidas, el modelo debe cumplir 4 supuestos que evaluamos analizando los residuos:
R nos da 4 gráficos de diagnóstico automáticamente al aplicar
plot() a un objeto lm. Usamos
par(mfrow = c(2, 2)) para ponerlos todos en una cuadrícula
de 2x2.
# Configura R para mostrar 4 gráficos en una cuadrícula (2x2)
par(mfrow = c(2, 2))
# Genera los gráficos de diagnóstico
plot(modelo_pas_imc)
Gráficos de diagnóstico para el modelo IMC/PAS.
# Restaura la configuración gráfica a 1x1
par(mfrow = c(1, 1))
La extrapolación es usar el modelo para predecir valores de \(Y\) para valores de \(X\) que están fuera del rango de los datos originales con los que se construyó el modelo.
Estos son puntos que merecen atención especial, ya que pueden distorsionar los resultados de la regresión:
Outlier (Valor Atípico): Es una observación con un residuo grande. Es un punto que está lejos de la línea de regresión (verticalmente). El modelo hizo una mala predicción para ese punto.
Punto de Apalancamiento (Leverage): Es una observación con un valor de \(X\) extremo (lejos de la media \(\bar{x}\)). Este punto tiene el potencial de “jalar” o influir mucho en la línea de regresión, esté o no alineado con la tendencia.
Punto Influyente: Es un punto que, si se elimina, cambia significativamente la línea de regresión (la pendiente \(b_1\) o el intercepto \(b_0\)). Un punto suele ser influyente si es a la vez un outlier y tiene alto apalancamiento.
(El gráfico “Residuals vs Leverage” del Módulo 5 está diseñado específicamente para ayudar a identificar estos puntos).
La Regresión Lineal Simple también funciona si la variable explicativa \(X\) es categórica dicotómica (ej. “Tratamiento” vs “Placebo”, “Fumador” vs “No Fumador”).
Para usarla en el modelo matemático, R crea automáticamente una variable indicadora (dummy). A una categoría la llama “Nivel de Referencia” (codificada como 0) y a la otra le asigna el valor 1.
Un investigador estudia el efecto de un nuevo fármaco para la diabetes. Mide el Nivel de HbA1c (Hemoglobina Glicosilada) (\(Y\)) en dos grupos:
Si R elige “Placebo” como la referencia, la codificación interna es:
\(X = 0\): Grupo Placebo
\(X = 1\): Grupo Fármaco
La ecuación \(\hat{y} = b_0 + b_1x\) se interpreta de forma muy inteligente:
Nota pedagógica: Correr
lm(Y ~ X_dicotomica)es matemáticamente equivalente a realizar una prueba t de Student para muestras independientes.
# 0. Simular datos
set.seed(456)
grupo <- factor(rep(c("Placebo", "Farmaco"), each = 30))
# Suponemos que el fármaco reduce la HbA1c en 1.5 puntos
hba1c <- ifelse(grupo == "Placebo", rnorm(30, 8.5, 1), rnorm(30, 7.0, 1))
datos_farmaco <- data.frame(grupo, hba1c)
# 1. Visualizar (Boxplot es mejor para Y continua vs X categórica)
boxplot(hba1c ~ grupo, data = datos_farmaco,
main = "HbA1c por Grupo de Tratamiento",
ylab = "Nivel de HbA1c (%)",
col = c("lightblue", "salmon"))
Boxplot de HbA1c por grupo de tratamiento.
# 2. Correr el modelo.
# R elegirá "Farmaco" como 0 (referencia) por orden alfabético.
# Para claridad pedagógica, re-nivelamos para que "Placebo" sea la referencia:
datos_farmaco$grupo <- relevel(datos_farmaco$grupo, ref = "Placebo")
# Corremos el modelo
modelo_farmaco <- lm(hba1c ~ grupo, data = datos_farmaco)
# 3. Ver resultados
summary(modelo_farmaco)
##
## Call:
## lm(formula = hba1c ~ grupo, data = datos_farmaco)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.15506 -0.68735 -0.00451 0.58496 2.04829
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 8.7317 0.1847 47.278 < 2e-16 ***
## grupoFarmaco -1.5756 0.2612 -6.032 1.21e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.012 on 58 degrees of freedom
## Multiple R-squared: 0.3855, Adjusted R-squared: 0.3749
## F-statistic: 36.39 on 1 and 58 DF, p-value: 1.205e-07
A continuación, se desglosa la salida de
summary(modelo_farmaco) línea por línea, usando nuestros
valores simulados como ejemplo.
Call: (La Llamada)Call: lm(formula = hba1c ~ grupo, data = datos_farmaco) *
Interpretación: Esta línea es simplemente un
recordatorio de la fórmula exacta y el conjunto
de datos (data) que usted utilizó para crear el
objeto modelo_farmaco. Es útil para verificar que corrió el
modelo que pretendía correr.
Min 1Q Median 3Q Max -2.04321 -0.69085 -0.00941 0.64787 2.24151
Median (Mediana): El valor ideal es
cerca de 0. Nuestro valor de -0.00941 es
excelente, indicando que los errores positivos y negativos están bien
balanceados.1Q y 3Q (Cuartiles):
Buscamos simetría. Comparamos el valor absoluto del primer cuartil
(|-0.69| ≈ 0.69) con el tercer cuartil (0.64).
Están muy cerca, lo que sugiere que la distribución de los residuos es
bastante simétrica alrededor de cero.Min y Max: Nos muestran
los errores más extremos (el modelo subestimó en 2.04 puntos y
sobreestimó en 2.24 puntos en los peores casos). También parecen
simétricos.Coefficients:)Esta tabla detalla los componentes de la ecuación del modelo: \(\hat{HbA1c} = b_0 + b_1(grupoFarmaco)\).
(Intercept)
Estimate (ej. 8.550): Es el valor de
\(b_0\). Es la media de
HbA1c para el Grupo Placebo.Std. Error (ej. 0.185): Es el error
estándar de esa media. Mide la precisión de la estimación de la media
del grupo placebo.t value (ej. 46.2) y Pr(>|t|)
(ej. <2e-16): Prueban si la media del grupo placebo es
significativamente diferente de 0. (Clínicamente no es relevante, pero
confirma que la media es positiva).grupoFarmaco
Estimate (ej. -1.580): Es el valor de
\(b_1\). Es la diferencia en
medias (\(Media_{Farmaco} -
Media_{Placebo}\)).t value (ej. -6.0) y Pr(>|t|)
(ej. 5e-08): Esta es la prueba clave. Prueba la \(H_0: \beta_1 = 0\) (no hay diferencia entre
grupos).5e-08) es < 0.05, rechazamos \(H_0\). Concluimos que existe una
diferencia estadísticamente significativa entre los dos
grupos.Estas líneas evalúan qué tan bien funciona el modelo en su conjunto.
Residual standard error: 1.01 on 58 degrees of freedom
58 degrees of freedom: Grados de
libertad de los residuos (n - k - 1, o
60 - 1 - 1 = 58).Multiple R-squared: 0.383, Adjusted R-squared: 0.372
Multiple R-squared (R²): Es el
Coeficiente de Determinación.Adjusted R-squared (R² Ajustado): Una
versión corregida (y más realista) del R² que penaliza la
complejidad.F-statistic: 36.0 on 1 and 58 DF, p-value: 5.0e-08
5.0e-08)
es < 0.05, lo que rechaza \(H_0\). Confirma que nuestro modelo
(saber el grupo) es significativamente mejor para predecir HbA1c que
simplemente usar la media general de todos los pacientes.💡 Conexión Clave: ¡Prueba t = Prueba F!
En la Regresión Lineal Simple (con un solo predictor, como en este caso), la prueba t para el coeficiente y la prueba F global son matemáticamente idénticas y dan la misma respuesta.
Observe los valores de nuestro ejemplo:
t valueparagrupoFarmaco= -6.0F-statisticglobal = 36.0- p-valor de t = 5e-08
- p-valor de F = 5.0e-08
La relación es: \((t \text{ value})^2 = F \text{ statistic}\)
\[(-6.0)^2 = 36.0\]
Ambas pruebas están evaluando la misma hipótesis (si hay una asociación significativa entre el grupo y la HbA1c) y, por lo tanto, llegan exactamente al mismo p-valor.
Cuando la variable explicativa \(X\) tiene \(k\) categorías (ej. Estadio de Cáncer I, II, III, IV), no podemos usar un solo número (1, 2, 3, 4) porque implicaría un orden y una distancia que podrían no ser reales.
En su lugar, el modelo crea \(k-1\) variables dummy (indicadoras).
Se elige automáticamente una categoría como Nivel de Referencia (usualmente la primera por orden alfabético o la que definamos).
Se crea una variable dummy (binaria 0/1) para cada una de las otras \(k-1\) categorías.
Un epidemiólogo estudia la relación entre el Nivel de Actividad Física (\(X\)) y el Índice de Masa Corporal (IMC) (\(Y\)).
La ecuación (que ahora es una regresión múltiple) es: \[\hat{IMC} = b_0 + b_1X_{media} + b_2X_{alta}\]
Nota pedagógica: Este modelo es la base del Análisis de Varianza (ANOVA). Correr este
lm()es equivalente a realizar un ANOVA para comparar las medias de los 3 grupos.
# 0. Simular datos
set.seed(789)
# Definimos los niveles en el orden deseado ("Baja" será la referencia)
actividad_levels <- c("Baja", "Media", "Alta")
actividad <- factor(sample(actividad_levels, 90, replace = TRUE),
levels = actividad_levels)
# Suponemos IMC = 30 (Baja), 27 (Media), 25 (Alta) + ruido
imc <- 30 + (actividad == "Media") * (-3) + (actividad == "Alta") * (-5) + rnorm(90, 0, 2)
datos_actividad <- data.frame(actividad, imc)
# 1. Visualizar
boxplot(imc ~ actividad, data = datos_actividad,
main = "IMC por Nivel de Actividad",
col = c("red", "yellow", "green"))
Boxplot de IMC por nivel de actividad.
# 2. Correr el modelo
# R automáticamente crea las dummies (X_media y X_alta)
# basado en el factor 'actividad'
modelo_actividad <- lm(imc ~ actividad, data = datos_actividad)
# 3. Ver resultados
summary(modelo_actividad)
##
## Call:
## lm(formula = imc ~ actividad, data = datos_actividad)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.4710 -1.3205 0.2047 1.4053 4.0628
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 30.1765 0.3594 83.968 < 2e-16 ***
## actividadMedia -3.1782 0.4829 -6.581 3.37e-09 ***
## actividadAlta -5.0115 0.5282 -9.488 4.49e-15 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.935 on 87 degrees of freedom
## Multiple R-squared: 0.5201, Adjusted R-squared: 0.509
## F-statistic: 47.14 on 2 and 87 DF, p-value: 1.354e-14
Basado en la salida Coefficients:
\(b_0\)
(Intercept): (Ej. 30.150). Es el IMC
medio esperado para el grupo de referencia (actividad
“Baja”).
\(b_1\)
(actividadMedia): (Ej. -3.100). Es la
diferencia entre la media del grupo “Media” y la media
del grupo “Baja”.
\(b_2\)
(actividadAlta): (Ej. -5.250). Es la
diferencia entre la media del grupo “Alta” y la media
del grupo “Baja”.
El p-valor global del modelo F (en la última línea del summary) nos dirá si existe alguna diferencia significativa entre las medias de los tres grupos (el resultado del ANOVA).
Este es, posiblemente, el concepto más importante de la bioestadística.
El hecho de encontrar un p-valor pequeño (ej. \(p < 0.05\)) o un R² alto (ej. \(R^2 = 0.85\)) NO PRUEBA que la variable \(X\) causa un cambio en la variable \(Y\).
La regresión lineal, al igual que la correlación, solo mide asociación (o predicción).
En un estudio observacional, una fuerte asociación entre \(X\) e \(Y\) podría existir por varias razones además de la causalidad:
Conclusión: La causalidad solo puede inferirse a partir de diseños de estudio muy robustos, específicamente Ensayos Clínicos Aleatorizados (ECA), donde el investigador manipula \(X\) (asigna el tratamiento/placebo al azar) y elimina el efecto de las variables de confusión.
CAP_modifedad), uno dicotómico (genero) y uno
politómico (nivel_edu) en modelos RLS separados.En este módulo final, usaremos nuestra base de datos
CAP_modif para practicar todo lo aprendido. No
construiremos un modelo múltiple, sino tres modelos simples
separados para entender la relación “cruda” (no ajustada) de
cada predictor con el puntaje de conocimientos.
Nuestra variable de respuesta (\(Y\)) será siempre
puntaje_C.
Este primer paso es el más crítico. Cargaremos los datos y, lo más
importante, inspeccionaremos las variables categóricas
(genero y nivel_edu) para asegurarnos de que R
las entienda como “factores” y para ver cuáles son sus niveles de
referencia.
# Instalar paquetes si no los tiene
# install.packages("readxl")
library(readxl)
# 2. Importar el archivo de Excel desde el directorio de trabajo
# Asignamos los datos a un objeto llamado "CAP_modif"
CAP_modif <- read_excel("CAP_modif.xlsx")
# 2. Inspeccionar la estructura
# Vemos los nombres de columnas y sus tipos
str(CAP_modif)
## tibble [515 × 92] (S3: tbl_df/tbl/data.frame)
## $ id : num [1:515] 1 2 3 4 5 6 7 8 9 10 ...
## $ part_prev : chr [1:515] "No" "Si" "No" "No" ...
## $ municipio : chr [1:515] "Santa Tecla" "Santa Tecla" "Santa Tecla" "Santa Tecla" ...
## $ edad : num [1:515] 52 50 27 50 47 47 33 21 37 29 ...
## $ genero : chr [1:515] "Femenino" "Masculino" "Femenino" "Masculino" ...
## $ nivel_edu : chr [1:515] "Nunca asistio" "Primer ciclo" "Bachillerato" "Tercer ciclo" ...
## $ enf_cro : chr [1:515] "No" "Si" "No" "No" ...
## $ hipertension : chr [1:515] "No" "No" "No" "No" ...
## $ diabetes : chr [1:515] "No" "Si" "No" "No" ...
## $ epoc : chr [1:515] "No" "No" "No" "No" ...
## $ renal : chr [1:515] "No" "No" "No" "No" ...
## $ artritis : chr [1:515] "No" "No" "No" "No" ...
## $ cardiopatia : chr [1:515] "No" "No" "No" "No" ...
## $ hipotiroidismo : chr [1:515] "No" "No" "No" "No" ...
## $ glaucoma : chr [1:515] "No" "No" "No" "No" ...
## $ lupus : chr [1:515] "No" "No" "No" "No" ...
## $ ulcera_venosa : chr [1:515] "No" "No" "No" "No" ...
## $ ninguna : logi [1:515] NA NA NA NA NA NA ...
## $ area : chr [1:515] "Urbana" "Rural" "Rural" "Urbana" ...
## $ hijxs : chr [1:515] "Si" "Si" "Si" "No" ...
## $ nucleo : num [1:515] 5 2 5 3 4 5 3 2 3 3 ...
## $ empleo : chr [1:515] "Desempleo" "Empleo" "Desempleo" "Empleo" ...
## $ ocupacion : chr [1:515] "Desempleo" "Empleada(o) permanente" "Desempleo" "Trabajo por cuenta propia sin local" ...
## $ ingreso : chr [1:515] "Menos de 365" "Prefiero no contestar" "366 a 730" "Menos de 365" ...
## $ prev_per : chr [1:515] "No" "No, sabe" "No" "No" ...
## $ rec_apoyo : chr [1:515] NA "No" NA NA ...
## $ satisfaccion : chr [1:515] NA NA NA NA ...
## $ prev_fam : chr [1:515] "Si, hubo sospecha pero no se hizo la prueba" "No" "No" "No" ...
## $ mortalidad : chr [1:515] "No" "No" "No" "No" ...
## $ c1 : num [1:515] 3 1 1 1 1 1 1 1 1 1 ...
## $ c2 : num [1:515] 2 1 1 1 1 1 1 1 1 1 ...
## $ c3 : num [1:515] 3 1 3 1 1 3 1 3 3 1 ...
## $ c4 : num [1:515] 1 1 1 1 1 1 1 3 3 1 ...
## $ c5 : num [1:515] 1 3 1 1 3 1 3 3 3 2 ...
## $ c6 : num [1:515] 1 1 2 1 1 2 1 2 2 1 ...
## $ c7 : num [1:515] 3 3 2 2 3 1 1 3 1 1 ...
## $ c8 : num [1:515] 1 1 1 1 1 1 1 1 1 1 ...
## $ c9 : num [1:515] 1 1 2 1 1 1 1 1 1 1 ...
## $ c10 : num [1:515] 2 1 1 2 1 1 1 1 1 1 ...
## $ a1 : num [1:515] 5 4 5 5 4 3 4 3 2 5 ...
## $ a2 : num [1:515] 5 5 5 5 4 3 4 3 5 5 ...
## $ a3 : num [1:515] 1 2 5 5 3 1 4 1 2 4 ...
## $ a4 : num [1:515] 5 5 5 5 4 5 4 5 5 4 ...
## $ a5 : num [1:515] 1 3 5 1 4 4 4 1 3 4 ...
## $ p1 : num [1:515] 5 3 5 5 1 4 3 3 3 2 ...
## $ p2 : num [1:515] 2 0 3 3 0 2 0 2 2 0 ...
## $ p3 : num [1:515] 3 0 2 3 0 3 0 2 2 0 ...
## $ p4 : num [1:515] 5 1 5 3 1 3 1 3 3 1 ...
## $ p5 : num [1:515] 5 1 3 2 3 3 3 2 5 3 ...
## $ dosis : num [1:515] 3 3 4 3 2 2 2 1 4 3 ...
## $ razon_nv : chr [1:515] "Razon 5" "Razon 6" "Razon 1" "Razon 6" ...
## $ periodico : chr [1:515] "Si" "No" "No" "Si" ...
## $ television : chr [1:515] "Si" "Si" "Si" "Si" ...
## $ redes_sociales : chr [1:515] "No" "Si" "Si" "No" ...
## $ personal_salud : chr [1:515] "No" "No" "No" "No" ...
## $ radio : chr [1:515] "Si" "No" "Si" "No" ...
## $ paginas_internet : chr [1:515] "No" "No" "Si" "Si" ...
## $ escuela : chr [1:515] "Si" "No" "No" "No" ...
## $ mensajes : chr [1:515] "Si" "Si" "Si" "Si" ...
## $ patrocinio : logi [1:515] NA NA NA NA NA NA ...
## $ uso_de_mascarilla : chr [1:515] "Si" "Si" "Si" "Si" ...
## $ distanciamiento_social : chr [1:515] "Si" "No" "Si" "Si" ...
## $ lavado_de_manos : chr [1:515] "No" "Si" "Si" "No" ...
## $ ponerse_la_vacuna : chr [1:515] "Si" "No" "No" "Si" ...
## $ no_recuerdo : chr [1:515] "No" "No" "No" "No" ...
## $ todas : chr [1:515] "No" "No" "No" "No" ...
## $ No_he_escuchado : chr [1:515] "No" "No" "No" "No" ...
## $ transmite_por_el_agua : chr [1:515] "Si" "No" "No" "Si" ...
## $ transmite_en_las_suelas: chr [1:515] "Si" "No" "No" "Si" ...
## $ rociar_desinfectantes : chr [1:515] "Si" "No" "Si" "Si" ...
## $ beben_alcohol : chr [1:515] "No" "No" "No" "Si" ...
## $ pueden_dejar_de_aplicar: chr [1:515] "Si" "No" "No" "No" ...
## $ no_se_debe_vacunar : chr [1:515] "No" "No" "Si" "Si" ...
## $ producen_esterilidad : chr [1:515] "No" "No" "No" "No" ...
## $ producen_homosexualidad: chr [1:515] "No" "Si" "No" "No" ...
## $ inyectan_el_virus : chr [1:515] "No" "No" "Si" "Si" ...
## $ antibioticos_son_buenos: chr [1:515] "No" "No" "No" "Si" ...
## $ vitaminas_y_minerales : chr [1:515] "No" "No" "No" "No" ...
## $ entrevistadoras : num [1:515] 2 1 2 2 1 2 1 2 2 1 ...
## $ puntaje_A : num [1:515] 17 19 25 21 19 16 20 13 17 22 ...
## $ c1recod : num [1:515] 0 1 1 1 1 1 1 1 1 1 ...
## $ c2recod : num [1:515] 0 1 1 1 1 1 1 1 1 1 ...
## $ c3recod : num [1:515] 0 1 0 1 1 0 1 0 0 1 ...
## $ c4recod : num [1:515] 1 1 1 1 1 1 1 0 0 1 ...
## $ c5recod : num [1:515] 1 0 1 1 0 1 0 0 0 0 ...
## $ c6recod : num [1:515] 1 1 0 1 1 0 1 0 0 1 ...
## $ c7recod : num [1:515] 0 0 0 0 0 1 1 0 1 1 ...
## $ c8recod : num [1:515] 1 1 1 1 1 1 1 1 1 1 ...
## $ c9recod : num [1:515] 1 1 0 1 1 1 1 1 1 1 ...
## $ c10recod : num [1:515] 0 1 1 0 1 1 1 1 1 1 ...
## $ puntaje_C : num [1:515] 5 8 6 8 8 8 9 5 6 9 ...
## $ puntaje_P : num [1:515] 20 5 18 16 5 15 7 12 15 6 ...
# 3. Conversión de variables categóricas
# Si 'genero' y 'nivel_edu' aparecen como 'chr' (texto),
# debemos convertirlos a 'factor'.
CAP_modif$genero <- as.factor(CAP_modif$genero)
CAP_modif$nivel_edu <- as.factor(CAP_modif$nivel_edu)
# 4. Inspeccionar los niveles (¡CRÍTICO!)
# Esto nos dice qué categorías existen y cuál es la referencia
# (la referencia es la primera que aparece en la lista)
print("Niveles de la variable 'genero':")
## [1] "Niveles de la variable 'genero':"
levels(CAP_modif$genero)
## [1] "Femenino" "Masculino"
print("Niveles de la variable 'nivel_edu':")
## [1] "Niveles de la variable 'nivel_edu':"
levels(CAP_modif$nivel_edu)
## [1] "Bachillerato" "Nunca asistio" "Primer ciclo" "Segundo ciclo"
## [5] "Tecnico" "Tercer ciclo" "Universitario"
Aquí aplicamos lo visto en el Módulo 3.
# 1. Visualizar (Diagrama de Dispersión)
plot(puntaje_C ~ edad, data = CAP_modif,
main = "Puntaje de Conocimientos vs. Edad",
xlab = "Edad (años)",
ylab = "Puntaje de Conocimientos (puntaje_C)",
pch = 19, col = "blue")
# 2. Correr el modelo RLS
modelo_edad <- lm(puntaje_C ~ edad, data = CAP_modif)
# 3. Añadir la línea de regresión
abline(modelo_edad, col = "red", lwd = 2)
Relación entre Puntaje de Conocimientos y Edad.
# 4. Ver los resultados
summary(modelo_edad)
##
## Call:
## lm(formula = puntaje_C ~ edad, data = CAP_modif)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.9922 -1.1856 -0.0352 1.5853 3.0078
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.736995 0.209577 36.92 < 2e-16 ***
## edad -0.014322 0.004651 -3.08 0.00218 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.618 on 513 degrees of freedom
## Multiple R-squared: 0.01815, Adjusted R-squared: 0.01624
## F-statistic: 9.484 on 1 and 513 DF, p-value: 0.002184
edad): “Por cada año adicional de edad, el puntaje
de conocimientos [aumenta/disminuye] en [X] puntos, en promedio”. (Mire
el Estimate de edad).Multiple R-squared).Pr(>|t|) de edad).Aquí aplicamos lo visto en el Módulo 7.
# 1. Visualizar (Boxplot)
boxplot(puntaje_C ~ genero, data = CAP_modif,
main = "Puntaje de Conocimientos por Género",
ylab = "Puntaje de Conocimientos (puntaje_C)",
col = c("pink", "lightblue"))
Puntaje de Conocimientos por Género.
# 2. Correr el modelo RLS (Prueba t)
modelo_genero <- lm(puntaje_C ~ genero, data = CAP_modif)
# 3. Ver los resultados
summary(modelo_genero)
##
## Call:
## lm(formula = puntaje_C ~ genero, data = CAP_modif)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.0402 -1.1993 -0.0402 1.8007 2.9598
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.19931 0.09563 75.287 <2e-16 ***
## generoMasculino -0.15913 0.14500 -1.098 0.273
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.631 on 513 degrees of freedom
## Multiple R-squared: 0.002343, Adjusted R-squared: 0.0003978
## F-statistic: 1.205 on 1 and 513 DF, p-value: 0.2729
(Basado en la salida del chunk Carga_Datos_CAP,
suponga que el Nivel de Referencia (ej. “Femenino”) fue el primero en la
lista levels(CAP_modif$genero))
genero[Nivel 2]): “El género [Nivel 2, ej.
‘Masculino’] tiene, en promedio, [X] puntos [más/menos] en conocimientos
que el género de referencia”.Pr(>|t|) del coeficiente \(b_1\)).Aquí aplicamos lo visto en el Módulo 8.
(Nota Importante: Si el nivel de referencia (ej. “Sin estudios” o “Primaria”) no es el primero en la lista alfabética, debemos re-nivelarlo como se muestra en el chunk)
# 1. OPCIONAL: Re-nivelar el factor si es necesario
# Supongamos que la salida de `levels(CAP_modif$nivel_edu)`
# mostró que "Bachillerato" era la referencia (por orden alfabético),
# pero queremos que "Primaria" sea la referencia.
# Descomente la línea de abajo para re-nivelar:
# CAP_modif$nivel_edu <- relevel(CAP_modif$nivel_edu, ref = "Primaria")
# 2. Visualizar (Boxplot)
# (Usar 'las=2' para girar las etiquetas del eje x si son muy largas)
boxplot(puntaje_C ~ nivel_edu, data = CAP_modif,
main = "Puntaje de Conocimientos por Nivel Educativo",
ylab = "Puntaje de Conocimientos (puntaje_C)",
las = 2,
col = rainbow(length(levels(CAP_modif$nivel_edu))))
Puntaje de Conocimientos por Nivel Educativo.
# 3. Correr el modelo RLS (ANOVA)
modelo_edu <- lm(puntaje_C ~ nivel_edu, data = CAP_modif)
# 4. Ver los resultados
summary(modelo_edu)
##
## Call:
## lm(formula = puntaje_C ~ nivel_edu, data = CAP_modif)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.4486 -0.8889 0.1111 1.2593 3.1111
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.4486 0.1131 65.859 < 2e-16 ***
## nivel_eduNunca asistio -0.8123 0.3469 -2.341 0.019599 *
## nivel_eduPrimer ciclo -1.3028 0.2492 -5.228 2.5e-07 ***
## nivel_eduSegundo ciclo -0.7079 0.2050 -3.454 0.000599 ***
## nivel_eduTecnico -0.1986 0.3621 -0.549 0.583519
## nivel_eduTercer ciclo -0.5598 0.1817 -3.081 0.002178 **
## nivel_eduUniversitario 1.0275 0.2629 3.908 0.000106 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.538 on 508 degrees of freedom
## Multiple R-squared: 0.1214, Adjusted R-squared: 0.111
## F-statistic: 11.7 on 6 and 508 DF, p-value: 2.688e-12
(Suponga que “Primaria” es su nivel de referencia)
dummy):
nivel_edu[Secundaria]: “Las personas con nivel
‘Secundaria’ tienen, en promedio, [X] puntos [más/menos] que las de
‘Primaria’”.nivel_edu[Bachillerato]: “Las personas con nivel
‘Bachillerato’ tienen, en promedio, [X] puntos [más/menos] que las de
‘Primaria’”.F-statistic (última línea) nos dice si existe
alguna diferencia significativa en el puntaje de conocimientos
entre cualquiera de los niveles educativos (el resultado del
ANOVA)”.Reflexión Final del Tutorial:
Acabamos de analizar las asociaciones crudas (univariadas). El siguiente paso en un análisis real (que veríamos en Regresión Múltiple) sería combinar todos estos predictores en un solo modelo (
lm(puntaje_C ~ edad + genero + nivel_edu)).Al hacer eso, podríamos ver el efecto “ajustado” de la edad, controlando por el efecto del género y la educación. A menudo, las asociaciones “crudas” que vimos aquí cambian (o incluso desaparecen) cuando se “ajustan” por otros predictores.