1.- Introducción

La regresión lineal por mínimos cuadrados, así como muchas de sus adaptaciones, se emplean como método para estimar la media de una variable respuesta condicionada a uno o varios predictores. Es decir, parte de la premisa de que la media de la variable respuesta depende del valor que tomen otras variables. En determinadas situaciones, puede ocurrir que la media no sea el parámetro más informativo y que en su lugar se desee conocer un determinado cuantil, por ejemplo el cuantil 0.5 (la mediana). Es aquí donde la regresión de cuantiles (quantile regression) interviene. Si bien la matemática es diferente a la empleada en regresión por mínimos cuadrados ordinarios, la interpretación final es muy similar. Se obtienen coeficientes de regresión que estiman el efecto que tiene cada predictor sobre un cuantil específico de la variable respuesta.

El poder realizar regresión sobre cualquier parte de la distribución permite conocer la influencia de los predictores desde el mínimo al máximo rango de la variable respuesta. Esto es especialmente útil en modelos de regresión en los que no se cumple la condición de varianza constante, ya que esto significa que no hay un único ratio de cambio (pendiente) que represente bien a toda la variable respuesta a la vez.

2.- EJEMPLO Introductorio

# EJEMPLO 1 simulado
library(ggpubr)
## Loading required package: ggplot2
library(ggplot2)
# Variable X
x <- seq(0, 100, length.out = 100)
#Varianza heterocedástica
varianza <- 0.1 + 0.75*x
#Parámetros de la ecuación
b_0 <- 1
b_1 <- 2.5
# Error normal estocástico
set.seed(12345)
error <- rnorm(100, mean = 0, sd = varianza)
# respuesta
y <- b_0 + b_1*x + error
datos <- data.frame(x, y)
#Plot
ggplot(data=datos,aes(x=x, y=y)) + geom_point()+theme_classic2()

# Regresión OLS 
ggplot(data = datos, aes(x=x, y=y)) +
  geom_point() +
  geom_smooth(method = "lm", colour = "red", se = TRUE) +
  theme_bw()
## `geom_smooth()` using formula = 'y ~ x'

X > 50 –> La dispersión es más amplia. El intervalo de confianza calculado por OLS es más o menos constante, pero debería ser más amplio cuando hay más dispersión en cuando X es mayor a 30; por lo tanto, el IC no está totalmente bien calculado.

# Regresión de cuartiles
#-------------------------------------------------
library(quantreg)
## Warning: package 'quantreg' was built under R version 4.3.3
## Loading required package: SparseM
## 
## Attaching package: 'SparseM'
## The following object is masked from 'package:base':
## 
##     backsolve
modelo_q1 <- rq(formula = y ~x, tau = c(0.25, 0.50, 0.75),
                data = datos)
summary(object = modelo_q1, se = "boot")
## 
## Call: rq(formula = y ~ x, tau = c(0.25, 0.5, 0.75), data = datos)
## 
## tau: [1] 0.25
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  1.05855  2.76532    0.38280  0.70270
## x            2.04895  0.15254   13.43247  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.25, 0.5, 0.75), data = datos)
## 
## tau: [1] 0.5
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) -0.35595  2.86543   -0.12422  0.90140
## x            2.90813  0.18799   15.46997  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.25, 0.5, 0.75), data = datos)
## 
## tau: [1] 0.75
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) -0.10366  2.39117   -0.04335  0.96551
## x            3.24257  0.16537   19.60798  0.00000
library(ggplot2)
ggplot(data = datos, aes(x = x, y=y)) +
  geom_point()+
  geom_quantile(quantiles = c(0.25, 0.50, 0.75), color = "red")+
  theme_bw()
## Smoothing formula not specified. Using: y ~ x

plot(summary(modelo_q1), parm = "x")
## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

Vemos que existen diferencias significativas entre usar un modelo de cuantiles y OLS, ya que los efectos de la inclinación (parámetrob1) son diferentes al 95% de confianza.

# Regresión de cuartiles
#-------------------------------------------------
library(quantreg)
modelo_q2 <- rq(formula = y ~x, tau = c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9),
                data = datos)
## Warning in rq.fit.br(x, y, tau = tau, ...): Solution may be nonunique
summary(object = modelo_q2, se = "boot")
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.1
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept) -12.07734   8.90067   -1.35690   0.17793
## x             1.89136   0.18873   10.02141   0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.2
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  1.05855  2.44811    0.43240  0.66640
## x            1.90960  0.11450   16.67733  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.3
## 
## Coefficients:
##             Value   Std. Error t value Pr(>|t|)
## (Intercept) 1.58470 2.86543    0.55304 0.58149 
## x           2.11467 0.22950    9.21411 0.00000 
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.4
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) -0.25413  3.33203   -0.07627  0.93936
## x            2.55878  0.29176    8.77026  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.5
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) -0.35595  3.35278   -0.10616  0.91567
## x            2.90813  0.19473   14.93413  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.6
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) -0.22484  2.04632   -0.10987  0.91273
## x            3.01891  0.11233   26.87489  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.7
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  0.22956  2.50301    0.09171  0.92711
## x            3.16010  0.10635   29.71513  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.8
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  0.73865  4.87541    0.15151  0.87989
## x            3.36107  0.28741   11.69450  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.9
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  0.16782  4.48556    0.03741  0.97023
## x            3.92620  0.19642   19.98859  0.00000
library(ggplot2)
ggplot(data = datos, aes(x = x, y=y)) +
  geom_point()+
  geom_quantile(quantiles = c(0.1, 0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9), color = "red")+
  theme_bw()
## Smoothing formula not specified. Using: y ~ x
## Warning in rq.fit.br(wx, wy, tau = tau, ...): Solution may be nonunique

plot(summary(modelo_q2), parm ="x")
## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

#EJEMPLO 2 simulado
library(ggpubr)
library(ggplot2)
# Variable X
x <- seq(100, 0, lenght.out = 100)
## Warning: In seq.default(100, 0, lenght.out = 100) :
##  extra argument 'lenght.out' will be disregarded
#Varianza heterocedástica
varianza <- 0.1 + 0.8*x
#Parámetros de la ecuación
b_0 <- 5
b_1 <- 2.5
#Error normal estocástico
set.seed(12345)
error <- rnorm(100, mean = 0, sd = varianza)
#respuesta
y <- b_0 - b_1*x + error
## Warning in b_0 - b_1 * x + error: longitud de objeto mayor no es múltiplo de la
## longitud de uno menor
datos <- data.frame(x, y)
ggplot(data = datos, aes(x = x, y = y)) +
  geom_point() +
  theme_bw()

Es heterocedástica la varianza.

# Regresion OLS
ggplot(data = datos, aes(x=x, y=y)) +
  geom_point()+
  geom_smooth(method = "lm", colour = "red", se = TRUE) +
  geom_smooth(method = "lm", colour = "red", se = TRUE) +
  theme_bw()
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'

# Regresión de deciles
#-----------------------------------
library(quantreg)
modelo_q3 <- rq(formula = y ~ x, tau = c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9), data = datos)
summary(object = modelo_q3, se = "boot")
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.1
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept)   6.96147   7.30674    0.95275   0.34304
## x            -3.62776   0.30239  -11.99699   0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.2
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept)   4.07252   3.17579    1.28236   0.20271
## x            -3.09051   0.22054  -14.01357   0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.3
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept)   4.59184   2.52954    1.81528   0.07251
## x            -2.76074   0.15741  -17.53890   0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.4
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept)   8.43088   4.62566    1.82263   0.07138
## x            -2.62256   0.20420  -12.84307   0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.5
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  7.52970  4.98562    1.51029  0.13416
## x           -2.23182  0.22963   -9.71919  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.6
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept)   6.26312   3.84001    1.63101   0.10606
## x            -2.04362   0.13351  -15.30712   0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.7
## 
## Coefficients:
##             Value     Std. Error t value   Pr(>|t|) 
## (Intercept)  11.34007   3.65457    3.10298   0.00250
## x            -1.99575   0.10283  -19.40738   0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.8
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) 12.27541  8.80110    1.39476  0.16621
## x           -1.87628  0.24648   -7.61239  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.9
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) 20.66961 14.32706    1.44270  0.15226
## x           -1.42548  0.36111   -3.94749  0.00015
ggplot(data = datos, aes(x = x, y = y)) + 
  geom_point()+
  geom_smooth(method = "lm", se = TRUE, color = "red") +
  geom_quantile(quantiles = c(1:9)/10) + 
  theme_bw()
## `geom_smooth()` using formula = 'y ~ x'
## Smoothing formula not specified. Using: y ~ x

plot(summary(rq(y ~ x, tau = c(1:9)/10, data = datos)), parm = "x")
## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

No es lo mismo hacer una regresión cuantílica que hacer una estimación de media con ‘mínimos cuadrados ordinarios’. Vemos que va disminuyendo la renta realmente a medida que aumenta la x.

# Contraste de significación conjunta para saber si hay que hacer regresión cuantílica
#-----------------------------------------------------------------------------------------
modelo_q01 <- rq(formula = y ~x, tau = 0.1, data = datos)
modelo_q02 <- rq(formula = y ~x, tau = 0.2, data = datos)
modelo_q03 <- rq(formula = y ~x, tau = 0.3, data = datos)
modelo_q04 <- rq(formula = y ~x, tau = 0.4, data = datos)
modelo_q05 <- rq(formula = y ~x, tau = 0.5, data = datos)
modelo_q06 <- rq(formula = y ~x, tau = 0.6, data = datos)
modelo_q07 <- rq(formula = y ~x, tau = 0.7, data = datos)
modelo_q08 <- rq(formula = y ~x, tau = 0.8, data = datos)
modelo_q09 <- rq(formula = y ~x, tau = 0.9, data = datos)
anova(modelo_q01, modelo_q02, modelo_q03, modelo_q04, modelo_q05, modelo_q06, modelo_q07, modelo_q08, modelo_q09)
## Warning in summary.rq(x, se = se, R = R, covariance = TRUE): 2 non-positive fis
## Quantile Regression Analysis of Deviance Table
## 
## Model: y ~ x
## Joint Test of Equality of Slopes: tau in {  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9  }
## 
##   Df Resid Df F value    Pr(>F)    
## 1  8      901  8.1955 9.556e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Rechazo H0; por tanto, es preferible la regresión de cuantiles.

#Ejemplo3
# Predictor
x <- seq(0, 100, length.out = 100)
# Intercept y pendiente
b_0 <- 6
b_1 <- 0.5
# Error aleatorio normal
set.seed(1)
error <- rnorm(100, mean = 0, sd = 4)
# Variable respuesta
y <- b_0 + b_1*x + error
datos <- data.frame(x, y)

modelo_ols <- lm(y ~ x, data = datos)
summary(modelo_ols)
## 
## Call:
## lm(formula = y ~ x, data = datos)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -9.360 -2.423  0.062  2.341  9.190 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  6.52486    0.71676   9.103 1.07e-14 ***
## x            0.49821    0.01238  40.233  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.611 on 98 degrees of freedom
## Multiple R-squared:  0.9429, Adjusted R-squared:  0.9423 
## F-statistic:  1619 on 1 and 98 DF,  p-value: < 2.2e-16
#Regresión OLS
ggplot(data = datos, aes(x = x, y =y)) +
  geom_point()+
  geom_smooth(method = "lm", colour = "red", se = TRUE)
## `geom_smooth()` using formula = 'y ~ x'

  theme_bw()
## List of 136
##  $ line                            :List of 6
##   ..$ colour       : chr "black"
##   ..$ linewidth    : num 0.5
##   ..$ linetype     : num 1
##   ..$ lineend      : chr "butt"
##   ..$ arrow        : logi FALSE
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_line" "element"
##  $ rect                            :List of 5
##   ..$ fill         : chr "white"
##   ..$ colour       : chr "black"
##   ..$ linewidth    : num 0.5
##   ..$ linetype     : num 1
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_rect" "element"
##  $ text                            :List of 11
##   ..$ family       : chr ""
##   ..$ face         : chr "plain"
##   ..$ colour       : chr "black"
##   ..$ size         : num 11
##   ..$ hjust        : num 0.5
##   ..$ vjust        : num 0.5
##   ..$ angle        : num 0
##   ..$ lineheight   : num 0.9
##   ..$ margin       : 'margin' num [1:4] 0points 0points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : logi FALSE
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ title                           : NULL
##  $ aspect.ratio                    : NULL
##  $ axis.title                      : NULL
##  $ axis.title.x                    :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 1
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 2.75points 0points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.title.x.top                :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 0
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 0points 2.75points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.title.x.bottom             : NULL
##  $ axis.title.y                    :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 1
##   ..$ angle        : num 90
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 2.75points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.title.y.left               : NULL
##  $ axis.title.y.right              :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 1
##   ..$ angle        : num -90
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.75points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text                       :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : chr "grey30"
##   ..$ size         : 'rel' num 0.8
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.x                     :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 1
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 2.2points 0points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.x.top                 :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : NULL
##   ..$ vjust        : num 0
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 0points 2.2points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.x.bottom              : NULL
##  $ axis.text.y                     :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 1
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 0points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.y.left                : NULL
##  $ axis.text.y.right               :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 0
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.2points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.text.theta                 : NULL
##  $ axis.text.r                     :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 0.5
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 2.2points
##   .. ..- attr(*, "unit")= int 8
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ axis.ticks                      :List of 6
##   ..$ colour       : chr "grey20"
##   ..$ linewidth    : NULL
##   ..$ linetype     : NULL
##   ..$ lineend      : NULL
##   ..$ arrow        : logi FALSE
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_line" "element"
##  $ axis.ticks.x                    : NULL
##  $ axis.ticks.x.top                : NULL
##  $ axis.ticks.x.bottom             : NULL
##  $ axis.ticks.y                    : NULL
##  $ axis.ticks.y.left               : NULL
##  $ axis.ticks.y.right              : NULL
##  $ axis.ticks.theta                : NULL
##  $ axis.ticks.r                    : NULL
##  $ axis.minor.ticks.x.top          : NULL
##  $ axis.minor.ticks.x.bottom       : NULL
##  $ axis.minor.ticks.y.left         : NULL
##  $ axis.minor.ticks.y.right        : NULL
##  $ axis.minor.ticks.theta          : NULL
##  $ axis.minor.ticks.r              : NULL
##  $ axis.ticks.length               : 'simpleUnit' num 2.75points
##   ..- attr(*, "unit")= int 8
##  $ axis.ticks.length.x             : NULL
##  $ axis.ticks.length.x.top         : NULL
##  $ axis.ticks.length.x.bottom      : NULL
##  $ axis.ticks.length.y             : NULL
##  $ axis.ticks.length.y.left        : NULL
##  $ axis.ticks.length.y.right       : NULL
##  $ axis.ticks.length.theta         : NULL
##  $ axis.ticks.length.r             : NULL
##  $ axis.minor.ticks.length         : 'rel' num 0.75
##  $ axis.minor.ticks.length.x       : NULL
##  $ axis.minor.ticks.length.x.top   : NULL
##  $ axis.minor.ticks.length.x.bottom: NULL
##  $ axis.minor.ticks.length.y       : NULL
##  $ axis.minor.ticks.length.y.left  : NULL
##  $ axis.minor.ticks.length.y.right : NULL
##  $ axis.minor.ticks.length.theta   : NULL
##  $ axis.minor.ticks.length.r       : NULL
##  $ axis.line                       : list()
##   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
##  $ axis.line.x                     : NULL
##  $ axis.line.x.top                 : NULL
##  $ axis.line.x.bottom              : NULL
##  $ axis.line.y                     : NULL
##  $ axis.line.y.left                : NULL
##  $ axis.line.y.right               : NULL
##  $ axis.line.theta                 : NULL
##  $ axis.line.r                     : NULL
##  $ legend.background               :List of 5
##   ..$ fill         : NULL
##   ..$ colour       : logi NA
##   ..$ linewidth    : NULL
##   ..$ linetype     : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_rect" "element"
##  $ legend.margin                   : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
##   ..- attr(*, "unit")= int 8
##  $ legend.spacing                  : 'simpleUnit' num 11points
##   ..- attr(*, "unit")= int 8
##  $ legend.spacing.x                : NULL
##  $ legend.spacing.y                : NULL
##  $ legend.key                      : NULL
##  $ legend.key.size                 : 'simpleUnit' num 1.2lines
##   ..- attr(*, "unit")= int 3
##  $ legend.key.height               : NULL
##  $ legend.key.width                : NULL
##  $ legend.key.spacing              : 'simpleUnit' num 5.5points
##   ..- attr(*, "unit")= int 8
##  $ legend.key.spacing.x            : NULL
##  $ legend.key.spacing.y            : NULL
##  $ legend.frame                    : NULL
##  $ legend.ticks                    : NULL
##  $ legend.ticks.length             : 'rel' num 0.2
##  $ legend.axis.line                : NULL
##  $ legend.text                     :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : 'rel' num 0.8
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ legend.text.position            : NULL
##  $ legend.title                    :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : NULL
##   ..$ hjust        : num 0
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi TRUE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ legend.title.position           : NULL
##  $ legend.position                 : chr "right"
##  $ legend.position.inside          : NULL
##  $ legend.direction                : NULL
##  $ legend.byrow                    : NULL
##  $ legend.justification            : chr "center"
##  $ legend.justification.top        : NULL
##  $ legend.justification.bottom     : NULL
##  $ legend.justification.left       : NULL
##  $ legend.justification.right      : NULL
##  $ legend.justification.inside     : NULL
##  $ legend.location                 : NULL
##  $ legend.box                      : NULL
##  $ legend.box.just                 : NULL
##  $ legend.box.margin               : 'margin' num [1:4] 0cm 0cm 0cm 0cm
##   ..- attr(*, "unit")= int 1
##  $ legend.box.background           : list()
##   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
##  $ legend.box.spacing              : 'simpleUnit' num 11points
##   ..- attr(*, "unit")= int 8
##   [list output truncated]
##  - attr(*, "class")= chr [1:2] "theme" "gg"
##  - attr(*, "complete")= logi TRUE
##  - attr(*, "validate")= logi TRUE
# Regresión de deciles
#--------------------------------
library(quantreg)
modelo_q4 <- rq(formula = y ~ x, tau = c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9), data = datos)
summary(object = modelo_q4, se = "boot")
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.1
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  2.68990  2.05876    1.30656  0.19442
## x            0.48395  0.03006   16.09761  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.2
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  3.49418  1.13471    3.07937  0.00269
## x            0.50172  0.01922   26.09970  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.3
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  5.92341  1.10758    5.34805  0.00000
## x            0.47738  0.02017   23.66365  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.4
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  6.12755  0.85652    7.15398  0.00000
## x            0.48810  0.01804   27.05332  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.5
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  6.74025  1.09245    6.16983  0.00000
## x            0.49438  0.01859   26.58875  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.6
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  7.68284  0.82533    9.30886  0.00000
## x            0.49591  0.01549   32.01511  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.7
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  8.41102  0.72995   11.52276  0.00000
## x            0.49815  0.01375   36.22220  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.8
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept)  9.17249  0.90674   10.11587  0.00000
## x            0.49793  0.01961   25.39726  0.00000
## 
## Call: rq(formula = y ~ x, tau = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 
##     0.8, 0.9), data = datos)
## 
## tau: [1] 0.9
## 
## Coefficients:
##             Value    Std. Error t value  Pr(>|t|)
## (Intercept) 10.43941  1.27425    8.19257  0.00000
## x            0.50427  0.02262   22.29470  0.00000
ggplot(data = datos, aes(x = x, y = y)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE, color = "red") +
  geom_quantile(quantiles = c(1:9)/10) +
  theme_bw()
## `geom_smooth()` using formula = 'y ~ x'
## Smoothing formula not specified. Using: y ~ x

plot(summary(rq(y~x, tau = c(1:9)/10, data = datos)), parm = "x")
## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

La inclinación de todos los cuantiles es similar a la de OLS.

# Contraste de significación conjunta para saber si hay que hacer regresión cuantílica
#-----------------------------------------------------------------------------------------
modelo_q01 <- rq(formula = y ~x, tau = 0.1, data = datos)
modelo_q02 <- rq(formula = y ~x, tau = 0.2, data = datos)
modelo_q03 <- rq(formula = y ~x, tau = 0.3, data = datos)
modelo_q04 <- rq(formula = y ~x, tau = 0.4, data = datos)
modelo_q05 <- rq(formula = y ~x, tau = 0.5, data = datos)
modelo_q06 <- rq(formula = y ~x, tau = 0.6, data = datos)
modelo_q07 <- rq(formula = y ~x, tau = 0.7, data = datos)
modelo_q08 <- rq(formula = y ~x, tau = 0.8, data = datos)
modelo_q09 <- rq(formula = y ~x, tau = 0.9, data = datos)
anova(modelo_q01, modelo_q02)
## Quantile Regression Analysis of Deviance Table
## 
## Model: y ~ x
## Joint Test of Equality of Slopes: tau in {  0.1 0.2  }
## 
##   Df Resid Df F value Pr(>F)
## 1  1      199  0.5501 0.4592

Al ser Pr(>F) mayor a 0.05, la inclinación de las ecuaciones del cuantil del 10% y 20% son similares.

anova(modelo_q01, modelo_q02, modelo_q03, modelo_q04, modelo_q05, modelo_q06, modelo_q07, modelo_q08, modelo_q09)
## Quantile Regression Analysis of Deviance Table
## 
## Model: y ~ x
## Joint Test of Equality of Slopes: tau in {  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9  }
## 
##   Df Resid Df F value Pr(>F)
## 1  8      892   0.676  0.713

Las inclinaciones de todos los cuantiles (10%, 20%,…, 90%) son similares.

Da igual hacer regresión de cuantiles que OLS, porque las pendientes son similares.

plot(summary(rq(y~x, tau = c(1:9)/10, data = datos)), parm = 1)
## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

## Warning in rq.fit.br(x, y, tau = tau, ci = TRUE, ...): Solution may be
## nonunique

Las constantes son diferentes para cada cuantil. Obviamente cuantiles inferiores empiezan en valor de Y inferiores. (Esto no es suficiente para hacer regresiones de cuantiles).

3.- BIBLIOGRAFIA

A gentle introduction to quantile regression for ecologists, Brian S. Cade and Barry R. Noon

http://data.library.virginia.edu/getting-started-with-quantile-regression/

Quantile regression in r: a vignette, Roger Koenker