-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGráficas_con_ggplot2_parte_1.qmd
1560 lines (1280 loc) · 61.5 KB
/
Gráficas_con_ggplot2_parte_1.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "Gráficas con `ggplot2`"
subtitle: "Parte 1: Fundamentos de graficación en `R`"
author: "Rodrigo Zepeda-Tello y Rossana Torres"
date: "`r Sys.Date()`"
abstract: "Mostramos cómo funciona `ggplot2` para elaborar gráficas de puntos, de barras y de trayectorias. Utilizamos funciones de suavizamiento y algunas opciones de personalización mediante `theme`."
title-block-banner: false
execute:
error: true
warning: false
theme: lux
toc-title: "Contenido"
author-title: "Autores"
published-title: "Última actualización"
abstract-title: "Resumen"
backgroundcolor: "#fffff8"
format:
pdf: default
html:
self-contained: true
theme: litera
toc: true
toc-location: left
toc-depth: 3
number-sections: true
number-depth: 3
reference-location: margin
citation-location: margin
bibliography: skeleton.bib
link-citations: yes
editor:
markdown:
wrap: 80
---
```{r}
#| echo: false
#| message: false
library("ggplot2")
library("gridExtra")
library("cowplot")
library("tidyverse")
library("kableExtra")
```
::: callout-note
Los datos están disponibles en el [Github](https://github.com/RodrigoZepeda/CursoR/tree/master/datasets) y en [Dropbox](https://www.dropbox.com/sh/ajgteruqo1wf47d/AADMfTnIUeIFSn_3whMVYgjfa?dl=0)
:::
::: callout-warning
Si aún no cuentas con una instalación de `ggplot2` dentro de `R` ve a la
[sección de instalación de
paquetes](https://rodrigozepeda.github.io/CursoR/Introducci%C3%B3n_a_R.html#instalaci%C3%B3n-de-paquetes)
o bien corre la siguiente instrucción:
```{r}
#| eval: false
install.packages("ggplot2")
```
:::
## ¿Qué es `ggplot2`?
`R` cuenta con su propia forma de hacer gráficas mediante el comando `plot`. Sin embargo, las gráficas que puedes hacer con plot son, salvo en el caso de regresiones, mucho más sencillas que las producidas por el paquete `ggplot`. Dicho paquete fue desarrollado inicialmente por [Hadley Wickham](http://hadley.nz) y actualmente [continúa en desarrollo](https://github.com/tidyverse/ggplot2) por más de 198 colaboradores distintos. Por su belleza y facilidad, nosotros nos enfocaremos en gráficas con `ggplot2`.
::: callout-note
Algunas de las referencias que vale la pena tengas en mente para graficar con
`ggplot2` son:
+ El libro de @wickham2016r con la versión en español disponible
de manera gratuita [en este
link](https://es.r4ds.hadley.nz/visualizaci%C3%B3n-de-datos.html)
+ El libro de
@ggplot2 disponible [en línea](https://ggplot2-book.org/index.html)
+ La página
oficial de `ggplot2`:
[https://ggplot2.tidyverse.org/](https://ggplot2.tidyverse.org/)
+ La lista de
[colores en `R`](http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf) así como
[mi página favorita para generar paletas de
colores](https://www.learnui.design/tools/data-color-picker.html)
+ Las 50
visualizaciones más comunes con `ggplot2` recolectadas por
[r-statistics.co](http://r-statistics.co/Top50-Ggplot2-Visualizations-MasterList-R-Code.html),
las [extensiones a ggplot2](https://exts.ggplot2.tidyverse.org/gallery/) así
como la [galería de `R`](https://r-graph-gallery.com/).
+ Finalmente checa las paletas de colores prediseñadas en paquetes de `R` como [`wesanderson`](https://github.com/karthik/wesanderson) o [`MetBrewer`](https://github.com/BlakeRMills/MetBrewer) así como la de [Harry Potter](https://github.com/aljrico/harrypotter).
:::
```{r}
#| column: margin
#| fig-width: 3.5
#| fig-height: 3.5
#| cache: true
#| echo: false
#| message: false
#| out-width: "150px"
#| fig-cap: "ggplot2 es el mejor paquete para graficar."
knitr::include_graphics('images/ggplot2.jpg')
```
Aprovecharemos para instalar dos paquetes que se encargan de leer bases de datos así como uno que usaremos más adelante para suavizar tendencias:
```{r}
#| eval: false
install.packages("readxl") #Para leer archivos de excel
install.packages("readr") #Para leer archivos en csv
install.packages("ggformula") #Para suavizar datos en gráficas (splines)
```
(No olvides limpiar todo tu ambiente de `R` con `rm(list = ls())` antes de iniciar; tampoco olvides que estaremos trabajando un nuevo script con `Ctrl+Shift+N` si estás en `RStudio` o `File > New File > RScript`).
Para ello, llama al paquete utilizando el comando `library`:
```{r}
#Librería para graficar
library(ggplot2)
#Librería para leer los datos en csv
library(readr)
```
```{r}
#| column: margin
#| fig-width: 3.5
#| fig-height: 3.5
#| cache: true
#| echo: false
#| message: false
#| out-width: "150px"
#| fig-cap: "Hadley Wickham, el creador de ggplot2."
knitr::include_graphics('images/hadleywickham.jpg')
```
`ggplot` trabaja con `tibbles`; los `tibbles` (pronunciados `tíblz`) son el formato preferido para tener tablas de datos. Probemos leer los datos de `diabetes` los cuales consisten en una muestra obtenida en Virginia EEUU en población afroamericana con el objetivo de determinar las prevalencias de obesidad, diabetes y otros factores de riesgo cardiovascular y proviene de la colección de bases de datos de [bioestadística de Vanderbilt](https://hbiostat.org/data/).
::: callout-tip
Puedes encontrar más información de la investgación en los artículos [Prevalence of coronary heart disease risk factors among rural blacks: A community-based study.](https://pubmed.ncbi.nlm.nih.gov/9258308/) y [A trial of church-based smoking cessation interventions for rural African Americans.](https://pubmed.ncbi.nlm.nih.gov/9010903/)
:::
Para ello, leeremos el archivo.
Hay dos formas:
1. Si estás en `RStudio` puedes irte al panel derecho superior e `Import Dataset > From text (readr)` Eso te escribirá un código como el siguiente:
```{r}
#| eval: false
setwd("tu/directorio")
datos_diabetes <- read_csv("datasets/diabetes.csv")
```
2) la segunda forma es aprendiendo directamente que el comando es `read_csv` seguido del nombre del archivo. ¡Siempre puedes guardar cualquier archivo de `Excel` en `.csv` y leerlo con `R` así!
```{r}
#| cache: true
#| echo: false
#| message: false
#| fig-cap: "Para guardar un archivo de `Excel` en formato `csv` puedes utilizar ` F12` (`Shift+Command+S` en Mac) o bien, ir a `File > Save As...` y luego seleccionar `File Format`."
knitr::include_graphics('images/CSV.png')
```
```{r}
#| echo: false
#| message: false
datos_diabetes <- read_csv("datasets/diabetes.csv")
```
La base de datos se ve más o menos así:
```{r}
#| echo: false
datos_diabetes %>% head() %>% kable() %>%
kable_styling()
```
Por ahora nos enfocaremos en los niveles de colesterol `chol` y la edad `age` de las personas (cada `id` es un individuo distinto).
## Gráfica de puntos
Para graficar el comando `ggplot(tus_datos)` coloca la capa inicial el cual es un lienzo vacío:
```{r}
#Creación de un lienzo de puntos
ggplot(datos_diabetes)
```
Probemos agregar puntos con `geom_point` especificando mediante el comando `aes` las variables de la base que vamos a graficar en cada uno de los ejes.
```{r}
#| warning: true
#Gráfica de puntos
ggplot(datos_diabetes) +
geom_point(aes(x = age, y = chol))
```
::: callout-warning
Te darás cuenta que `R` arroja un `warning` indicando que quitó una fila por valores faltantes. Esto es porque en la base de datos el `id = 1281` no cuenta con mediciones de colesterol por lo cual esa fila se remueve de la gráfica (de otra forma ¿cómo graficar algo que no medimos?).
:::
¡No olvides el `+`! Podemos agregar color a los `geom_point` con el comando `color`:
```{r}
#Gráfica de la base de datos de diabetes
ggplot(datos_diabetes) +
geom_point(aes(x = age, y = chol), color = "tomato3")
```
Una lista completa de los colores posibles [está aquí.](http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf). También puedes usar colores RGB o en formato HEX. Por ejemplo el [Manual de Identidad Gráfica del Gobierno de México](https://www.gob.mx/wikiguias/articulos/manual-de-identidad-grafica-2018-2024) establece que el tono de verde institucional es el `#235B4E` el cual se puede colocar tal cual.
```{r}
#Gráfica de la base de datos de diabetes
ggplot(datos_diabetes) +
geom_point(aes(x = age, y = chol), color = "#235B4E")
```
Podemos cambiar los títulos (`title`) de los ejes, el subtítulo (`subtitle`) y el pie de figura (`caption`) mediante `labs`:
```{r}
#Agregamos etiquetas
ggplot(datos_diabetes) +
geom_point(aes(x = age, y = chol), color = "#235B4E") +
labs(
x = "Edad (años)",
y = "Niveles de colesterol (mg/dl)",
title = "Edad contra niveles de colesterol en la población afroamericana de Virginia",
subtitle = "University of Virginia School of Medicine.",
caption = "Fuente: https://hbiostat.org/data/"
)
```
Las gráficas cuentan con varios temas (`themes`) con diseños predefinidos para cambiar su imagen. Prueba los distintos: `theme_classic`, `theme_bw`, `theme_gray`, `theme_linedraw`, `theme_light`, `theme_minimal`, `theme_dark` y `theme_void`.^[Puedes tener aún más temas si descargas el paquete (`ggthemes`)[https://yutannihilation.github.io/allYourFigureAreBelongToUs/ggthemes/]. ]
```{r}
ggplot(datos_diabetes) +
geom_point(aes(x = age, y = chol), color = "#235B4E") +
labs(
x = "Edad (años)",
y = "Niveles de colesterol (mg/dl)",
title = "Edad contra niveles de colesterol en la población afroamericana de Virginia",
subtitle = "University of Virginia School of Medicine.",
caption = "Fuente: https://hbiostat.org/data/"
) +
theme_minimal() #Agrega un tema
```
Para incrementar el tamaño de los puntos podemos usar el comando `size` dentro de `geom_point`:
```{r}
#Agregamos etiquetas
ggplot(datos_diabetes) +
geom_point(aes(x = age, y = chol), color = "#235B4E", size = 2.5) +
labs(
x = "Edad (años)",
y = "Niveles de colesterol (mg/dl)",
title = "Edad contra niveles de colesterol en la población afroamericana de Virginia",
subtitle = "University of Virginia School of Medicine.",
caption = "Fuente: https://hbiostat.org/data/"
) +
theme_minimal() #Agrega un tema
```
Y si se empalman podemos hacer unos más transparentes que otros usando `alpha`
```{r}
#Agregamos etiquetas
ggplot(datos_diabetes) +
geom_point(aes(x = age, y = chol), color = "#235B4E",
size = 2.5, alpha = 0.5) +
labs(
x = "Edad (años)",
y = "Niveles de colesterol (mg/dl)",
title = "Edad contra niveles de colesterol en la población afroamericana de Virginia",
subtitle = "University of Virginia School of Medicine.",
caption = "Fuente: https://hbiostat.org/data/"
) +
theme_minimal()
```
Finalmente, para guardar tu gráfica escribe `ggsave` con el nombre (sea en `pdf` o en `png` y las medidas de ancho (`width`) y alto (`height`) deseadas en pulgadas)
```{r}
#| eval: false
#width: ancho
#height: alto
ggsave("Edad_vs_colesterol.pdf", width = 8, height = 5)
```
El código completo para la gráfica es entonces:
```{r}
#| eval: false
#Librerías a usar
library(readr) #Leer archivos .csv
library(ggplot2) #Graficar
#Lectura de la base de datos de Virginia
datos_diabetes <- read_csv("datasets/diabetes.csv")
#Realización de la gráfica
ggplot(datos_diabetes) +
geom_point(aes(x = age, y = chol), color = "#235B4E",
size = 2.5, alpha = 0.5) +
labs(
x = "Edad (años)",
y = "Niveles de colesterol (mg/dl)",
title = "Edad contra niveles de colesterol en la población afroamericana de Virginia",
subtitle = "University of Virginia School of Medicine.",
caption = "Fuente: https://hbiostat.org/data/"
) +
theme_minimal()
#La guardamos en formato de 8 x 5 pulgadas
ggsave("Edad_vs_colesterol.pdf", width = 8, height = 5)
```
### Versión con `esquisse`
La librería `esquisse` provee una interfaz más amigable para generar las gráficas y puede serte de utilidad. ¡Veámosla!
```{r}
#| eval: false
library("esquisse") #Llamamos a la librería
set_i18n("es") #Le decimos que opere en idioma español
esquisser() #Corremos el código!
```
Una vez hayas empezado a correr el código obtendrás una pantalla como esta:
```{r}
#| echo: false
#| message: false
#| fig-cap: "Cuando comiensas a usar `esquisse` se abre una pantalla"
knitr::include_graphics('images/esquisser1.png')
```
En ella selecciona la base de datos que estamos usando (`datos_diabetes`) y selecciona `Importar Datos`
```{r}
#| echo: false
#| message: false
#| fig-cap: "Selecciona tu base de datos"
knitr::include_graphics('images/esquisser2.png')
```
Dentro de apariencia establece el color adecuado (`#235B4E`) y el tema `minimal`.
```{r}
#| echo: false
#| message: false
#| fig-cap: "Selecciona tu base de datos"
knitr::include_graphics('images/esquisser3.png')
```
En `Etiquetas & Título` elige los títulos adecuados
```{r}
#| echo: false
#| message: false
#| fig-cap: "Selecciona tu base de datos"
knitr::include_graphics('images/esquisser4.png')
```
En `Opciones de Gráfico` cambia el tamaño de los puntos a `2.5`
```{r}
#| echo: false
#| message: false
#| fig-cap: "Selecciona tu base de datos"
knitr::include_graphics('images/esquisser5.png')
```
Finalmente, ve a `código` y copia en tu `script` el código correspondiente
```{r}
#| echo: false
#| message: false
#| fig-cap: "Selecciona tu base de datos"
knitr::include_graphics('images/esquisser6.png')
```
Nota que no es exactamente igual al código de la sección anterior pero es una buena aproximación para tener una gráfica con la cual empezar.
### R Básico
1. Imita la siguiente gráfica de altura (`height`) contra peso (`weight`) de la base de datos de diabetes. En esta usamos otro tema distinto (`classic`) y los puntos son naranjas (`orange`) de tamaño $0.5$:
```{r}
#| echo: false
#| warning: false
ggplot(datos_diabetes) + geom_point(aes(x = weight, y = height), color = "orange", size = 0.5) + xlab("Peso (libras)") + ylab("Altura (pulgadas)") + ggtitle("Gráfica de peso contra altura") + theme_classic()
```
2. Dentro del `aes` puedes también aplicar funciones a las variables. Por ejemplo si queremos graficar índice de masa corporal ($\text{peso (kg)} / (\text{altura (m)}^2)$) podemos calcular el IMC en el mismo `aes` haciendo: `... aes(x = (weight * 0.453592) /(height * 0.0254)^2, ...) ...`. Donde el factor `0.453592` es para convertir de libras a kilos y `0.0254` de pulgadas a metros. Grafica en el eje `x` el índice de masa corporal (IMC) y en `y` el radio de colesterol definido como el nivel de colesterol `chol` entre el colesterol de alta densidad `hdl`. Obtén una gráfica como esta de color púrpura (`purple`), tamaño `0.5` y tema `bw`:
```{r}
#| echo: false
#| warning: false
ggplot(datos_diabetes) +
geom_point(aes(x = (weight * 0.453592) /(height * 0.0254)^2, y = chol/hdl), color = "purple", size = 0.5) + xlab("IMC") + ylab("Radio de colesterol") + ggtitle("Relación entre IMC y colesterol") + theme_bw()
```
3. Descarga y lee las bases de [datasets/IMSS_BCG_2019.csv y datasets/IMSS_BCG_2020.csv](https://www.dropbox.com/sh/51x0s7w7s11que0/AABWlyxNkBOi5I9S3FHQW8Eya?dl=0) las cuales contiene información de las dosis aplicadas de **B.C.G** (Vacuna contra la tuberculosis) contra los casos de tuberculosis detectados en el IMSS por delegación en el mismo año (2019 y 2020 respectivamente). Replica las siguientes dos gráficas con color `deepskyblue3`, `size = 1.5`. Para ello requieres instalar la librería `ggrepel` y usar `geom_text_repel`. Tu código debe tener una estructura similar a esto:
```{r}
#| eval: false
#Lectura de datos
#...
#Gráfica
ggplot(...) +
geom_point(...) +
geom_text_repel(aes(x = `Dosis BCG`, #Así se ponen las
y = `Casos detectados tuberculosis`, #etiquetas
label = Del), size = 2) + #de entidad
labs(...) +
...
```
```{r}
#| echo: false
#| message: false
#| out-height: "500px"
library(cowplot)
library(ggrepel)
grafica <- function(data_name = "datasets/IMSS_BCG_2019.csv", year = 2019){
bcg <- read_csv(data_name,
locale = locale(encoding = "UTF-8"), show_col_types = F)
ggplot(bcg) +
geom_point(aes(x = `Dosis BCG`,
y = `Casos detectados tuberculosis`),
color = "deepskyblue3", size = 1.5) +
geom_text_repel(aes(x = `Dosis BCG`,
y = `Casos detectados tuberculosis`,
label = Del), size = 2) +
labs(
x = "Dosis de B.C.G aplicadas",
y = "Casos detectados de tuberculosis",
subtitle = glue::glue("Instituto Mexicano del Seguro Social, {year}"),
title = "Dosis de B.C.G. contra casos detectados de tuberculosis",
caption = "Fuente: Datos Abiertos del IMSS / Elaboración propia"
) +
theme_minimal()
}
plot_grid(grafica(), grafica(data_name = "datasets/IMSS_BCG_2020.csv", year = 2020),
ncol = 1)
```
### R Intermedio
En la base de `diabetes`, utiliza `scale_y_continuous` en particular la opción de `sec.axis` para agregar un segundo eje `y` del lado derecho donde la altura esté en metros (no pulgadas). Repite el proceso con `scale_x_continuous` para agregar un eje `x` en la parte superior con el peso en kilogramos.
```{r, echo = FALSE}
ggplot(datos_diabetes) +
geom_point(aes(x = weight, y = height), color = "orange", size = 0.5) +
ggtitle("Gráfica de peso contra altura") +
theme_classic() +
scale_y_continuous("Altura (pulgadas)",
sec.axis = sec_axis(~ . * 0.0254, name = "Altura (metros)")) +
scale_x_continuous("Peso (libras)",
sec.axis = sec_axis(~ . * 0.453592, name = "Peso (kilogramos)"))
```
## Gráficas de columnas (barras)
### Una tranquila (BCG en IMSS)
La base de datos `IMSS_BCG_2019.csv` contiene las dosis de B.C.G que se han aplicado en el IMSS por Delegación. Generaremos una gráfica de barras con ellas. Para eso leemos la base:
```{r}
#| message: false
bcg <- read_csv("datasets/IMSS_BCG_2020.csv")
```
Ésta se ve más o menos así:
```{r}
#| echo: false
head(bcg) %>%
kable() %>%
kableExtra::kable_styling()
```
Graficaremos la columna de `Dosis BCG` por delegación `Del`. Para ello ponemos nuestro lienzo con `ggplot` y agregamos un `geom_col`:
```{r}
ggplot(bcg) +
geom_col(aes(x = Del, y = `Dosis BCG`))
```
Nota que aquí a la variable hubo que llamarle `Dosis BCG` con los acentos graves <code>`</code>
Esto porque de otra forma genera error pues piensa que `Dosis` y `BCG` son dos palabras distintas:
```{r}
ggplot(bcg) +
geom_col(aes(x = Del, y = Dosis BCG))
```
Para darle color usaremos tanto `color` como `fill`. Nota que el `color` cambia la orilla:
```{r}
ggplot(bcg) +
geom_col(aes(x = Del, y = `Dosis BCG`), color = "red")
```
mientras que `fill` cambia el contenido:
```{r}
ggplot(bcg) +
geom_col(aes(x = Del, y = `Dosis BCG`), color = "red",
fill = "blue")
```
Cambiaré los colores por unos más bellos, y agregaré título y etiquetas a los ejes. En este caso no deseo etiqueta en el eje `x` por lo cual lo dejaré como comillas vacías: `""`.
```{r}
ggplot(bcg) +
geom_col(aes(x = Del, y = `Dosis BCG`),
color = "red", fill = "blue") +
labs(
x = "",
y = "Dosis BCG aplicadas",
title = "Dosis de B.C.G. aplicadas en el IMSS",
subtitle = "Año 2020"
)
```
Voy a agregar comas a los números del eje `y` con `scale_y_continuous`. El `scale_y_continuous` manipula lo que sea del eje `y`. En mi caso deseo sólo que los números les ponga comas (otra opción es para porcentajes usar `percent` en lugar de `comma`):
```{r}
ggplot(bcg) +
geom_col(aes(x = Del, y = `Dosis BCG`),
color = "red", fill = "blue") +
labs(
x = "",
y = "Dosis BCG aplicadas",
title = "Dosis de B.C.G. aplicadas en el IMSS",
subtitle = "Año 2020"
) +
scale_y_continuous(labels = scales::comma)
```
Finalmente usaremos `theme` para cambiar la orientación de las etiquetas del eje `x` a vertical (_i.e_ con un ángulo de 90º) para que se vean mejor:
```{r}
ggplot(bcg) +
geom_col(aes(x = Del, y = `Dosis BCG`),
color = "red", fill = "blue") +
labs(
x = "",
y = "Dosis BCG aplicadas",
title = "Dosis de B.C.G. aplicadas en el IMSS",
subtitle = "Año 2020"
) +
scale_y_continuous(labels = scales::comma) +
theme(axis.text.x = element_text(angle = 90,
hjust = 1, vjust = 0.5))
```
Seguro en este punto te estarás preguntando ¿y cómo Rod sabe cuál es el código para cada opción? La respuesta es que pasé mucho tiempo (¡demasiado!) en Google encontrándola pero que una vez encontré el cómo rotar las etiquetas guardé el código en mi cuaderno y ahora cada que se ofrece ¡ya sé qué poner!
Finalmente agregaré colores más lindos y un `theme_linedraw`
```{r}
ggplot(bcg) +
geom_col(aes(x = Del, y = `Dosis BCG`),
color = "black", fill = "tomato3") +
labs(
x = "",
y = "Dosis BCG aplicadas",
title = "Dosis de B.C.G. aplicadas en el IMSS",
subtitle = "Año 2020"
) +
scale_y_continuous(labels = scales::comma) +
theme_linedraw() + #Nota que se agrega antes porque
#si se pone después desconfigura la rotada
theme(axis.text.x = element_text(angle = 90,
hjust = 1, vjust = 0.5))
```
### Ejercicio
Utiliza la base de datos `IMSS_BCG_2019.csv` y genera la siguiente gráfica con `color` de la orilla `white` y relleno (`fill`) de color `forestgreen`. El tema es el `bw` y el texto del eje `x` está a 45 grados:
```{r}
#| echo: false
read_csv("datasets/IMSS_BCG_2019.csv", show_col_types = F) %>%
ggplot() +
geom_col(aes(x = Del, y = `Casos detectados tuberculosis`),
color = "white", fill = "forestgreen") +
labs(
x = "",
y = "Casos",
title = "Casos detectados de tuberculosis en el IMSS",
subtitle = "Año 2019",
caption = "Fuente: Datos Abiertos IMSS"
) +
scale_y_continuous(labels = scales::comma) +
theme_bw() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 0.5))
```
### Una más complicada (Seguro Popular)
El archivo `inegi_seguro_popular.csv` ([datos reales obtenidos de INEGI](https://datos.gob.mx/busca/dataset/porcentaje-de-la-poblacion-afiliada-al-seguro-popular-derecho-a-la-salud-recepcion-del-derecho)) contiene información del número de personas afiliadas al seguro popular por entidad federativa en 2010 y 2015. Graficaremos ambos años. Para ello, leamos el archivo:
```{r}
#| echo: false
seguro.pop <- read_csv("datasets/inegi_seguro_popular.csv",
locale = locale(encoding = "WINDOWS-1252"))
```
```{r}
#| eval: false
seguro.pop <- read_csv("inegi_seguro_popular.csv",
locale = locale(encoding = "WINDOWS-1252"))
```
Notarás que esta vez tuvimos que establecer un _locale_ esto es porque la base tiene acentos y caracteres del español y cuando la base fue generada por una computadora `Windows` hay que especificar que viene de _Windows_ con el locale.
:::{.callout-note}
El `locale` es un poco más complicado y refiere a cómo la computadora sabe qué secuencia de bits corresponde a qué caracter. Latinoamérica usualmente está entre `WINDOWS-1252` y `UTF-8`.
:::
Podemos graficar los datos que aparecen en gráfica de barras mediante el comando `geom_col`:
```{r}
#Gráfica encimada
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`))
```
Esta vez como los nombres de las columnas contienen varias palabras hubo que colocarlas entre dos [acentos graves ó backticks:](https://en.wikipedia.org/wiki/Backtick) <code>`</code>
Nota que hay gráficas donde el porcentaje supera el 100% esto es porque `R`, de inicio, combina los años `2010` y `2015` sumando los valores. Podemos ver esto con el comando `fill` diciéndole a `R` que `Periodo` no lo lea como número sino como caracter `character` (de otra forma buscará colorearlo con el color `2010` y `2015` los cuales no se distinguen):
```{r}
#Gráfica encimada con dos periodos
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`,
fill = as.character(Periodo)))
```
Ojo como `periodo` es una sola palabra podemos ponerlo con o sin el acento grave <code>`</code>:
```{r}
#Gráfica encimada con dos periodos (equivalente)
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`,
fill = as.character(`Periodo`)))
```
Mediante `coord_flip()` podemos rotar las coordenadas:
```{r}
#Gráfica encimada
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`,
fill = as.character(`Periodo`))) +
coord_flip()
```
Existen dos formas de separar los años: mediante `facet_wrap()` en dos gráficas distintas o mediante `position` dentro de la misma gráfica. Veamos sus diferencias:
```{r}
#Gráfica con position
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`,
fill = as.character(`Periodo`)),
position = "dodge") +
coord_flip()
```
o bien:
```{r}
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`,
fill = as.character(`Periodo`))) +
coord_flip() +
facet_wrap(~as.character(`Periodo`))
```
A mí me gusta más el de `facet_wrap()` así que continuaré trabajando con él. Podemos mejorar la leyenda mediante el `scale_fill_manual` (`scale_color_manual` respectivamente si nos interesa cambiar sólo el color de las barras)
```{r}
#Gráfica colores mediante "scale_fill_manual"
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`,
fill = as.character(`Periodo`))) +
coord_flip() +
facet_wrap(~ as.character(`Periodo`)) +
scale_fill_manual("Año",
values = c("2010" = "#EB2188", #colores del 2010
"2015" = "#080A52")) #colores del 2015
```
Podemos reordenar el eje para que `Aguascalientes` quede hasta arriba. Para eso especificamos el orden. Lo podemos hacer manualmente (pero qué flojera):
```{r}
orden <- c('Estados Unidos Mexicanos', 'Aguascalientes', 'Baja California',
'Baja California Sur', 'Campeche', 'Coahuila de Zaragoza',
'Colima', 'Chiapas', 'Chihuahua', 'Ciudad de México', 'Durango',
'Guanajuato', 'Guerrero', 'Hidalgo', 'Jalisco', 'México',
'Michoacán de Ocampo', 'Morelos', 'Nayarit', 'Nuevo León',
'Oaxaca', 'Puebla', 'Querétaro', 'Quintana Roo', 'San Luis Potosí',
'Sinaloa', 'Sonora', 'Tabasco', 'Tamaulipas', 'Tlaxcala',
'Veracruz de Ignacio de la Llave', 'Yucatán', 'Zacatecas')
```
O bien pidiéndole a `R` una lista de los estados en la base:
```{r}
orden <- unique(seguro.pop$`Entidad federativa`)
```
en cualquiera de los casos esa lista la pondremos en reversa dentro de limits:
```{r}
#Reordenamos el eje vertical
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`,
fill = as.character(`Periodo`))) +
coord_flip() +
facet_wrap(~ as.character(`Periodo`)) +
scale_fill_manual("Año",
values = c("2010" = "#EB2188",
"2015" = "#080A52")) +
scale_x_discrete(limits = rev(orden))
```
Finalmente, podemos agregar los formatos de etiquetas usuales:
```{r}
ggplot(seguro.pop) +
geom_col(aes(x = `Entidad federativa`,
y = `Porcentaje de la población afiliada al seguro popular`,
fill = as.character(`Periodo`))) +
coord_flip() +
facet_wrap(~ as.character(`Periodo`)) +
scale_fill_manual("Año",
values = c("2010" = "#EB2188",
"2015" = "#080A52")) +
scale_x_discrete(limits = rev(orden)) +
labs(
title = "Población afiliada al Seguro Popular\npor entidad federativa",
y = "Proporción de la población",
x = "Entidad federativa",
caption = "Fuente: INEGI"
) +
theme_bw()
```
### Ejercicio
1. El siguiente código genera una base de datos de nombre `vacunacion` con la información de cuántos niños menores de uno o dos años tienen el esquema completo de cuatro vacunas de acuerdo con las distintas Encuestas Nacionales de Salud ENSA/ENSANUT.
```{r}
Encuesta <- rep(c("2000","2006","2012","2018-19","2021"), 2)
vacperc <- c(c(0.265, 0.784, 0.742, 0.199, 0.311), c(0.5, 0.847, 0.779, 0.353, 0.358))
clase <- c(rep("1 año cumplido", 5), rep("2 años cumplidos", 5))
vacunacion <- data.frame(Encuesta, vacperc, clase)
colnames(vacunacion) <- c("ENSANUT", "Porcentaje vacunado", "Edad de los niños")
```
Corre el código tal cual y una vez lo hayas corrido, grafica los datos con columnas eligiendo colores y texto adecuados.
2. Utiliza la base `IMSS_BCG_2019.csv` para realizar una gráfica de barras identica a la que sigue (el `fill` es `deepskyblue4` y no tiene `color`). Para agregar los numeritos en las barras se usó `geom_text` con `size = 2`, `hjust = 0`, `color = "white"` y `angle = 90`. El tema es el `bw`.
```{r}
#| echo: false
imss2019 <- read_csv("datasets/IMSS_BCG_2019.csv", show_col_types = FALSE)
ggplot(imss2019) +
geom_col(aes(x = Del, y = `Dosis BCG`), fill = "deepskyblue4") +
geom_text(aes(x = Del,
y = 100,
label = scales::comma(`Dosis BCG`)),
color = "white", angle = 90, hjust = 0, size = 2) +
theme_bw() +
labs(
x = "Delegación",
y = "Dosis de B.C.G. aplicadas",
title = "Dosis de B.C.G. aplicadas en el IMSS",
subtitle = "Instituto Mexicano del Seguro Social, 2019"
) +
theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
scale_y_continuous(labels = scales::comma)
```
## Histogramas con `ggplot2`
### Un histograma es una gráfica de barras especial
El comando `geom_histogram` sirve para crear histogramas. Un histograma es un tipo de gráfico de barras que acumula en cada barra conteos de cuántos cayeron en ese sitio. Para entender mejor, veamos un ejemplo. Para ello copia el siguiente código el cual genera una base de datos expuesta a continuación:
```{r}
datos_histograma <- tibble(
estaturas = c(1.42, 1.45, 1.65, 1.55, 1.32, 1.44, 1.50, 1.51, 1.62, 1.55)
)
```
```{r}
#| echo: false
datos_histograma %>%
kable() %>%
kable_styling()
```
Viendo la base de datos notamos que puede resumirse según fueron cayendo en distintos intervalos:
```{r}
#| echo: false
datos_histograma %>%
mutate(`Intervalo`= cut(estaturas, c(1.3,1.4,1.5,1.6,1.7,1.8))) %>%
mutate(Intervalo = str_remove_all(Intervalo,"\\(|\\]")) %>%
mutate(Intervalo = str_replace_all(Intervalo,","," - ")) %>%
group_by(Intervalo) %>%
tally() %>%
kable() %>%
kable_styling()
```
Podemos elaborar fácilmente una gráfica de barras para ese conteo:
```{r}
#| echo: false
datos_histograma %>%
mutate(`Intervalo`= cut(estaturas, c(1.3,1.4,1.5,1.6,1.7,1.8))) %>%
mutate(Intervalo = str_remove_all(Intervalo,"\\(|\\]")) %>%
mutate(Intervalo = str_replace_all(Intervalo,","," - ")) %>%
group_by(Intervalo) %>%
tally() %>%
ggplot() +
geom_col(aes(x = Intervalo, y = n), fill = "purple")
```
donde, de nuevo, la altura de la barra corresponde al conteo de cuántos cayeron en ese intervalo.
Podemos también hacer una gráfica de barras donde no pongamos el conteo absoluto sino el porcentaje (sabemos que hay `r nrow(datos_histograma)` mediciones en total) y esto se vería así:
```{r}
#| echo: false
datos_histograma %>%
mutate(`Intervalo`= cut(estaturas, c(1.3,1.4,1.5,1.6,1.7,1.8))) %>%
mutate(Intervalo = str_remove_all(Intervalo,"\\(|\\]")) %>%
mutate(Intervalo = str_replace_all(Intervalo,","," - ")) %>%
group_by(Intervalo) %>%
tally() %>%
ggplot() +
geom_col(aes(x = Intervalo, y = n/10), fill = "purple")
```
Un histograma representa la misma idea que estas gráficas de barras de manera simplificada. Usando los datos asignados previamente puedo construir un histograma como sigue:
```{r}
ggplot(datos_histograma) +
geom_histogram(aes(x = estaturas), color = "white",
breaks = c(1.3, 1.4, 1.5, 1.6, 1.7, 1.8))
```
donde los `breaks` indican a `R` dónde hacer los cortes (volveremos más adelante).
Si quisiéramos verlo como porcentaje y no cómo conteo basta con agregar una opción (muy específica que a nadie se le va a ocurrir sin googlearlo) de `y = (..count..)/sum(..count..)` en el `aes` como sigue:
```{r}
ggplot(datos_histograma) +
geom_histogram(aes(x = estaturas, y = (..count..)/sum(..count..)),
color = "white",
breaks = c(1.3, 1.4, 1.5, 1.6, 1.7, 1.8))
```
¡Hagamos entonces nuestro primer histograma!
### Histograma de colesterol
Tomaremos de nuevo la base de diabetes que usamos en la sección anterior. Para ello la leemos:
```{r}
#| message: false
datos_diabetes <- read_csv("datasets/diabetes.csv")
```
Para armar el histograma es sólo necesario especificar una variable en el `aes`:
```{r}
#Graficación de un histograma
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol))
```
Date cuenta que solito `R` decide cuántas barras poner.
::: callout-note
Según [Ioannidis](http://www.madgik.di.uoa.gr/sites/default/files/vldb03_pp19-30.pdf) histograma viene del griego _histos_ (mástil) y _gram-ma_ (algo escrito). Por lo que literalmente sería algo escrito en mástiles. A pesar de que éstos se atribuyen a Karl Pearson, los histogramas fueron inventados desde antes. Él fue quien les puso nombre.
:::
Para especificar el número de barras hay dos formas: utilizando el comando `bins` lo que le dice a `R` cuántas barras poner:
```{r}
#Graficación de un histograma con 50 barras
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol), bins = 50)
```
O bien especificando el ancho de cada barra y dejando a `R` decidir:
```{r}
#Graficación con barras de ancho 10
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol), binwidth = 10)
```
o bien especificando de dónde a dónde van los puntos de corte de cada barra:
```{r}
#Graficación con barras de ancho 10
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol),
breaks = c(50, 100, 150, 200, 250, 300, 350))
```
El comando `fill` cambia el color interno de las barras.
```{r}
#El comando fill cambia el color
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol), bins = 50, fill = "#cef0ff")
```
Mientras que el comando `color` cambia el color del borde de la misma:
```{r}
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol), bins = 50,
fill = "#cef0ff", color = "#1D1B1B")
```
FInalmente, podemos hacer que el histograma muestre no el número de casos totales en la base sino la proporción de los casos mediante `y = ..density..`. La diferencia entre `..density..` y `(..count..)/sum(..count..)` es que ``..density..` está hecho para que la suma de las áreas de los rectángulos dé $1$ mientras que en `(..count..)/sum(..count..)` la suma de las alturas de los rectángulos es la que da $1$.
```{r}
#..density.. nos da el % de casos de manera normalizada
#para que los rectángulos sumen sus áreas a área 1
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol, y = ..density..),
bins = 50, fill = "#cef0ff", color = "#1D1B1B")
```
Podemos agregar, además, una densidad kernel que nos dé una idea de cómo se ve la distribución ajustada. Como veremos más adelante, la densidad kernel (aunque puede ser manipulable) es más fácil que no nos dé errores de distribución incorrecta.
```{r}
#Gráfica de histograma con densidad kernel
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol, y = ..density..),
bins = 50,
fill = "#cef0ff", color = "#1D1B1B") +
geom_density(aes(x = chol))
```
**Ojo** `ggplot2` funciona por capas por lo cual el orden en el que se agrega cada capa (`geom`) sí afecta el cómo se ve. Si ponemos el `geom_density` antes del `geom_histogram` nos queda la línea _detrás_ del histograma:
```{r}
#Gráfica de histograma con densidad kernel
ggplot(datos_diabetes) +
geom_density(aes(x = chol)) +
geom_histogram(aes(x = chol, y = ..density..),
bins = 50,
fill = "#cef0ff", color = "#1D1B1B")
```
Continuando con la edición podemos cambiar los parámetros de `color` y `size` de la distribución para ajustar su color y tamaño. Así mismo, [`linetype` nos da una línea discontinua](https://ggplot2.tidyverse.org/reference/aes_linetype_size_shape.html):
```{r}
#Cambio de color y tipo de línea a la densidad
ggplot(datos_diabetes) +
geom_histogram(aes(x = chol, y = ..density..),
bins = 50,
fill = "#cef0ff", color = "#1D1B1B") +
geom_density(aes(x = chol), color = "deepskyblue4",
linetype = "dotted", size = 1)
```
Finalmente, modificamos los temas:
```{r}
#Graficación con barras de ancho 0.05