if (!require("pacman")) install.packages("pacman") # instala pacman si se requiere
## Loading required package: pacman
pacman::p_load(tidyverse,
readxl,writexl,googlesheets4, # importar hojas de cálculo
haven, foreign, # importación de dta y sav
sjlabelled, # etiquetas
janitor, skimr, #limpieza y verificación
imputeTS, # para imputar valores
srvyr, # Para el diseño muestral
esquisse, # para usar ggplot de manera más amigable
#DescTools, # Paquete para estimaciones y pruebas
#infer, # tidy way
#broom, # Una escobita para limpiar (pero es para arreglar)
#estimatr, car, stargazer, ggpubr, # Para la regresión práctica 7
#jtools, lm.beta, robustbase, sandwich, effects,
#officer,flextable,huxtable, ggstance, kableExtra, # Para la regresión práctica 8
#ResourceSelection, lmtest, mlogit, nnet # Práctica 9
apyramid)
En caso que no tengas un proyecto,establecer el directorio puede ayudar
rm(list=ls()) # mala práctica pero quizás necesaria porque vamos a cambiar de tema
setwd("/Users/anaescoto/Dropbox/2020/2021-1 R para Demográfos/repo/R_Demo")
Vamos a trabajar con las proyecciones de CONAPO. No son microdatos, sino que están agregados.
pob_mit_proyecciones <- read.csv("https://github.com/aniuxa/R_Demo/raw/master/datos/pob_mit_proyecciones.csv", encoding = "latin1")
Son las poblaciones a mitad de julio de CONAPO (podríamos descargarlas directamente, pero yo estoy vetada)
Vamos a limpiar los nombres:
pob_mit_proyecciones<-clean_names(pob_mit_proyecciones)
Base de ECOVID - ML
ecovid0420 <- read_dta("https://github.com/aniuxa/R_Demo/raw/master/datos/ecovid0420.dta")
Revisemos esta base de datos de las proyecciones de población.
skimr::skim(pob_mit_proyecciones)
Name | pob_mit_proyecciones |
Number of rows | 592460 |
Number of columns | 7 |
_______________________ | |
Column type frequency: | |
character | 2 |
numeric | 5 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
entidad | 0 | 1 | 6 | 19 | 0 | 33 | 0 |
sexo | 0 | 1 | 7 | 7 | 0 | 2 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
renglon | 0 | 1 | 296230.50 | 171028.61 | 1 | 148115.8 | 296230.5 | 444345.2 | 592460 | ▇▇▇▇▇ |
ano | 0 | 1 | 2009.62 | 23.70 | 1950 | 1989.0 | 2010.0 | 2030.0 | 2050 | ▁▇▇▇▇ |
cve_geo | 0 | 1 | 15.88 | 9.59 | 0 | 8.0 | 16.0 | 24.0 | 32 | ▇▆▇▆▇ |
edad | 0 | 1 | 54.50 | 31.75 | 0 | 27.0 | 54.5 | 82.0 | 109 | ▇▇▇▇▇ |
poblacion | 0 | 1 | 31142.55 | 113815.57 | 0 | 1353.0 | 8429.0 | 23210.0 | 1198088 | ▇▁▁▁▁ |
La edad y sexo son de las variables más importantes en la demografía para explicar la estructura de una población. Las pirámides son parte esencial de lo que llamamos “Demografía estática”
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
count(edad, sexo, wt=poblacion)
## edad sexo n
## 1 0 Hombres 1087447
## 2 0 Mujeres 1048275
## 3 1 Hombres 1093379
## 4 1 Mujeres 1054636
## 5 2 Hombres 1100800
## 6 2 Mujeres 1061974
## 7 3 Hombres 1108402
## 8 3 Mujeres 1069224
## 9 4 Hombres 1114769
## 10 4 Mujeres 1075251
## 11 5 Hombres 1119479
## 12 5 Mujeres 1079856
## 13 6 Hombres 1122374
## 14 6 Mujeres 1082945
## 15 7 Hombres 1123921
## 16 7 Mujeres 1084339
## 17 8 Hombres 1125153
## 18 8 Mujeres 1085091
## 19 9 Hombres 1126053
## 20 9 Mujeres 1086065
## 21 10 Hombres 1127584
## 22 10 Mujeres 1087661
## 23 11 Hombres 1129609
## 24 11 Mujeres 1089876
## 25 12 Hombres 1131125
## 26 12 Mujeres 1091850
## 27 13 Hombres 1132647
## 28 13 Mujeres 1093043
## 29 14 Hombres 1134624
## 30 14 Mujeres 1094700
## 31 15 Hombres 1135375
## 32 15 Mujeres 1096156
## 33 16 Hombres 1132192
## 34 16 Mujeres 1094702
## 35 17 Hombres 1125251
## 36 17 Mujeres 1090828
## 37 18 Hombres 1117509
## 38 18 Mujeres 1087223
## 39 19 Hombres 1109641
## 40 19 Mujeres 1083771
## 41 20 Hombres 1102086
## 42 20 Mujeres 1079684
## 43 21 Hombres 1096148
## 44 21 Mujeres 1075574
## 45 22 Hombres 1091600
## 46 22 Mujeres 1072730
## 47 23 Hombres 1087899
## 48 23 Mujeres 1072186
## 49 24 Hombres 1085130
## 50 24 Mujeres 1073520
## 51 25 Hombres 1082381
## 52 25 Mujeres 1074674
## 53 26 Hombres 1076872
## 54 26 Mujeres 1072980
## 55 27 Hombres 1067297
## 56 27 Mujeres 1068216
## 57 28 Hombres 1053499
## 58 28 Mujeres 1061332
## 59 29 Hombres 1034307
## 60 29 Mujeres 1051403
## 61 30 Hombres 1011472
## 62 30 Mujeres 1039180
## 63 31 Hombres 988604
## 64 31 Mujeres 1027221
## 65 32 Hombres 965801
## 66 32 Mujeres 1015218
## 67 33 Hombres 942390
## 68 33 Mujeres 1002010
## 69 34 Hombres 919305
## 70 34 Mujeres 988221
## 71 35 Hombres 896592
## 72 35 Mujeres 974208
## 73 36 Hombres 873907
## 74 36 Mujeres 959980
## 75 37 Hombres 851872
## 76 37 Mujeres 945900
## 77 38 Hombres 831435
## 78 38 Mujeres 932221
## 79 39 Hombres 813363
## 80 39 Mujeres 919070
## 81 40 Hombres 798429
## 82 40 Mujeres 906932
## 83 41 Hombres 786879
## 84 41 Mujeres 896078
## 85 42 Hombres 778434
## 86 42 Mujeres 886410
## 87 43 Hombres 772787
## 88 43 Mujeres 877830
## 89 44 Hombres 769375
## 90 44 Mujeres 870050
## 91 45 Hombres 764980
## 92 45 Mujeres 860137
## 93 46 Hombres 757394
## 94 46 Mujeres 846516
## 95 47 Hombres 746793
## 96 47 Mujeres 830179
## 97 48 Hombres 732815
## 98 48 Mujeres 811113
## 99 49 Hombres 715821
## 100 49 Mujeres 789955
## 101 50 Hombres 696964
## 102 50 Mujeres 767549
## 103 51 Hombres 677054
## 104 51 Mujeres 744410
## 105 52 Hombres 656393
## 106 52 Mujeres 721093
## 107 53 Hombres 635666
## 108 53 Mujeres 698207
## 109 54 Hombres 615300
## 110 54 Mujeres 676110
## 111 55 Hombres 595239
## 112 55 Mujeres 654659
## 113 56 Hombres 575163
## 114 56 Mujeres 633454
## 115 57 Hombres 554862
## 116 57 Mujeres 612236
## 117 58 Hombres 534116
## 118 58 Mujeres 590710
## 119 59 Hombres 512657
## 120 59 Mujeres 568495
## 121 60 Hombres 490368
## 122 60 Mujeres 545388
## 123 61 Hombres 467264
## 124 61 Mujeres 521365
## 125 62 Hombres 443508
## 126 62 Mujeres 496619
## 127 63 Hombres 419402
## 128 63 Mujeres 471502
## 129 64 Hombres 395342
## 130 64 Mujeres 446438
## 131 65 Hombres 371668
## 132 65 Mujeres 421793
## 133 66 Hombres 348231
## 134 66 Mujeres 397629
## 135 67 Hombres 325584
## 136 67 Mujeres 373826
## 137 68 Hombres 303653
## 138 68 Mujeres 350451
## 139 69 Hombres 281962
## 140 69 Mujeres 327678
## 141 70 Hombres 263044
## 142 70 Mujeres 307972
## 143 71 Hombres 245905
## 144 71 Mujeres 289911
## 145 72 Hombres 228560
## 146 72 Mujeres 271286
## 147 73 Hombres 212000
## 148 73 Mujeres 253512
## 149 74 Hombres 196198
## 150 74 Mujeres 236526
## 151 75 Hombres 181139
## 152 75 Mujeres 220312
## 153 76 Hombres 166687
## 154 76 Mujeres 204682
## 155 77 Hombres 152868
## 156 77 Mujeres 189639
## 157 78 Hombres 140048
## 158 78 Mujeres 175607
## 159 79 Hombres 127762
## 160 79 Mujeres 162010
## 161 80 Hombres 115671
## 162 80 Mujeres 148399
## 163 81 Hombres 104116
## 164 81 Mujeres 135195
## 165 82 Hombres 93281
## 166 82 Mujeres 122638
## 167 83 Hombres 83179
## 168 83 Mujeres 110754
## 169 84 Hombres 73767
## 170 84 Mujeres 99478
## 171 85 Hombres 65042
## 172 85 Mujeres 88823
## 173 86 Hombres 56978
## 174 86 Mujeres 78763
## 175 87 Hombres 49511
## 176 87 Mujeres 69250
## 177 88 Hombres 42618
## 178 88 Mujeres 60304
## 179 89 Hombres 36260
## 180 89 Mujeres 51906
## 181 90 Hombres 30398
## 182 90 Mujeres 44050
## 183 91 Hombres 25043
## 184 91 Mujeres 36758
## 185 92 Hombres 20354
## 186 92 Mujeres 30268
## 187 93 Hombres 16274
## 188 93 Mujeres 24515
## 189 94 Hombres 12786
## 190 94 Mujeres 19504
## 191 95 Hombres 9901
## 192 95 Mujeres 15288
## 193 96 Hombres 7502
## 194 96 Mujeres 11723
## 195 97 Hombres 5550
## 196 97 Mujeres 8762
## 197 98 Hombres 4001
## 198 98 Mujeres 6372
## 199 99 Hombres 2797
## 200 99 Mujeres 4498
## 201 100 Hombres 1895
## 202 100 Mujeres 3074
## 203 101 Hombres 1243
## 204 101 Mujeres 2030
## 205 102 Hombres 784
## 206 102 Mujeres 1291
## 207 103 Hombres 478
## 208 103 Mujeres 789
## 209 104 Hombres 277
## 210 104 Mujeres 459
## 211 105 Hombres 154
## 212 105 Mujeres 257
## 213 106 Hombres 80
## 214 106 Mujeres 135
## 215 107 Hombres 48
## 216 107 Mujeres 70
## 217 108 Hombres 20
## 218 108 Mujeres 30
## 219 109 Hombres 10
## 220 109 Mujeres 14
Podemos pensar en las pirámides como un doble histograma
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
ggplot(
aes(edad, weight=poblacion)
) + geom_histogram(binwidth = 5)
Tendríamos que darle la vuelta para verle más el parecido
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
ggplot(
aes(edad, weight=poblacion)
) + geom_histogram(binwidth = 5) + # verificar el ancho de clase
coord_flip()
Si queremos hacerlo como gráficos de barra, seguramente queremos cortar la variable de edad. Igual este paso es esencial en la vida demográfica:
pob_mit_proyecciones<-pob_mit_proyecciones %>%
mutate(eda5=cut(edad, # la variable a cortar
breaks=seq(0,110, # El rango válido
by=5), # El ancho del intervalo
include.lowest=T, # para que incluya el valor más bajo dentro del intervalo
right=F)) # indica si el intervalo irá abierto en la derecha, ponemos un no con "FALSE"
Veamos esta variable:
pob_mit_proyecciones %>% count(eda5, wt=poblacion)
## eda5 n
## 1 [0,5) 1850369450
## 2 [5,10) 1798397314
## 3 [10,15) 1740546022
## 4 [15,20) 1650518583
## 5 [20,25) 1528556801
## 6 [25,30) 1415601789
## 7 [30,35) 1311311827
## 8 [35,40) 1208943818
## 9 [40,45) 1105462886
## 10 [45,50) 998015168
## 11 [50,55) 885777598
## 12 [55,60) 767255276
## 13 [60,65) 644700229
## 14 [65,70) 522585219
## 15 [70,75) 402225474
## 16 [75,80) 285455139
## 17 [80,85) 180727873
## 18 [85,90) 97828264
## 19 [90,95) 41841611
## 20 [95,100) 12408739
## 21 [100,105) 2052151
## 22 [105,110] 132230
### gráfico de barras de edades quinquenales
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
ggplot(aes(eda5, weights=poblacion))+
geom_bar() # dibuja la geometría de barra
Una pirámide es un histograma por sexo, donde el valor de los hombres es negativo:
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
mutate(poblacion=if_else(sexo=="Hombres", -poblacion, poblacion)) %>%
ggplot(aes(eda5, fill=sexo, weights=poblacion))+
geom_bar() # dibuja la geometría de barra
Podemos darle la vuelta y cambiarle los colores
pob_mit_proyecciones<-pob_mit_proyecciones %>%
mutate(poblacion2=if_else(sexo=="Hombres", -poblacion, poblacion))
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
ggplot(aes(eda5, fill=sexo, weights=poblacion2))+
geom_bar() + coord_flip() +
scale_fill_brewer(palette = "Set2") +
theme_light() + theme(axis.text.x = element_text(angle = 90))
Como que las escalas tampoco están muy perfectas y no queremos las negativa.¡Los hombres no son personas negativas!
Veamos un poco cómo se comporta esa variable:
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
count(eda5, sexo, wt=poblacion2) %>%
summarise(max=max(n), min=min(n))
## max min
## 1 5457130 -5655589
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
ggplot(aes(eda5, fill=sexo, weights=poblacion2))+
geom_bar() + coord_flip() +
scale_y_continuous(breaks = seq(-6000000, 6000000, by=1000000), # cuántos
limits = c(-6000000,6000000),
labels = paste0(
as.character(c(6:0,# sustituye negativos
1:6) # Para lo positivo
)
)
)+
labs(y="Poblacion - millones", x="Grupos de edad") +
scale_fill_brewer(palette = "Set2") +
theme_light() + theme(axis.text.x = element_text(angle = 90))
Esto es para el volumen de la población ¿Cómo podemos hacer una pirámide que sea en términos de proporciones?
Vamos a necesitar el total de la población:
pob_mit_proyecciones<-pob_mit_proyecciones %>%
group_by(cve_geo, ano) %>%
mutate(p_edo=sum(poblacion)) %>%
ungroup()
head(pob_mit_proyecciones)
## # A tibble: 6 x 10
## renglon ano entidad cve_geo edad sexo poblacion eda5 poblacion2 p_edo
## <int> <int> <chr> <int> <int> <chr> <int> <fct> <int> <int>
## 1 1 1950 República… 0 0 Homb… 572103 [0,5) -572103 2.70e7
## 2 2 1950 República… 0 0 Muje… 559162 [0,5) 559162 2.70e7
## 3 3 1950 República… 0 1 Homb… 514540 [0,5) -514540 2.70e7
## 4 4 1950 República… 0 1 Muje… 505269 [0,5) 505269 2.70e7
## 5 5 1950 República… 0 2 Homb… 478546 [0,5) -478546 2.70e7
## 6 6 1950 República… 0 2 Muje… 469322 [0,5) 469322 2.70e7
Hoy sí haremos lo mismo pero para las proporciones:
pob_mit_proyecciones<-pob_mit_proyecciones %>%
mutate(poblacion3=if_else(sexo=="Hombres", -poblacion/p_edo, poblacion/p_edo))
Una vez que ya tenemos nuestra variable proporcional:
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
ggplot(aes(eda5, fill=sexo, weights=poblacion3))+
geom_bar() + coord_flip() +
scale_y_continuous(labels = scales::percent_format(accuracy=0.01))+
labs(y="Poblacion - %", x="Grupos de edad") +
scale_fill_brewer(palette = "Set2") +
theme_light() + theme(axis.text.x = element_text(angle = 90))
Podemos hacer varias pirámides aplicando facets o grids:
pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano%in%seq(2020,2050, by=10)) %>%
ggplot(aes(eda5, fill=sexo, weights=poblacion3))+
geom_bar() + coord_flip() +
scale_y_continuous(labels = scales::percent_format(accuracy=0.01))+
labs(y="Poblacion - %", x="Grupos de edad") +
scale_fill_brewer(palette = "Set2") +
theme_light() + theme(axis.text.x = element_text(angle = 90)) +
facet_wrap(~ano)
Para procedimientos muy rutinarios, podemos hacer funciones
mi_funcion<-function(x) {
x<-x+1
x
}
mi_funcion(5)
## [1] 6
Podemos complicarla:
mi_funcion<-function(x,a) {
x<-x+a
x
}
mi_funcion(5,2)
## [1] 7
Así que podemos hacer una función de pirámide:
piramide<-function(ent, ano) {
x<-ent
a<-ano
pob_mit_proyecciones %>%
filter(cve_geo==x) %>%
filter(ano==a) %>%
ggplot(aes(eda5, fill=sexo, weights=poblacion3))+
geom_bar() + coord_flip() +
scale_y_continuous(labels = scales::percent_format(accuracy=0.01))+
labs(y="Poblacion - %", x="Grupos de edad") +
scale_fill_brewer(palette = "Set2") +
theme_light()
}
Veamos si funciona:
piramide(1, 1990)
piramide(12, 2050)
Vamos a hacer un ejemplo de edad simple, y de cómo hacemos cuando los datos no están agrupados. Lo más fácil para volver negativos a los hombres es crear una nueva variable
ecovid0420 %>%
mutate(dummy=if_else(pb1==1,
-1,
1)) %>%
ggplot(aes(pb2,
fill=as_label(pb1),
weights=dummy))+
geom_histogram(binwidth = 5) + coord_flip()
## Warning: Removed 25 rows containing non-finite values (stat_bin).
Necesita que tengamos los datos quinquenales No acepta funciones en las variables edad y sexo
pira <- pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
age_pyramid(eda5, # edad
split_by = sexo,
count=poblacion) # sexo
pira + theme_minimal()
Nos ahorra un par de pasos, pero siempre tenemos que solucionar algunos elemtnos
pira <- pob_mit_proyecciones %>%
filter(cve_geo==0) %>%
filter(ano==2020) %>%
age_pyramid(eda5, # edad
split_by = sexo,
count=poblacion) # sexo
pira + theme_minimal()
Un paquete en desarrollo
#if (!require("devtools")) {
# install.packages("devtools")
# }
#devtools::install_github("diegovalle/mxmaps")
library(mxmaps)
Índice de competitividad estatal (no internacional)
url <- "https://github.com/aniuxa/R_Demo/raw/master/datos/ICE_2018.xlsx"
destfile <- "ICE_2018.xlsx"
curl::curl_download(url, destfile)
ICE_2018 <- read_excel(destfile, sheet = "para_importar")
## New names:
## * `` -> ...102
## * `` -> ...105
ICE_2018 <- clean_names(ICE_2018) # limpia los nombres
data("df_mxstate") # carga la base estatal del paquete
glimpse(df_mxstate)
## Rows: 32
## Columns: 12
## $ region <chr> "01", "02", "03", "04", "05", "06", "07", "08", "…
## $ state_name <chr> "Aguascalientes", "Baja California", "Baja Califo…
## $ state_name_official <chr> "Aguascalientes", "Baja California", "Baja Califo…
## $ state_abbr <chr> "AGS", "BC", "BCS", "CAMP", "COAH", "COL", "CHPS"…
## $ state_abbr_official <chr> "Ags.", "BC", "BCS", "Camp.", "Coah.", "Col.", "C…
## $ pop <int> 1312544, 3315766, 712029, 899931, 2954915, 711235…
## $ pop_male <int> 640091, 1650341, 359137, 441276, 1462612, 350791,…
## $ pop_female <int> 672453, 1665425, 352892, 458655, 1492303, 360444,…
## $ afromexican <int> 653, 7445, 11032, 3554, 2761, 762, 4042, 2738, 16…
## $ part_afromexican <int> 4559, 10432, 5132, 6833, 8137, 3314, 17265, 8886,…
## $ indigenous <int> 153395, 283055, 103034, 400811, 204890, 145297, 1…
## $ part_indigenous <int> 18716, 38391, 11728, 13140, 28588, 12373, 52172, …
Un primer mapa:
df_mxstate$value<-df_mxstate$pop
mxstate_choropleth(df_mxstate,
title = "Total población, por Estado")
ICE_2018$value<- ICE_2018$homicidios
mxstate_choropleth(ICE_2018,
title = "Tasa de homicidios")
ggsave(plot=last_plot(), #objeto donde está el gráfico
device="png", # formato del gráfico
filename = "mapa.png") # nombre el archivo de salida
## Saving 7 x 5 in image
Hacer una pirámide con su base específica. Si no se presta para esto, debe hacerlo con la PEA, en lugar del sexo usando la ECOVID.
Hacer un mapa sobre una variable de ICE
Darse de alta en IPUMS para poderlo usar en la siguiente sesión.
Y saben, a subir: