library(tidyverse)
options(scipen = 99)
Cargamos la base de datos. Los datos se obtuvieron de Banco Mundial y se agruparon diversas bases.
El dataset puede descargarse desde aqui.
También puede cargarse desde una query a data.world:
bancomundial <- read.csv(“https://query.data.world/s/owzasudqx4g5a3lqt32ykoudalq3ul”, header=TRUE, stringsAsFactors=TRUE)
bancomundial <- read.csv("data-wb/dataset_bancomundial.csv",
stringsAsFactors = TRUE)
En primer lugar vamos a ver que contienen nuestros datos.
head(bancomundial)
## Country.Name Country.Code Region IncomeGroup year
## 1 American Samoa ASM East Asia & Pacific Upper middle income 1960
## 2 American Samoa ASM East Asia & Pacific Upper middle income 1961
## 3 American Samoa ASM East Asia & Pacific Upper middle income 1962
## 4 American Samoa ASM East Asia & Pacific Upper middle income 1963
## 5 American Samoa ASM East Asia & Pacific Upper middle income 1964
## 6 American Samoa ASM East Asia & Pacific Upper middle income 1965
## pop_total perc_urban_pop pop_in_largest_city GDP_in_USD
## 1 20123 66.211 NA NA
## 2 20602 66.641 NA NA
## 3 21253 67.068 NA NA
## 4 22034 67.493 NA NA
## 5 22854 67.916 NA NA
## 6 23672 68.334 NA NA
summary(bancomundial)
## Country.Name Country.Code Region
## Afghanistan : 61 ABW : 61 East Asia & Pacific :2257
## Albania : 61 AFG : 61 Europe & Central Asia :3538
## Algeria : 61 AGO : 61 Latin America & Caribbean :2562
## American Samoa: 61 ALB : 61 Middle East & North Africa:1281
## Andorra : 61 AND : 61 North America : 183
## Angola : 61 ARE : 61 South Asia : 488
## (Other) :12871 (Other):12871 Sub-Saharan Africa :2928
## IncomeGroup year pop_total
## High income :5002 Min. :1960 Min. : 3893
## Low income :1769 1st Qu.:1975 1st Qu.: 468584
## Lower middle income:3050 Median :1990 Median : 4133322
## Upper middle income:3416 Mean :1990 Mean : 24335531
## 3rd Qu.:2005 3rd Qu.: 13226839
## Max. :2020 Max. :1397715000
## NA's :326
## perc_urban_pop pop_in_largest_city GDP_in_USD
## Min. : 2.077 Min. : 5254 Min. : 8824448
## 1st Qu.: 30.185 1st Qu.: 519169 1st Qu.: 1409873950
## Median : 50.258 Median : 1136880 Median : 7480968858
## Mean : 51.131 Mean : 2618042 Mean : 173953217878
## 3rd Qu.: 71.755 3rd Qu.: 2658965 3rd Qu.: 49745088112
## Max. :100.000 Max. :37468302 Max. :21433226000000
## NA's :345 NA's :4125 NA's :3352
¿Qué vemos?
Hay 61 observaciones por país, cada una de ellas corresponde a un año. Los años van desde 1960 a 2020. El país con menos habitantes de la muestra tuvo 3.893hab, y el país más habitado contó con 1.397.715.000hab. El porcentaje de población urbana promedio es 50.258%, mientras existe algún país con 100% de población urbana.
Veamos cuales son las regiones:
table(bancomundial$Region)
##
## East Asia & Pacific Europe & Central Asia
## 2257 3538
## Latin America & Caribbean Middle East & North Africa
## 2562 1281
## North America South Asia
## 183 488
## Sub-Saharan Africa
## 2928
Ahora, vamos a crear una variable que sea PBI (GDP) per capita (anual)
datos <- bancomundial %>%
mutate(GDP_per_capita = GDP_in_USD / pop_total)
summary(datos$GDP_per_capita)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 34.79 559.00 1954.24 8583.15 8050.54 189422.22 3355
El PBI per cápita mínimo es apróximadamente 245 veces más chico que el promedio.
¿Cómo se relaciona la población con el porcentaje de población urbana?
Para esto, vamos a usar un gráfico de scatterplot (o gráfico de puntos).
datos %>%
ggplot() +
geom_point(aes(y = perc_urban_pop, x = pop_total, color = Region), alpha = 0.6) +
labs(title = "Correlación entre el porcentaje de población urbana y la población total",
x= "Población total (en millones)",
y = "Población urbana (%)") +
scale_x_continuous(labels = c(250, 500,750,1000, 1250),breaks = 10^6 *c(250, 500,750,1000, 1250)) +
theme_light()
## Warning: Removed 446 rows containing missing values (geom_point).
Vemos que hay dos países (probablemente sean India y China) que, por su población, distorcionan el gráfico. La gran mayoría de los países tienen menos de 250 millones de habitantes.
Vamos a analizar las regiones como conjunto. Para ello, vamos a generar un nuevo dataset agrupando las regiones.
Previamente, necesitamos agregar nuevos campos para poder obtener los resultados por región.
datos <- datos %>%
mutate(urban_pop = round(perc_urban_pop*pop_total/100, digits = 0))
Ahora si, vamos a obtener los datos por región:
datos.region <- datos%>%
group_by(year, Region) %>%
summarise(pop_total = sum(pop_total, na.rm = TRUE), #sumamos población total de la región
urban_pop = sum(urban_pop, na.rm = TRUE), #sumamos población urbana de la región
perc_urban_pop = round(urban_pop/pop_total*100, digits = 2), #obtenemos el % de población urbana
GDP_in_USD = sum(GDP_in_USD, na.rm = TRUE), #sumamos el PBI total de la región
GDP_per_capita = round(GDP_in_USD/pop_total)) #obtenemos el PBI per capita de la región
## `summarise()` regrouping output by 'year' (override with `.groups` argument)
head(datos.region)
## # A tibble: 6 x 7
## # Groups: year [1]
## year Region pop_total urban_pop perc_urban_pop GDP_in_USD GDP_per_capita
## <int> <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1960 East Asia … 1.03e9 231615684 22.5 1.46e11 142
## 2 1960 Europe & C… 6.60e8 368034505 55.8 2.79e11 422
## 3 1960 Latin Amer… 2.20e8 108735965 49.5 5.74e10 261
## 4 1960 Middle Eas… 1.05e8 36736033 34.9 1.14e10 108
## 5 1960 North Amer… 1.99e8 138875014 69.9 5.84e11 2939
## 6 1960 South Asia 5.73e8 95913995 16.7 4.75e10 83
Veamos el scatterplot.
datos.region %>%
ggplot() +
geom_point(aes(y = perc_urban_pop, x = pop_total, color = Region), alpha = 0.6) +
labs(title = "Correlación entre el porcentaje de población urbana y la población total",
subtitle = "Por regiones",
color = "Región",
x= "Población total (en millones)",
y = "Población urbana (%)") +
scale_x_continuous(labels = seq(0,2500,200),breaks = 10^6 *seq(0,2500,200)) +
theme_light()
## Warning: Removed 7 rows containing missing values (geom_point).
Vemos que cada región tiene un comportamiento distinto. A continuación queremos evaluar la relación entre la población total y el porcentaje de población urbana en América Latina.
¿Cómo se relaciona la población total de América Latina (variable explicativa) con el porcentaje de población urbana en el continente según cada año?
Vamos a filtrar los datos de datos.region en América Latina.
datos.latam <- datos.region %>%
filter(Region == "Latin America & Caribbean")
head(datos.latam)
## # A tibble: 6 x 7
## # Groups: year [6]
## year Region pop_total urban_pop perc_urban_pop GDP_in_USD GDP_per_capita
## <int> <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1960 Latin Amer… 219825927 108735965 49.5 5.74e10 261
## 2 1961 Latin Amer… 225909659 113558251 50.3 6.08e10 269
## 3 1962 Latin Amer… 232179886 118597846 51.1 9.40e10 405
## 4 1963 Latin Amer… 238608947 123826704 51.9 9.48e10 397
## 5 1964 Latin Amer… 245143683 129227573 52.7 1.06e11 431
## 6 1965 Latin Amer… 251756122 134636970 53.5 1.14e11 453
Vamos a realizar nuevamente un gráfico de puntos o scatterplot. En el eje x, vamos a colocar nuestra variable explicativa (población total) y en el eje y colocaremos la variable que queremos explicar (porcentaje de población urbana)
datos.latam %>%
ggplot() +
geom_point(aes(y = perc_urban_pop, x = pop_total)) +
labs(title = "Correlación entre el porcentaje de población urbana y la población total",
subtitle = "En América Latina",
x= "Población total (en millones)",
y = "Población urbana (%)") +
scale_x_continuous(labels = c(200, 400, 600),breaks = 10^6 *c(200, 400, 600) )+
theme_light()
## Warning: Removed 1 rows containing missing values (geom_point).
Vemos que existe una relación positiva entre la población total en América Latina y la tasa de población urbana en la región.
Con el objetivo de analizar la relación entre nuestras variables, vamos a armar un modelo estádistico a partir de una regresión lineal. En R, vamos a usar la función lm() (por “linear model”).
lm1 <- lm(data = datos.latam, perc_urban_pop ~ pop_total )
Con el símbolo ~ estamos pidiendo a la función que evalúe perc_urban_pop, nuestra variable dependiente o a explicar, a partir (o versus) pop_total, nuestra variable explicativa o independiente.
Veamos el efecto que tiene la población total sobre el porcentaje de población urbana en América Latina.
lm1
##
## Call:
## lm(formula = perc_urban_pop ~ pop_total, data = datos.latam)
##
## Coefficients:
## (Intercept) pop_total
## 37.28021838891 0.00000007151
Recordemos como se expresaba la formula de una regresión lineal simple.
\(y_{i} = \beta_{0} + \beta_{1} X_{1} + \epsilon\)
Entonces, de acuerdo a nuestros coeficientes, tendríamos:
\(y_{i} = 37.28021838891 + 0.00000007151 X_{pop.total} + \epsilon\)
¿Qué significa esto?
Que por cada incremento de 1 en la población total, hay un incremento de 0.00000007151 en el porcentaje de población urbana.
Dicho de otra manera, por cada incremento de 1.000.000 de personas en la población total, hay un incremento de 0.07151 en el porcentaje de población urbana.
Vemos como se grafica nuestro modelo:
Recordemos que la regresión lineal puede ser modelada en este caso con una línea
datos.latam %>%
ggplot() +
geom_abline(aes(intercept= 37.28021838891 , slope = 0.00000007151), color = "red", linetype = "dashed") +
geom_point(aes(y = perc_urban_pop, x = pop_total)) +
labs(title = "Correlación entre el porcentaje de población urbana y el PBI per capita",
x= "Población total (en millones)",
y = "Población urbana (%)") +
scale_x_continuous(labels = c(200, 400, 600),breaks = 10^6 *c(200, 400, 600) )+
theme_light()
## Warning: Removed 1 rows containing missing values (geom_point).
Podemos observar que si bien nuestro modelo está relacionado con los datos, no coincide perfectamente. ¿Qué tan bien se desempeña nuestro modelo?
Para ello vamos a usar la función summary().
summary(lm1)
##
## Call:
## lm(formula = perc_urban_pop ~ pop_total, data = datos.latam)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.5398 -1.2617 0.3349 1.4382 1.8408
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 37.28021838891 0.71371004550 52.23 <0.0000000000000002 ***
## pop_total 0.00000007151 0.00000000157 45.55 <0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.583 on 58 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.9728, Adjusted R-squared: 0.9723
## F-statistic: 2075 on 1 and 58 DF, p-value: < 0.00000000000000022
¿Qué podemos deducir?
El r-squared (o R2) tiene un valor de 0.9728. Esta métrica varía de 0 a 1, y permite entender que tan bien nuestro modelo ajusta a las observaciones. En este caso, tenemos un R2 muy alto, con lo cual es mucho lo que nuestro modelo explica. Además el pvalor para la variable pop_total es muy bajo, es decir que la variable es significativamente estadística.
Como conclusión, hay una fuerta correlación entre las variables pop_total y perc_urban_pop (según el p-valor), y además nuestro modelo ajusta bien a los datos (según R2).
Vimos que si bien nuestro modelo es bastante explicativo, también creemos que el PBI per capita de América Latina influye en el porcentaje de población urbana.
Queremos incorporar la variable GDP_per_capita a nuestro modelo de regresión lineal. ¿Cómo se hace? ¡Es muy fácil! Simplemente tenemos que agregar la variable al modelo.
lm2 <- lm(data = datos.latam, perc_urban_pop ~ pop_total + GDP_per_capita)
Con el símbolo + agregamos una variable explicativa más, en este caso GDP_per_capita
Vamos a ver los resultados de nuestro modelo.
lm2
##
## Call:
## lm(formula = perc_urban_pop ~ pop_total + GDP_per_capita, data = datos.latam)
##
## Coefficients:
## (Intercept) pop_total GDP_per_capita
## 32.21658144028 0.00000009047 -0.00087414338
La fórmula para una regresión lineal múltiple es la siguiente:
\(y_{i} = \beta_{0} + \beta_{1} X_{1} + \beta_{2} X_{2} + \epsilon\)
Entonces, de acuerdo a nuestros coeficientes, tendríamos:
\(y_{i} = 32.21658144028 + 0.00000009047 X_{pop.total} -0.00087414338 X_{GDP.per.capita } + \epsilon\)
¿Qué significa esto?
La población sigue teniendo un efecto positivo: por cada incremento de 1.000.000 de personas en América Latina, el porcentaje de población urbana aumenta de 0.09047.
El PBI per capita parecería tener un efecto negativo: por cada incremento de 1000 USD en el PBI per capita, el porcentaje de población urbana disminuye de 0.8741.
Veamos que tan bien se desempeñó nuestro modelo.
summary(lm2)
##
## Call:
## lm(formula = perc_urban_pop ~ pop_total + GDP_per_capita, data = datos.latam)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.8091 -0.9458 0.5530 0.8425 1.8199
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 32.216581440279 0.932952868194 34.532 < 0.0000000000000002 ***
## pop_total 0.000000090466 0.000000003086 29.316 < 0.0000000000000002 ***
## GDP_per_capita -0.000874143379 0.000131331421 -6.656 0.0000000119 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.198 on 57 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.9847, Adjusted R-squared: 0.9842
## F-statistic: 1834 on 2 and 57 DF, p-value: < 0.00000000000000022
Al incorporar una segunda variable observamos:
- Las dos variables: pop_total y GDP_per_capita son significativas.
- El R2 es aún mayor, nuestro modelo se ajusta mejora a la realidad.
En el segundo gráfico pudimos observar que la relación entre la población total y el porcentaje de población urbana estaba fuertemente diferenciado por región.
La regresión lineal permite utilizar como variable explicativa una variable categórica. ¿Cómo funciona? Se crea una variable binaria (dummy) que indica si pertenece o no a esa categoría, y cual es el efecto de pertenecer a esa categoría.
Como vimos antes, las regiones están compuestas por 7 categorías. Entonces nuestro modelo de regresión quedaría así:
- EAP = East Asia & Pacific
- ECA = Europe & Central Asia
- LAC = Latin America & Caribbean
- MENA = Middle East & North Africa
- NA = North America
- SA = South Asia
- SSA = Sub-Saharan Africa
\(y_{i} = \beta_{0} + \beta_{EAP} X_{EAP} + \beta_{ECA} X_{ECA} + \beta_{LAC} X_{LAC} + \beta_{MENA} X_{MENA} + \beta_{NA} X_{NA} + \beta_{SA} X_{SA}+ \beta_{SSA} X_{SSA} +\epsilon\)
Donde los \(\beta_{i}\) toman el valor del efecto y los \(X_{i}\) adoptan valor 1 o 0 si se encuentran en esa región.
Ahora corramos nuestro modelo para evaluar la relación entre porcentaje de población urbana y la región donde se encuentran.
lm3 <- lm(data = datos.region, perc_urban_pop ~ Region)
lm3
##
## Call:
## lm(formula = perc_urban_pop ~ Region, data = datos.region)
##
## Coefficients:
## (Intercept) RegionEurope & Central Asia
## 36.41 29.65
## RegionLatin America & Caribbean RegionMiddle East & North Africa
## 32.02 16.54
## RegionNorth America RegionSouth Asia
## 40.05 -11.59
## RegionSub-Saharan Africa
## -9.46
¿Qué significa?
Lo primero que observamos es que no están nuestras 7 regiones, falta East Asia & Pacific. Esto ocurre porque el modelo toma la primer región (alfabéticamente) como línea de base. Es decir, si la categoría Region es East Asia & Pacific entonces el porcentaje de población urbana sería 36.41%. En caso de corresponder la categoría South Asia tendrías un porcentaje de población urbana de 26.95 (36.41-9.46).
Volviendo a nuestro modelo, la regresión tendría la siguiente ecuación:
\(y_{i} = 36.41 + 29.65 X_{ECA} + 32.02 X_{LAC} + 16.54X_{MENA} + 40.05X_{NA} -11.592X_{SA} -9.46X_{SSA} +\epsilon\)
Las variables X (dummies) solo se activan 1 vez (en la categoría de corresponde) o ninguna (para la categoría East Asia & Pacific). Para las demás \(X_{i}\), el valor que adopta es 0.
Nota: Con la función relevel(factor, ref) podríamos modificar el nivel de referencia y remplazar East Asia & Pacific por otra categoría.
Veamos ahora los resultados del modelo.
summary(lm3)
##
## Call:
## lm(formula = perc_urban_pop ~ Region, data = datos.region)
##
## Residuals:
## Min 1Q Median 3Q Max
## -18.9688 -5.4098 0.4153 5.1152 23.2945
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) 36.406 1.007 36.165
## RegionEurope & Central Asia 29.649 1.424 20.826
## RegionLatin America & Caribbean 32.023 1.424 22.494
## RegionMiddle East & North Africa 16.543 1.424 11.620
## RegionNorth America 40.051 1.424 28.133
## RegionSouth Asia -11.595 1.424 -8.144
## RegionSub-Saharan Africa -9.460 1.424 -6.645
## Pr(>|t|)
## (Intercept) < 0.0000000000000002 ***
## RegionEurope & Central Asia < 0.0000000000000002 ***
## RegionLatin America & Caribbean < 0.0000000000000002 ***
## RegionMiddle East & North Africa < 0.0000000000000002 ***
## RegionNorth America < 0.0000000000000002 ***
## RegionSouth Asia 0.00000000000000456 ***
## RegionSub-Saharan Africa 0.00000000009582287 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.798 on 413 degrees of freedom
## (7 observations deleted due to missingness)
## Multiple R-squared: 0.8639, Adjusted R-squared: 0.8619
## F-statistic: 436.9 on 6 and 413 DF, p-value: < 0.00000000000000022
Con la variable categórica Region observamos que:
- Todas las regiones son estadísticamente significativas.
- El R2 es de 0.8639, nuestro modelo ajusta muy bien, pero los modelos anteriores ajustaban mejor.
Sería interesante realizar un modelo de regresión lineal múltiple incorporando otras variables de nuestro dataset, como el año o la población de la ciudad más grande o el GroupIncome (categoría del Banco Mundial) al que pertenecen. ¡Prueben hacerlo!