Entender los abordajes estadísticos tradicionales como regresiones
Aquí veremos las pruebas estadísticas más comunes y mostraremos cómo pueden representarse en el formato de regresión lineal. Esta sección se basa en este artículo. Consúltelo para obtener una descripción más detallada de las alternativas no paramétricas.
1 Prueba t de una muestra
La prueba evalúa si la media de una variable continua es diferente de 0. Es equivalente a una regresión lineal sin predictor, que prueba si el intercepto es diferente de 0:
\(y = \beta_0 \qquad \mathcal{H}_0: \beta_0 = 0\)
Código
# number of observationsn <-50# set seedset.seed(123)# create variable with mean 1y <-rnorm(n = n, mean =1)# run t test(t <-t.test(y))
One Sample t-test
data: y
t = 7.9, df = 49, p-value = 2.7e-10
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
0.77127 1.29753
sample estimates:
mean of x
1.0344
Código
# run equivalent linear regression(lm_t <-summary(lm(y ~1)))
Call:
lm(formula = y ~ 1)
Residuals:
Min 1Q Median 3Q Max
-2.001 -0.594 -0.107 0.664 2.135
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.034 0.131 7.9 2.7e-10 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.926 on 49 degrees of freedom
Pongamos juntos los resultados de ambas pruebas para compararlos más de cerca:
model
estimate
p.value
t
mean of x
t-test
1.0344
0
7.9
lm
1.0344
0
7.9
Tenga en cuenta que, como no hay predictores en el modelo, utilizamos un ‘1’ en el lugar de los predictores en la fórmula del modelo (‘y ~ 1’).
2 Prueba de t pareada
Una prueba t pareada evalúa si la diferencia de promedios entre dos variables numéricas es 0
El modelo lineal correspondiente es el mismo que el de la prueba t de una muestra, pero la variable de entrada es la diferencia entre las dos variables (y1 - y2):
Código
set.seed(123)# sample sizen <-50# variable with mean 1y1 <-rnorm(n = n, mean =1)# variable with mean 3y2 <-rnorm(n = n, mean =1.4)# run paired t testpaired_t <-t.test(y1, y2, paired =TRUE)paired_t
Paired t-test
data: y1 and y2
t = -2.75, df = 49, p-value = 0.0084
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-0.88659 -0.13742
sample estimates:
mean of the differences
-0.512
Código
# difference between the 2 variablesdiff_y <- y1 - y2# run modellm_paired_t <-summary(lm(formula = diff_y ~1))lm_paired_t
Call:
lm(formula = diff_y ~ 1)
Residuals:
Min 1Q Median 3Q Max
-2.600 -0.701 0.112 1.035 2.909
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.512 0.186 -2.75 0.0084 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 1.32 on 49 degrees of freedom
model
estimate
p.value
t
mean of the differences
paired t-test
-0.512
0.00839
-2.7468
lm
-0.512
0.00839
-2.7468
3 Prueba t de dos promedios
También llamada prueba t independiente. Evalúa si los promedios de las dos variables son diferentes. La hipótesis nula es que la diferencia es 0:
# set seedset.seed(123)# number of observationsn <-50b0 <--4b1 <-3error <-rnorm(n = n, mean =0, sd =1)# random variablesx1_num <-rbinom(n = n, size =1, prob =0.5)y <- b0 + b1 * x1_num + errorx1 <-factor(x1_num, labels =c("a", "b"))# create data framexy_data_cat <-data.frame(x1, x1_num, y)# run paired t testindep_t <-t.test(xy_data_cat$y[xy_data_cat$x1 =="a"], xy_data_cat$y[xy_data_cat$x1 =="b"])indep_t
Welch Two Sample t-test
data: xy_data_cat$y[xy_data_cat$x1 == "a"] and xy_data_cat$y[xy_data_cat$x1 == "b"]
t = -12.3, df = 47.9, p-value <2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-3.7518 -2.6957
sample estimates:
mean of x mean of y
-4.07748 -0.85371
Código
# run regression modellm_indep_t <-summary(lm(formula = y ~ x1, data = xy_data_cat))lm_indep_t
Call:
lm(formula = y ~ x1, data = xy_data_cat)
Residuals:
Min 1Q Median 3Q Max
-2.113 -0.594 -0.136 0.552 2.246
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -4.077 0.186 -22.0 <2e-16 ***
x1b 3.224 0.263 12.3 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.928 on 48 degrees of freedom
Multiple R-squared: 0.758, Adjusted R-squared: 0.753
F-statistic: 151 on 1 and 48 DF, p-value: <2e-16
model
estimate
p.value
t
mean of y
2 means t-test
3.2238
0
-12.276
lm
3.2238
0
12.276
4 Tres o más promedios: ANDEVA unidireccional
Muy similar a la prueba t de dos promedios, pero con tres o más niveles en la variable categórica:
Se trata de un modelo de regresión múltiple. La variable categórica se codifica con dummy, por lo que se divide en predictores indicadores (\(x_i\) es \(x=0\) o \(x=1\)).
Un conjunto de datos con una variable categórica de 3 niveles puede simularse así:
Código
# set seedset.seed(123)# number of observationsn <-50b0 <--4b1 <-3error <-rnorm(n = n, mean =0, sd =1)# random variablesx1_num <-rbinom(n = n, size =2, prob =c(0.33, 0.33))y <- b0 + b1 * x1_num + errorx1 <-factor(x1_num, labels =c("a", "b", "c"))# create data framexy_data_cat2 <-data.frame(x1, y)head(xy_data_cat2)
# linear regressionlm_anv_1w <-summary(lm(formula = y1 ~ x1, data = xy_data_cat2))lm_anv_1w
Call:
lm(formula = y1 ~ x1, data = xy_data_cat2)
Residuals:
Min 1Q Median 3Q Max
-1.6721 -0.5195 -0.0289 0.4839 2.3266
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.842 0.187 4.51 4.2e-05 ***
x1b 0.565 0.277 2.04 0.047 *
x1c -0.141 0.367 -0.38 0.703
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.895 on 47 degrees of freedom
Multiple R-squared: 0.104, Adjusted R-squared: 0.066
F-statistic: 2.73 on 2 and 47 DF, p-value: 0.0755
model
F.statistic
p.value
1 way anova
2.7307
0.07552
value
lm
2.7307
0.07552
5 Chi-cuadrado para tablas de contingencia
Esta prueba busca la asociación entre dos variables categóricas basándose en la co-ocurrencia de las categorías, medidas como recuentos. Esto es lo que es una tabla de contingencia: recuentos de todas las combinaciones de categorías entre dos variables. Por ejemplo, las muertes por edad de los pasajeros del Titanic:
Los coeficientes de regresión son \(A_i\) y \(B_i\). \(\alpha_i\) y \(\beta_j\) son las proporciones de recuentos para los dos niveles de la variable categórica binaria (uno para cada uno de los niveles de la segunda variable categórica). Afortunadamente, existe una implementación de este modelo en el paquete R ‘MASS’ que simplifica la codificación:
Código
# Built-in chi-square. It requires matrix format.chi_mod <-chisq.test(mood_data)chi_mod
# convert to longmood_data_long <-as.data.frame(as.table(mood_data))# log linear model from MASS packagelog_lm_mod <- MASS::loglm(Freq ~ handedness + mood, data = mood_data_long)log_lm_mod
6 Alternativas “no paramétricas” como modelos de regresión lineal
Sólo presentaremos un ejemplo de prueba “no paramétrica”. No obstante, este único ejemplo debería bastar para demostrar la lógica que subyace a los procedimientos “no paramétricos”. La mayoría de las pruebas “no paramétricas” se basan en un sencillo truco de transformación de datos: la transformación de rango de las respuestas. Las transformaciones de rango convierten los valores en un índice según su posición cuando se ordenan por magnitud:
Wilcoxon signed rank test with continuity correction
data: y_data$y
V = 797, p-value = 0.12
alternative hypothesis: true location is not equal to 0
Código
signed_rank <-function(x) sign(x) *rank(abs(x))# As linear model with our dummy-coded group_y2:wicx_lm_mod <-lm(signed_rank(y) ~1, data = y_data) # compare tosummary(wicx_lm_mod)
Call:
lm(formula = signed_rank(y) ~ 1, data = y_data)
Residuals:
Min 1Q Median 3Q Max
-53.38 -24.13 0.12 25.37 43.62
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6.38 4.09 1.56 0.12
Residual standard error: 28.9 on 49 degrees of freedom
---title: <font size="7"><b>Modelos estádisticos tradicionales como regresiones</b></font>---```{=html}<style>body { counter-reset: source-line 0; }pre.numberSource code { counter-reset: none; }</style>``````{r,echo=FALSE,message=FALSE}options("digits"=5)options("digits.secs"=3)# options to customize chunk outputsknitr::opts_chunk$set(class.source ="numberLines lineAnchors", # for code line numbersmessage =FALSE)```::: {.alert .alert-info}# Objetivo del manual {.unnumbered .unlisted}- Entender los abordajes estadísticos tradicionales como regresiones:::```{r, echo = FALSE, message=FALSE}library(knitr)library(ggplot2)library(viridis)# ggplot settingsgeom_histogram <-function(...) ggplot2::geom_histogram(..., fill =viridis(10, alpha =0.5)[8], show.legend =FALSE, bins =20, color ="black")geom_smooth <-function(...) ggplot2::geom_smooth(..., color =viridis(10, alpha =0.5)[8])geom_boxplot <-function(...) ggplot2::geom_boxplot(..., fill =viridis(10, alpha =0.5)[7])theme_set(theme_classic(base_size =20))# options to customize chunk outputsknitr::opts_chunk$set(class.source ="numberLines lineAnchors", # for code line numbersmessage =FALSE)```Aquí veremos las pruebas estadísticas más comunes y mostraremos cómo pueden representarse en el formato de regresión lineal. Esta sección se basa en [este artículo](https://lindeloev.github.io/tests-as-linear/). Consúltelo para obtener una descripción más detallada de las alternativas no paramétricas. ---# Prueba t de una muestraLa prueba evalúa si la media de una variable continua es diferente de 0. Es equivalente a una regresión lineal sin predictor, que prueba si el intercepto es diferente de 0:<center><fontsize=6>$y = \beta_0 \qquad \mathcal{H}_0: \beta_0 = 0$</font></center> ```{r}# number of observationsn <-50# set seedset.seed(123)# create variable with mean 1y <-rnorm(n = n, mean =1)# run t test(t <-t.test(y))# run equivalent linear regression(lm_t <-summary(lm(y ~1)))``` Pongamos juntos los resultados de ambas pruebas para compararlos más de cerca:```{r, echo = FALSE}df <-data.frame(model =c("t-test", "lm"),estimate =c(t$estimate, lm_t$coefficients[1]),"p value"=c(t$p.value, lm_t$coefficients[4]),t =c(t$statistic, lm_t$coefficients[3]))df``` Tenga en cuenta que, como no hay predictores en el modelo, utilizamos un '1' en el lugar de los predictores en la fórmula del modelo ('y ~ 1').---# Prueba de t pareadaUna prueba t pareada evalúa si la diferencia de promedios entre dos variables numéricas es 0<center><fontsize=6>$y1 - y2 = \beta_0 \qquad \mathcal{H}_0: \beta_0 = 0$</font></center> El modelo lineal correspondiente es el mismo que el de la prueba t de una muestra, pero la variable de entrada es la diferencia entre las dos variables (y1 - y2):```{r}set.seed(123)# sample sizen <-50# variable with mean 1y1 <-rnorm(n = n, mean =1)# variable with mean 3y2 <-rnorm(n = n, mean =1.4)# run paired t testpaired_t <-t.test(y1, y2, paired =TRUE)paired_t# difference between the 2 variablesdiff_y <- y1 - y2# run modellm_paired_t <-summary(lm(formula = diff_y ~1))lm_paired_t``````{r, echo = FALSE}df <-data.frame(model =c("paired t-test", "lm"),estimate =c(paired_t$estimate, lm_paired_t$coefficients[1]),"p value"=c(paired_t$p.value, lm_paired_t$coefficients[4]),t =c(paired_t$statistic, lm_paired_t$coefficients[3]))df``` ---# Prueba t de dos promediosTambién llamada prueba t independiente. Evalúa si los promedios de las dos variables son diferentes. La hipótesis nula es que la diferencia es 0:<center><fontsize=6>$y = \beta_0 + \beta_1 * x1 \qquad \mathcal{H}_0: \beta_1 = 0$</font></center>```{r}# set seedset.seed(123)# number of observationsn <-50b0 <--4b1 <-3error <-rnorm(n = n, mean =0, sd =1)# random variablesx1_num <-rbinom(n = n, size =1, prob =0.5)y <- b0 + b1 * x1_num + errorx1 <-factor(x1_num, labels =c("a", "b"))# create data framexy_data_cat <-data.frame(x1, x1_num, y)# run paired t testindep_t <-t.test(xy_data_cat$y[xy_data_cat$x1 =="a"], xy_data_cat$y[xy_data_cat$x1 =="b"])indep_t# run regression modellm_indep_t <-summary(lm(formula = y ~ x1, data = xy_data_cat))lm_indep_t``````{r, echo = FALSE}df <-data.frame(model =c("2 means t-test", "lm"),estimate =c(indep_t$estimate[2] - indep_t$estimate[1], lm_indep_t$coefficients[2, 1]),"p value"=c(indep_t$p.value, lm_indep_t$coefficients[2, 4]),t =c(indep_t$statistic, lm_indep_t$coefficients[2, 3]))df``` ---# Tres o más promedios: ANDEVA unidireccionalMuy similar a la prueba t de dos promedios, pero con tres o más niveles en la variable categórica:<center><fontsize=6>$\hat{Y} \sim \beta_{o} + \beta_{1} * x_{1} + \beta_{2} * x_{2} + ... \qquad \mathcal{H}_0: y = \beta_0$</font></center> Se trata de un **modelo de regresión múltiple**. La variable categórica se codifica con dummy, por lo que se divide en predictores indicadores ($x_i$ es $x=0$ o $x=1$). Un conjunto de datos con una variable categórica de 3 niveles puede simularse así:```{r}# set seedset.seed(123)# number of observationsn <-50b0 <--4b1 <-3error <-rnorm(n = n, mean =0, sd =1)# random variablesx1_num <-rbinom(n = n, size =2, prob =c(0.33, 0.33))y <- b0 + b1 * x1_num + errorx1 <-factor(x1_num, labels =c("a", "b", "c"))# create data framexy_data_cat2 <-data.frame(x1, y)head(xy_data_cat2)``````{r, print_df = "default"}# ANOVA functionanv_1w <-anova(aov(formula = y1 ~ x1, data = xy_data_cat2))anv_1w# linear regressionlm_anv_1w <-summary(lm(formula = y1 ~ x1, data = xy_data_cat2))lm_anv_1w``````{r, echo = FALSE}df <-data.frame(model =c("1 way anova", "lm"),"F statistic"=c(anv_1w$`F value`[1], lm_anv_1w$fstatistic[1]),"p value"=c(anv_1w$`Pr(>F)`[1], 0.07552))df``` ---# Chi-cuadrado para tablas de contingenciaEsta prueba busca la asociación entre dos variables categóricas basándose en la co-ocurrencia de las categorías, medidas como recuentos. Esto es lo que es una tabla de contingencia: recuentos de todas las combinaciones de categorías entre dos variables. Por ejemplo, las muertes por edad de los pasajeros del Titanic:```{r}# Contingency table# modified from https://lindeloev.github.io/tests-as-linear/mood_data <-matrix(data =c(100, 70, 30, 32, 110, 120), nrow =2,dimnames =list(handedness =c("left_handed", "right_handed"), mood =c("happy", "meh", "sad")))mood_data``` Aunque la codificación es un poco más elaborada, puede reducirse a un modelo ANDEVA log-lineal de dos vías:$log(y_i) = log(N) + log(\alpha_i) + log(\beta_j) + log(\alpha_i\beta_j)$ Los coeficientes de regresión son $A_i$ y $B_i$. $\alpha_i$ y $\beta_j$ son las proporciones de recuentos para los dos niveles de la variable categórica binaria (uno para cada uno de los niveles de la segunda variable categórica). Afortunadamente, existe una implementación de este modelo en el paquete R 'MASS' que simplifica la codificación:```{r}# Built-in chi-square. It requires matrix format.chi_mod <-chisq.test(mood_data)chi_mod# convert to longmood_data_long <-as.data.frame(as.table(mood_data))# log linear model from MASS packagelog_lm_mod <- MASS::loglm(Freq ~ handedness + mood, data = mood_data_long)log_lm_mod``````{r, echo = FALSE}summ_log_lm <-summary(log_lm_mod)df <-data.frame(model =c("chi-square", "log lm"),`X squared`=c(chi_mod$statistic, summ_log_lm$tests[2, 1]),"p value"=c(chi_mod$p.value, summ_log_lm$tests[2, 3]))df``` # Alternativas "no paramétricas" como modelos de regresión linealSólo presentaremos un ejemplo de prueba "no paramétrica". No obstante, este único ejemplo debería bastar para demostrar la lógica que subyace a los procedimientos "no paramétricos". La mayoría de las pruebas "no paramétricas" se basan en un sencillo truco de transformación de datos: la transformación de rango de las respuestas. Las transformaciones de rango convierten los valores en un índice según su posición cuando se ordenan por magnitud:```{r}# simulate variableset.seed(123)y <-round(rnorm(n =5), 2)y# convert to ranksrank_y <-rank(y)rank_y``` ## Prueba de Wilcoxon para dos promediosTambién conocida como prueba de Mann-Whitney, es la alternativa no paramétrica a la prueba t de dos promedios: ```{r}# set seedset.seed(123)# number of observationsn <-50y <-rnorm(n = n, mean =0.2, sd =1)# create data framey_data <-data.frame(y)y# Wilcoxon / Mann-Whitney Uwilcx_mod <-wilcox.test(y_data$y)wilcx_modsigned_rank <-function(x) sign(x) *rank(abs(x))# As linear model with our dummy-coded group_y2:wicx_lm_mod <-lm(signed_rank(y) ~1, data = y_data) # compare tosummary(wicx_lm_mod)``````{r, echo = FALSE}summ_wicx_lm_mod <-summary(wicx_lm_mod)df <-data.frame(model =c("1 mean wilcoxon", "wilcoxon_lm"),p.value =c(wilcx_mod$p.value, summ_wicx_lm_mod$coefficients[4]))df``` ---# Referencias- [Common statistical tests are linear models](https://lindeloev.github.io/tests-as-linear/) --- <fontsize="4">Información de la sesión</font>```{r session info, echo=F}sessionInfo()```