R y Rstudio

R es un software libre diseñado para análisis estadisticos y gráficas. Se hizo popular siendo que su curva de aprendizaje es relativamente más empinada con respecto a otros lenguajes de programación. A pesar de esto Stata sigue siendo el software más utilziado en el analisís economico, pero es de pega y su licencia es muy cara 8por lo menos para mi ;) )

Una de las caracterristica peculiares es que resulta ser un proyecto colaborativo donde estudiosos de distitntas partes del mundo pueden aportar al enriquecimiento de las funciones de este software por medios de paquetes. Enb particular los más actualziados y estables se pueden encontrar en CRAN.

R es el lenguaje de programación y si tuvieramos que utilizarlo puro sería solo por medio de una consola. Al contrario R studio es un programa que permite utilizar R de manera más comoda y efectiva. R studio es un IDE, ósea un entorno de desarrollo integrado. Esto significa que es un sistema de software para el diseño de aplicaciones que combina herramientas del desarrollador comunes en una sola interfaz gráfica de usuario (GUI).

Lo basico

Hay algunas cosas que vale la pena hacer antes de empezar a trabajar. La primera es limpiar nuestra sesión eliminando todos los objetos y variables en memoria:

rm(list=ls())

Luego definimos la directory donde iremos trabajando:

setwd("C:/DAVE2/CIDE/Doc/Econometria II/Web")

Si preferimos podemos evitar el utilizo de la notación cientifica de default:

options(scipen=999) 

Y pasar los elementos graficos a una ventana independiente:

options(device = "windows")
dev.new()

Los paquetes

Como vimos en CRAN hay muchos paquetes que nos sirven para ampliar las funcionalides basicas de R (i.e hacer PSM, regresiones con efectos fijos, estimaciones de IC en presencia de heteroscedasticidad). Cuando queremos instalar un nuevo paquete podemos hacerlo a traves del ide de la siguiente forma:

Tools -> Install packages -> seleccionamo CRAN -> seleccionamos el paquete que nos interes

De otra forma podemos hacerlo directamente en el codigo:

install.packages("nombre paquete")

Cuando un paquete es ya instalado, es suficiente instalarlo solo la primera vez que lo utilizamos, en la siguientes sesiones o cuando queremos utilizarlo será suficiente solo cargarlo:

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.0.5
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5     v purrr   0.3.4
## v tibble  3.1.4     v dplyr   1.0.7
## v tidyr   1.1.3     v stringr 1.4.0
## v readr   2.0.1     v forcats 0.5.1
## Warning: package 'ggplot2' was built under R version 4.0.5
## Warning: package 'tibble' was built under R version 4.0.5
## Warning: package 'tidyr' was built under R version 4.0.5
## Warning: package 'readr' was built under R version 4.0.5
## Warning: package 'dplyr' was built under R version 4.0.5
## Warning: package 'forcats' was built under R version 4.0.5
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

Constantes y operaciones

Cuando queremos asignar un valor a una constante lo haremos de la siguiente forma:

a<-6
b<-7

El sistema asignará a las constantes designada los valores correspectivos y podremos utilizarlas para hacer las operaciones que queremos:

c<- a+b
d<- a-b
e<- a*b
f<- a/b
g<- a^b

Que resultados obtendremos?

c
## [1] 13
d
## [1] -1
e
## [1] 42
f
## [1] 0.8571429
g
## [1] 279936

Para imprimir un elemento es suficiente escribirlo en el editor del codigo o en la consola.

Ejercicio 1

Un rectangulo tiene una base igual a 10 unidades y una altura igual a 4 unidades. Genere una constante llamada area.rect que indique el area del rectangulo

Solución

area.rect <- 10*4
area.rect
## [1] 40
base <- 10
altura <- 4
area.rect <- base*altura

Ejercicio 2

¿Que pasa si el rectangulo ahora tiene una altura de 5? Genere la nueva area area.rect.2

Solución

altura <- 5
area.rect.2 <- base*altura

Notense que cuando volvemos a asignar una misma variable, el valor precedente se pierde.

Ejercicio 3

Un circulo tiene radio de 2.6. Genere una constante a.circ que indique el area del circulo y otra p.circ que indique la circunferencia

Solución

radio <- 2.6
d.circ <- radio^2*pi
p.circ <- pi*2*radio

Vemos que algunas constante ya vienen pre asignada en R y en su sintaxis

vectores y matrices

Podemos definir un vector de la siguiente forma

x<-c(3,4,5)

Podemos hacer operaciones con los vectores, como multiplicarlo por un escalar:

xx<-x*2
xx
## [1]  6  8 10

Nuestros vectores pueden ser compuestos por cadenas:

y <- c("Pedro", "Andrea", "Ana")
y
## [1] "Pedro"  "Andrea" "Ana"

Para obtner una matriz especificamos un vector y las dimeniones de la matriz misma:

M <- matrix(data=c(4,-2,1,6,0,5),nrow=2,ncol=3)
M
##      [,1] [,2] [,3]
## [1,]    4    1    0
## [2,]   -2    6    5

No es necesario siempre especificar el nombre del argumento:

N <- matrix(c(4,-2,1,6,0,5),2,3)
N
##      [,1] [,2] [,3]
## [1,]    4    1    0
## [2,]   -2    6    5

Se pueden hacer operaciones con las matrices así como hicimos con los vectores:

N2 <- N*2
N2
##      [,1] [,2] [,3]
## [1,]    8    2    0
## [2,]   -4   12   10

Operaciones basicas

R incluye en su funciones basicas unas para obtener informaciones estadisticas con respecto a nuestras variables (i.e. vectores)

Media

mean(x)
## [1] 4

si no conocemos la sintaxis y las caracteristicas de una funcion podemos utilizar la siguiente expresión:

?mean
## starting httpd help server ... done

Mediana, Varianza, Desviación Estandar, Standard Score (Z-Score)

median(x)   
## [1] 4
var(x)  
## [1] 1
sd(x)   
## [1] 1
scale(x)    
##      [,1]
## [1,]   -1
## [2,]    0
## [3,]    1
## attr(,"scaled:center")
## [1] 4
## attr(,"scaled:scale")
## [1] 1

Ahora bien vemos como graficar una curva sencilla con ggplot

library(ggplot2)
x <- c(-4,-3,-2,-1,0,1,2,3,4)
y<-x^2

Que curva obtendremos?

qplot(x, y)

Leer Base de datos

Vimos precedentemente que hemos fijado nuestro directorio de trabajo. Si la base que queremos cargar está en la misma carpeta para leer un archivo es suficiente a apuntar a esta directory poniendo adelante del nombre del archivo ./. Recuerdense que a diferencia de windows y stata tendremos que utilizar el slash al reves:

library(tidyverse)
mundata <- read_csv(file = "./mundata.csv")
## Rows: 2457 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (4): nom_ent, mun, cve_sun, nom_sun
## dbl (5): clave, clave_ent, pop, icu, beds
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Siquermos leer caracteres en español, podemos especificar el encodimg:

mundata <- read_csv(file = "./mundata.csv",
                    locale = locale(encoding = "latin1"))
## Rows: 2457 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (4): nom_ent, mun, cve_sun, nom_sun
## dbl (5): clave, clave_ent, pop, icu, beds
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Esta base de datos presenta los datos de la población de los municipios de México. Además presenta el numero de cama y unidades de cuidado intensivo de acuerdo a los ultimos registros oficiales.

Para explorar la base de datos podemos ver el nombbre de las columnas:

colnames(mundata)
## [1] "clave"     "clave_ent" "nom_ent"   "mun"       "pop"       "icu"      
## [7] "beds"      "cve_sun"   "nom_sun"

Las primeras filas:

head(mundata)
## # A tibble: 6 x 9
##   clave clave_ent nom_ent        mun           pop   icu  beds cve_sun nom_sun  
##   <dbl>     <dbl> <chr>          <chr>       <dbl> <dbl> <dbl> <chr>   <chr>    
## 1  1001         1 Aguascalientes Aguascali~ 961977    44  1022 M01.01  Aguascal~
## 2  1002         1 Aguascalientes Asientos    50864     0     0 <NA>    <NA>     
## 3  1003         1 Aguascalientes Calvillo    60760     0    30 <NA>    <NA>     
## 4  1004         1 Aguascalientes Cosío       16918     0     0 <NA>    <NA>     
## 5  1005         1 Aguascalientes Jesús Mar~ 130184    12   144 M01.01  Aguascal~
## 6  1006         1 Aguascalientes Pabellón ~  50032     0    30 <NA>    <NA>

De las cuales podemos especificar el numero exacto de filas a visualizar:

head(mundata, n=10)
## # A tibble: 10 x 9
##    clave clave_ent nom_ent        mun          pop   icu  beds cve_sun nom_sun  
##    <dbl>     <dbl> <chr>          <chr>      <dbl> <dbl> <dbl> <chr>   <chr>    
##  1  1001         1 Aguascalientes Aguascal~ 961977    44  1022 M01.01  Aguascal~
##  2  1002         1 Aguascalientes Asientos   50864     0     0 <NA>    <NA>     
##  3  1003         1 Aguascalientes Calvillo   60760     0    30 <NA>    <NA>     
##  4  1004         1 Aguascalientes Cosío      16918     0     0 <NA>    <NA>     
##  5  1005         1 Aguascalientes Jesús Ma~ 130184    12   144 M01.01  Aguascal~
##  6  1006         1 Aguascalientes Pabellón~  50032     0    30 <NA>    <NA>     
##  7  1007         1 Aguascalientes Rincón d~  57981     0    30 <NA>    <NA>     
##  8  1008         1 Aguascalientes San José~   9661     0     0 <NA>    <NA>     
##  9  1009         1 Aguascalientes Tepezalá   22743     0     0 <NA>    <NA>     
## 10  1010         1 Aguascalientes El Llano   21947     0     0 <NA>    <NA>

Podemos tambvién imprmir las ultimas observaciones:

tail(mundata)
## # A tibble: 6 x 9
##   clave clave_ent nom_ent   mun             pop   icu  beds cve_sun nom_sun     
##   <dbl>     <dbl> <chr>     <chr>         <dbl> <dbl> <dbl> <chr>   <chr>       
## 1 32053        32 Zacatecas Villa Gonzá~  13945     0     0 <NA>    <NA>        
## 2 32054        32 Zacatecas Villa Hidal~  20177     0     0 <NA>    <NA>        
## 3 32055        32 Zacatecas Villanueva    31804     0    22 <NA>    <NA>        
## 4 32056        32 Zacatecas Zacatecas    155533    24   337 M32.01  Zacatecas-G~
## 5 32057        32 Zacatecas Trancoso      20285     0    12 M32.01  Zacatecas-G~
## 6 32058        32 Zacatecas Santa María~   2855     0     0 <NA>    <NA>

O averiguar el tamaño de nuestro dataframe:

dim(mundata)
## [1] 2457    9

Si quermos saber el numero de filas de nuestra matriz podemos utilizar la siguinete función:

nrow(mundata)
## [1] 2457

Mintras para las columnas será:

ncol(mundata)
## [1] 9

Para saber la estructura de nuestro database podemos utilizar:

str(mundata)
## spec_tbl_df [2,457 x 9] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ clave    : num [1:2457] 1001 1002 1003 1004 1005 ...
##  $ clave_ent: num [1:2457] 1 1 1 1 1 1 1 1 1 1 ...
##  $ nom_ent  : chr [1:2457] "Aguascalientes" "Aguascalientes" "Aguascalientes" "Aguascalientes" ...
##  $ mun      : chr [1:2457] "Aguascalientes" "Asientos" "Calvillo" "Cosío" ...
##  $ pop      : num [1:2457] 961977 50864 60760 16918 130184 ...
##  $ icu      : num [1:2457] 44 0 0 0 12 0 0 0 0 0 ...
##  $ beds     : num [1:2457] 1022 0 30 0 144 ...
##  $ cve_sun  : chr [1:2457] "M01.01" NA NA NA ...
##  $ nom_sun  : chr [1:2457] "Aguascalientes" NA NA NA ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   clave = col_double(),
##   ..   clave_ent = col_double(),
##   ..   nom_ent = col_character(),
##   ..   mun = col_character(),
##   ..   pop = col_double(),
##   ..   icu = col_double(),
##   ..   beds = col_double(),
##   ..   cve_sun = col_character(),
##   ..   nom_sun = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>

Base de datos

Podemos filtrar nuestra base de datos:

filter(mundata, clave_ent==2)
## # A tibble: 5 x 9
##   clave clave_ent nom_ent         mun            pop   icu  beds cve_sun nom_sun
##   <dbl>     <dbl> <chr>           <chr>        <dbl> <dbl> <dbl> <chr>   <chr>  
## 1  2001         2 Baja California Ensenada    5.36e5    14   520 M02.01  Ensena~
## 2  2002         2 Baja California Mexicali    1.09e6    32  1101 M02.02  Mexica~
## 3  2003         2 Baja California Tecate      1.14e5     0   112 M02.03  Tijuana
## 4  2004         2 Baja California Tijuana     1.79e6    29  2189 M02.03  Tijuana
## 5  2005         2 Baja California Playas de ~ 1.08e5     0    64 M02.03  Tijuana

POdemos asignar la selección a una nueva variable:

mun.bc <- filter(mundata, clave_ent==2)

Se pueden poenr más de una condición:

mun.peninsula.baja <- filter(mundata, clave_ent==2 | clave_ent==3)

podemos seleccionar los estados de la frontera norte:

estados.frontera <- c("Baja California",
                      "Sonora",
                      "Chihuahua",
                      "Coahuila",
                      "Nuevo León",
                      "Tamaulipas")

El operador %in% indica pertenencia a un conjunto:

mun.frontera <- filter(mundata, nom_ent %in% estados.frontera)

Para calcular el promedio de los habitantes que viven en Baja California será suficiente hacer:

summarise(mun.frontera, mpop=mean(pop))
## # A tibble: 1 x 1
##     mpop
##    <dbl>
## 1 83299.

Ejercicio 4

  • Crea un nuevo objeto que tenga a los municipios del Estado de México llamado “México” en la base de datos) y que además tenga más de 10,000 habitantes

  • Crea otro objeto que tenga a los municipios en los estados de la frontera y que tengan cada uno más de 100 camas de hospital (beds)

  • Crea un nuevo objeto que tenga a todos los municipios de México que tengan entre 10 y 20 UCI

Solución

mun.edo.mex <- filter(mundata, nom_ent=="México" & pop>10000)


mun.frontera.camas <- filter(mundata, nom_ent %in% estados.frontera & beds>100)

mun.uci <- filter(mundata, icu>=10 & icu <=20)

Ordenamiento y selecciñon

Arrange srive para ordenar los datos de acuerdo a una variable

arrange(mun.bc, beds)
## # A tibble: 5 x 9
##   clave clave_ent nom_ent         mun            pop   icu  beds cve_sun nom_sun
##   <dbl>     <dbl> <chr>           <chr>        <dbl> <dbl> <dbl> <chr>   <chr>  
## 1  2005         2 Baja California Playas de ~ 1.08e5     0    64 M02.03  Tijuana
## 2  2003         2 Baja California Tecate      1.14e5     0   112 M02.03  Tijuana
## 3  2001         2 Baja California Ensenada    5.36e5    14   520 M02.01  Ensena~
## 4  2002         2 Baja California Mexicali    1.09e6    32  1101 M02.02  Mexica~
## 5  2004         2 Baja California Tijuana     1.79e6    29  2189 M02.03  Tijuana
mun.bc <- arrange(mun.bc, beds)

Si añadimos la opcion desc obtenemos el orden descendente

mun.bc <- arrange(mun.bc, desc(beds))

Select permite seleccionar variables (columnas)

pob.mun <- select(mundata, clave, pop)

Mutate permite crear nuevas variables o columnas

mundata <- mutate(mundata, recursos=beds+icu)

if_else nos permite evaluar condicionales (lo veremos de nuevo en funciones)

mundata <- mutate(mundata,
                  frontera=ifelse(nom_ent %in% estados.frontera, 1, 0))

Ejercicio 5

#Genere un objeto que contenga los municipios del centro del pais (Ciudad de México, Estado de México, Puebla, Tlaxcala y Morelos)

En el nuevo objeto, genere una nueva variable que indique el logaritmo natural del numero de camas de hospital por cada 100,000 habitantes en dichos municipios

Solución

estados.centro <- c("Ciudad de México",
                    "México",
                    "Puebla",
                    "Tlaxcala",
                    "Morelos")

mun.centro <- filter(mundata, nom_ent %in% estados.centro)



mun.centro <- mutate(mun.centro,
                     lcamas100=log(beds*100000/pop))

Mas de dply

Con summarise podemos obtener estadisticas basicas:

Media

summarise(mundata, media.pop=mean(pop))
## # A tibble: 1 x 1
##   media.pop
##       <dbl>
## 1    52012.

Desviacion Estadar

summarise(mundata, sd.pop=sd(pop))
## # A tibble: 1 x 1
##    sd.pop
##     <dbl>
## 1 147554.

Con group_by podemos implementar funciones por subgrupos

por_estado <- group_by(mundata,clave_ent)
summarise(por_estado, media.pop=mean(pop))
## # A tibble: 32 x 2
##    clave_ent media.pop
##        <dbl>     <dbl>
##  1         1   130421.
##  2         2   726974.
##  3         3   160942.
##  4         4    90965.
##  5         5    84703.
##  6         6    78515.
##  7         7    48562.
##  8         8    56739.
##  9         9   563665.
## 10        10    47923.
## # ... with 22 more rows

Creamos un nuevo objeto con la media por estado

medias.estado <- summarise(por_estado, media.pop=mean(pop))

Variables de factores

Volvemos a cargar los datos para tener nuestra base original

mundata <- read_csv(file = "./mundata.csv",
                    locale = locale(encoding = "latin1"))
## Rows: 2457 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (4): nom_ent, mun, cve_sun, nom_sun
## dbl (5): clave, clave_ent, pop, icu, beds
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Seleccionamos todas las columnas de nuestro interes

mundata <- select(mundata,
                  -c("cve_sun","nom_sun"))

Generemos una nueva variable llamada region que tome los valores de acuerdo a la definición de regiones siguiente: * 1 para la region * 2 para la region centro * 3 para la region centro-occidente * 4 para la region sureste

estados.norte <- c("Baja California",
                   "Baja California Sur", 
                   "Chihuahua",
                   "Coahuila",
                   "Durango",
                   "Nuevo León",
                   "Sinaloa",
                   "Sonora",
                   "Tamaulipas")

estados.centro <- c("Ciudad de México",
                    "Guerrero",
                    "Hidalgo",
                    "México",
                    "Morelos",
                    "Puebla",
                    "Tlaxcala",
                    "Oaxaca")

estados.centroocc <- c("Aguascalientes",
                       "Colima",
                       "Guanajuato",
                       "Jalisco",
                       "Michoacán",
                       "Nayarit",
                       "Querétaro",
                       "San Luis Potosí",
                       "Zacatecas")

estados.sureste <- c("Campeche",
                     "Chiapas",
                     "Quintana Roo",
                     "Tabasco",
                     "Veracruz",
                     "Yucatán")

Creamos entonces una variable categorica para las cuatro regiones. Creamos una variable del 1 al 4 para las regiones

Usamos la función case_when

mundata <- mutate(mundata,
                  region=case_when(nom_ent %in% estados.norte ~ 1, 
                                   nom_ent %in% estados.centro ~ 2,
                                   nom_ent %in% estados.centroocc ~ 3,
                                   nom_ent %in% estados.sureste ~ 4))

Construimos un objeto que reporte el promedio del numero de camas por cada 100,000 habitantes de los municipios, por region

mundata <- mutate(mundata, camas100=beds*100000/pop)
por_region <- group_by(mundata,region)

camas.region <- summarise(por_region, media.camas100=mean(camas100))

Convertimos region a factor

mundata <- mutate(mundata,
                  region=factor(region,
                                levels = c(1,2,3,4),
                                labels = c("Región Norte",
                                           "Región Centro",
                                           "Región Centro-Occidente",
                                           "Region Sureste")))

levels(mundata$region)
## [1] "Región Norte"            "Región Centro"          
## [3] "Región Centro-Occidente" "Region Sureste"

La pipa

Haremos en un paso lo siguiente: nos quedaremos con un objeto de los municipios de la Region Centro, creamos una variable que sume las camas y las UCI, generamos una variable que indique que el municipio tiene recursos bajos si tiene menos de 100 recursos de salud y, finalmente, que nos de la proporcion de municipios por estado que se consideran de recursos bajos

mundata %>% 
  filter(region=="Región Centro") %>%
  mutate(recursos_totales=beds+icu) %>% 
  mutate(recursos_bajos=ifelse(recursos_totales<100,1,0)) %>%
  group_by(nom_ent) %>% 
  summarize(prop.bajos=mean(recursos_bajos)) %>% 
  ungroup()
## # A tibble: 8 x 2
##   nom_ent          prop.bajos
##   <chr>                 <dbl>
## 1 Ciudad de México      0.125
## 2 Guerrero              0.926
## 3 Hidalgo               0.905
## 4 México                0.8  
## 5 Morelos               0.879
## 6 Oaxaca               NA    
## 7 Puebla                0.940
## 8 Tlaxcala              0.933

Ponemos lo anterior en un objeto

rec.bajos.centro <- mundata %>% 
  filter(region=="Región Centro") %>%
  mutate(recursos_totales=beds+icu) %>% 
  mutate(recursos_bajos=ifelse(recursos_totales<100,1,0)) %>%
  group_by(nom_ent) %>% 
  summarize(prop.bajos=mean(recursos_bajos)) %>% 
  ungroup()

Podemos trabajar con NA

rec.bajos.centro <- mundata %>% 
  filter(region=="Región Centro") %>%
  mutate(recursos_totales=beds+icu) %>% 
  mutate(recursos_bajos=ifelse(recursos_totales<100,1,0)) %>%
  group_by(nom_ent) %>% 
  summarize(prop.bajos=mean(recursos_bajos, na.rm=TRUE)) %>% 
  ungroup()

Manejo bases

cargamos una nueva base con la Población municipal en dos bases de datos del CONAPO:

library(janitor)
## Warning: package 'janitor' was built under R version 4.0.5
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
filename<-"./base_municipios_final_datos_01.csv"
popdata1 <- read_csv(file=filename,
                     locale = locale(encoding = "latin1"))   %>% 
  clean_names() %>% 
  filter(ano==2020)
## Rows: 447104 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (4): NOM_ENT, MUN, SEXO, EDAD_QUIN
## dbl (5): RENGLON, CLAVE, CLAVE_ENT, AÑO, POB
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
filename<-"./base_municipios_final_datos_02.csv"
popdata2 <- read_csv(file = filename,
                     locale = locale(encoding = "latin1"))   %>% 
  clean_names() %>% 
  filter(ano==2020)
## Rows: 653632 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (4): NOM_ENT, MUN, SEXO, EDAD_QUIN
## dbl (5): RENGLON, CLAVE, CLAVE_ENT, AÑO, POB
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Apilamos las bases:

mundata <- bind_rows(popdata1,popdata2)

Creamos una base a nivel municipal sumando dentro de cada municipio las filas de hombres y mujeres y los grupos de edad

mundata <- mundata %>% 
  select(-c(renglon)) %>%
  mutate(nom_ent=ifelse(clave_ent==20,"Oaxaca",nom_ent)) %>% 
  group_by(clave, clave_ent, nom_ent, mun) %>% 
  summarize(pop=sum(pob,na.rm=TRUE)) %>% 
  arrange(clave) %>%
  ungroup()
## `summarise()` has grouped output by 'clave', 'clave_ent', 'nom_ent'. You can override using the `.groups` argument.

Otro pequeños ejercicios con los recursos de salud publicos

filename<-"./Recursos_Salud_2018.csv"

icudata <- read_csv(file=filename,
                    locale = locale(encoding = "latin1"))  %>% 
  select(c("Clave Estado", "Clave Municipio", "Número de camas en la Unidad de Cuidados Intensivos (incluye pediátricas y adulto)")) %>% 
  rename("cve_edo"="Clave Estado",
         "cve_mun"="Clave Municipio",
         "icu"="Número de camas en la Unidad de Cuidados Intensivos (incluye pediátricas y adulto)") %>% 
  mutate(clave = str_c(cve_edo, cve_mun)) %>% 
  mutate(clave=as.numeric(clave)) %>% 
  group_by(clave) %>% 
  summarize(icu=sum(icu,na.rm=TRUE)) %>% 
  ungroup()
## Rows: 22544 Columns: 233
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr  (12): CLUES, SECTOR, CLAVE INSTITUCIÓN, Clave Estado, Nombre Estado, Cl...
## dbl (221): AÑO, Número de unidades, ¿Cuenta con agua potable?, ¿Cuenta con r...
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Para obtener los recursos publicos y privados

filename<-"./ESTABLECIMIENTO_SALUD_202003.csv"
bedsdata <- read_csv(file = filename,
                     locale = locale(encoding = "latin1")) %>% 
  select(c("CLAVE DE LA ENTIDAD", "CLAVE DEL MUNICIPIO", "CAMAS EN AREA DE HOS")) %>% 
  rename("cve_edo"="CLAVE DE LA ENTIDAD",
         "cve_mun"="CLAVE DEL MUNICIPIO",
         "beds"="CAMAS EN AREA DE HOS") %>% 
  mutate(clave = str_c(cve_edo, cve_mun)) %>% 
  mutate(clave=as.numeric(clave)) %>% 
  group_by(clave) %>% 
  summarize(beds=sum(beds,na.rm=TRUE)) %>% 
  ungroup()
## Rows: 39829 Columns: 82
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr  (59): CLUES, NOMBRE DE LA ENTIDAD, CLAVE DE LA ENTIDAD, NOMBRE DEL MUNI...
## dbl  (17): ID, CLAVE TIPO ESTABLECIMIENTO, CLAVE SCIAN, CONSULTORIOS DE MED ...
## date  (6): FECHA EMISION AV. FUN., FECHA DE CONSTRUCCION, FECHA DE INICIO DE...
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Pegamos la base de UCI y de camas usando la clave del municipio:

hospitaldata <- left_join(icudata, bedsdata, by="clave")

Con datos del sistema urbano nacional (SUN)

filename<-"./Base_SUN_2018.csv"
sundata <- read_csv(file = filename,
                    locale = locale(encoding = "latin1"))   %>% 
  clean_names() %>% 
  mutate(tsun=substring(cve_sun,first=1,last=1)) %>% 
  filter(tsun=="M") %>% 
  select(-c("cve_ent", "cve_loc", "nom_loc", "pob_2018","tsun", "nom_ent","nom_mun")) %>% 
  mutate(clave=as.numeric(cve_mun)) %>% 
  select(-c("cve_mun"))
## Rows: 1089 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (8): CVE_ENT, NOM_ENT, CVE_MUN, NOM_MUN, CVE_LOC, NOM_LOC, CVE_SUN, NOM_SUN
## dbl (1): POB_2018
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Finalmente la Base municipal será:

mundata <- left_join(mundata,hospitaldata, by="clave")
mundata <- left_join(mundata,sundata, by="clave")

Para guardar un archivo en .csv haremos

write.csv(mundata,"./base_ejercicio.csv",
          row.names = FALSE)

Funciones

Las funciones son objetos que nos permiten hacer determinadas acciones pasandole cada vez distintos argumento.

Definamos la función para calcular el area de un circulo.

Esta funcion tiene un solo argumento, pues necesito un solo ingrediente para conocer el area de un circulo: su radio

area_circ <- function(radio){
  return(pi*radio^2)
}

La aplicamos para un circulo de radio 7

area_circ(radio=7)
## [1] 153.938

La función puede ser aplicada a cualquier objeto que represente el radio de un circulo (lo que a veces llamamos “pasar”)

r <- 4
area_circ(radio=r)
## [1] 50.26548

Que equivale a:

area_circ(r)
## [1] 50.26548

Ejercicio 6

Genere una funcion para calcular el area de un rectangulo y aplicala en caso de un rectangulo con base 6 y altura 4

Solución

area_rect <- function(base, altura){
  return(base*altura)
}


area_rect(base=6,altura=4)
## [1] 24
area_rect(6, 4)
## [1] 24

Que pasaría si le paso solo un argumento?

#area_rect(altura=4)

Numeros aleatorios

Generemos un vector aleatorio

x <- runif(20,0,100)
mean(x)
## [1] 53.46325

¿Que pasa si lo volvemos a generar

x <- runif(20,0,100)
mean(x)
## [1] 52.42434

Siendo que tenemos una componente aleatoria fijamos una semilla para poder replicar los numeros (semi) aleatorios

set.seed(123)
x <- runif(20,0,100)
mean(x)
## [1] 55.08084

Y si los volvemos a generar

x <- runif(20,0,100)
mean(x)
## [1] 57.67208

Simulamos una base de datos

datos <- tibble(
  a = rnorm(100),
  b = rnorm(100),
  c = rnorm(100),
  d = rnorm(100))

Y obtenemos su media y varainza:

mean(datos$a)
## [1] -0.009794948
sd(datos$a)
## [1] 0.881015

Estandardizacion

A veces necesitamos presentar las variables estandardizadas, osea con media cero y desciacion estandar 1

datos.modificados <- datos %>% 
  mutate(a=(a-mean(datos$a))/sd(datos$a))

Controlamos los resultados

mean(datos.modificados$a)
## [1] -0.00000000000000001141665
sd(datos.modificados$a)
## [1] 1

Podemos crear una función que estandardice cada variables

estandarizar <- function(insumo1){
  nuevo.dato <- (insumo1-mean(insumo1))/sd(insumo1)
}

La ocupamos por lo tanto para crear nuestras nuevas columnas con los datos standardizados

datos.estandarizados <- datos %>% 
  mutate(a=estandarizar(a)) %>%
  mutate(b=estandarizar(b)) %>% 
  mutate(c=estandarizar(c)) %>% 
  mutate(d=estandarizar(d))

Calculamos de nuevo media y varianza

mean(datos.estandarizados$d)
## [1] 0.00000000000000001361758
sd(datos.estandarizados$d)
## [1] 1

Estructuras de control

Creamos una funcion para para sacar el promedio de un vector de calificaciones

promedio.cide <- function(calificaciones) {
  mean(calificaciones)
}

Dado un vector de calificaciones

profes <- c(7,7.6,8.1,9.0)

Pasamos ahora el vector a la funcion

promedio.cide(calificaciones=profes)
## [1] 7.925

A veces pero algun profesor no entrega a tiempo

profes.tarde <- c(7,7.6,8.1,NA)

Como esta nuestra funcion, el resultado es…

promedio.cide(profes.tarde)
## [1] NA

Tenemos por lo tanto arreglar la función

promedio.cide2 <- function(calificaciones) {
  mean(calificaciones, na.rm=T)
}

Y tendremos:

promedio.cide2(profes.tarde)
## [1] 7.566667

if

La condición if la usamos if para evaluar si una condición es cierta, podemos combianrlas con el uso de los operadores logicos clasicos.

mensaje.alumno <- function(calificaciones) {
  
  media <- mean(calificaciones)
  
  if(media>=8) {
    print("Aprobado")
  }
  else {
    print("Reprobado")
  }
}

Por lo tanto tenremos que:

mensaje.alumno(profes)
## [1] "Reprobado"

Si pero pasamos un vector de calificaciones distinto, obtendremos:

profes.SS.cide <- c(9.5, 9, 10, 9.2)

mensaje.alumno(profes.SS.cide)
## [1] "Aprobado"

Podemos crear mensajes más complicados

mensaje.complejo.alumno <- function(calificaciones) {
  media <- mean(calificaciones)
  if(is.na(media)) {
    print("Nervio")
  }
  else{
    if(media>=8) {
      print("Aprobado")
    }
    else {
      print("Reprobado")
    }
  }
}

Por lo tanto pasando el primer vector a la nueva función obtendremos:

mensaje.complejo.alumno(profes.tarde)
## [1] "Nervio"

O en el casodel segundo vector:

mensaje.complejo.alumno(profes.SS.cide)
## [1] "Aprobado"

ifelse

Sirve para vectorizar el if y el else y que la comparacion se haga para cada elemento de un vector de valores

Supongamos que queremos una funcion por partes:

  • Para valores menores o iguales que 0, queremos que la funcion nos regrese -x

  • Para valores mayores que 0, queremos el cuadrado de x

partes <- function(x){
  ifelse(x<=0,-x,x^2)
}

Creamos el cevtor de datos

x <- seq(-5,5, by=0.1)

Aplicamos la función y plotemaos el resultados

resultado <- partes(x)

plot(x, resultado,
     type = "l",
     main = "Nuestra función f(x)",
     xlab = "x",
     ylab = "f(x)")

Ejercicio 7

Para el siguiente vector de promedios de alumnos, use ifelse para encontrar el mensaje que se le dara a cada uno

Solución

promedios.del.grupo <- c(7,8.2,8.0,9.2,7.3)

mensaje.grupo <- function(x){
  ifelse(x>=8, "Aprobado", "Reprobado")
}

#Y entonces:
mensaje.grupo(promedios.del.grupo)
## [1] "Reprobado" "Aprobado"  "Aprobado"  "Aprobado"  "Reprobado"

For

Nos permite realizar una operacion para un conjunto o rango de valores. A esto componemtes le conocemos como bacles, ciclos o “loops”

valores <- c(-1,-2,0,1,2)

for(entrada in valores) {
  print(entrada^2)
}
## [1] 1
## [1] 4
## [1] 0
## [1] 1
## [1] 4

En algunas aplicaciones nos será util ir guardando los resultados de la evaluacion

salida <- NULL

i <- 1
for(entrada in valores) {
  salida[i] <- entrada^2
  i <- i+1
}

salida
## [1] 1 4 0 1 4

Casi nunca hacemos esto pues muchas operaciones estan vectorizadas o podemos vectorizar las funciones

salida.facil <- valores^2

salida.facil
## [1] 1 4 0 1 4

While

Otra opción para hacer loops es el utlizo del while. Este ciclo sigue hasta que se llegue a una condicion especifica / umbral.

umbral <- 5
valor <- 0

while(valor < umbral) {
  print("Todavía no.")
  valor <- valor + 1
}
## [1] "Todavía no."
## [1] "Todavía no."
## [1] "Todavía no."
## [1] "Todavía no."
## [1] "Todavía no."

Hay que siempre prestar atención a las condiciones de cierre del ciclo.

La familia apply

Facilitan el trabajo: pasamos argumentos y funciones

Recordemos que tenemos

head(datos)
## # A tibble: 6 x 4
##        a      b       c      d
##    <dbl>  <dbl>   <dbl>  <dbl>
## 1 -1.07   0.118 -0.574   0.237
## 2 -0.218 -0.947  0.618   1.22 
## 3 -1.03  -0.491  1.11   -1.34 
## 4 -0.729 -0.256  0.708   0.661
## 5 -0.625  1.84  -0.364  -0.523
## 6 -1.69  -0.652  0.0597  0.684
mean(datos$a)
## [1] -0.009794948
sd(datos$a)
## [1] 0.881015

Y que tenemos una funcion para estandarizar

datos.estandarizados.facil <- apply(X = datos, MARGIN = 2, FUN = estandarizar)

Noten que el objeto que nos regresa apply es una matrix

class(datos.estandarizados.facil)
## [1] "matrix" "array"

Corroboramos los resultados

mean(datos.estandarizados.facil[,3])
## [1] 0.00000000000000003159853
sd(datos.estandarizados.facil[,3])
## [1] 1

Recuerda,ps que siempre MARGIN se refiere a: 1==filas y 2==columnas

Ejercicio 8

Usando apply, corrobore que en el data frame estandarizado, cada variable o columna tiene media 0 y desviacion estandar 1

Solución

apply(datos.estandarizados.facil, 2, mean)
##                           a                           b 
## -0.000000000000000011416649 -0.000000000000000007836613 
##                           c                           d 
##  0.000000000000000031598530  0.000000000000000013617579
apply(datos.estandarizados.facil, 2, sd)
## a b c d 
## 1 1 1 1

Una desventaja del apply es que nos devuelve un objeto del mismo tipo que la funcion aplicada

class(datos.estandarizados.facil)
## [1] "matrix" "array"

De algun modo hay que ponerlo de nuevo en data frame

datos.estandarizados.facil <- as_tibble(datos.estandarizados.facil)

Ahora nuestro objeto será:

class(datos.estandarizados.facil)
## [1] "tbl_df"     "tbl"        "data.frame"

lapply

Funciona como apply, pero nos devuelve una lista:

datos.estandarizados.lapply <- lapply(datos, estandarizar)

Controlamos el tipo de objeto:

class(datos.estandarizados.lapply)
## [1] "list"

De todas formas tenemos que convertirlo en data frame

Pero no tenemos que preocuparnos por el formato del la salida de lapply: siempre será una lista

datos.estandarizados.super.facil <- as_tibble(datos.estandarizados.lapply)

Exploracion Datos

Funciones basicas

Como vimos precedentemente cuando tenemos un dataframe podemos obrtener algunas caracteristicas utiles del mismo:

head(mundata)
## # A tibble: 6 x 9
##   clave clave_ent nom_ent        mun           pop   icu  beds cve_sun nom_sun  
##   <dbl>     <dbl> <chr>          <chr>       <dbl> <dbl> <dbl> <chr>   <chr>    
## 1  1001         1 Aguascalientes Aguascali~ 961977    44  1022 M01.01  Aguascal~
## 2  1002         1 Aguascalientes Asientos    50864     0     0 <NA>    <NA>     
## 3  1003         1 Aguascalientes Calvillo    60760     0    30 <NA>    <NA>     
## 4  1004         1 Aguascalientes Cosío       16918     0     0 <NA>    <NA>     
## 5  1005         1 Aguascalientes Jesús Mar~ 130184    12   144 M01.01  Aguascal~
## 6  1006         1 Aguascalientes Pabellón ~  50032     0    30 <NA>    <NA>
dim(mundata)
## [1] 2457    9
nrow(mundata)
## [1] 2457
ncol(mundata)
## [1] 9
mean(mundata$beds)
## [1] NA
mean(mundata$beds, na.rm=TRUE)
## [1] 53.1148
mean(mundata$beds, na.rm=T)
## [1] 53.1148
sd(mundata$beds, na.rm=T)
## [1] 269.638
max(mundata$beds, na.rm=T)
## [1] 5337

Si queremos una base que indique el promedio de camas por estado:

aggregate(mundata$beds,
          by=list(Estado=mundata$nom_ent),
          mean)
##                 Estado          x
## 1       Aguascalientes  114.27273
## 2      Baja California  797.20000
## 3  Baja California Sur  218.40000
## 4             Campeche   82.00000
## 5              Chiapas   29.68644
## 6            Chihuahua   68.61194
## 7     Ciudad de México 1365.87500
## 8             Coahuila   93.44737
## 9               Colima   88.30000
## 10             Durango   51.23077
## 11          Guanajuato   99.02174
## 12            Guerrero   29.04938
## 13             Hidalgo   35.16667
## 14             Jalisco   73.92000
## 15              México   86.42400
## 16           Michoacán   46.05310
## 17             Morelos   46.27273
## 18             Nayarit   62.35000
## 19          Nuevo León  134.82353
## 20              Oaxaca         NA
## 21              Puebla   34.26267
## 22           Querétaro  121.66667
## 23        Quintana Roo  140.90000
## 24     San Luis Potosí   49.82759
## 25             Sinaloa  198.38889
## 26              Sonora   50.83333
## 27             Tabasco  118.76471
## 28          Tamaulipas  107.88372
## 29            Tlaxcala   18.41667
## 30            Veracruz   29.11792
## 31             Yucatán         NA
## 32           Zacatecas   19.24138
mean.camas.mun <- aggregate(mundata$beds,
                            by=list(Estado=mundata$nom_ent),
                            mean)

El problemas es que hay nan, entonces arreglamos con na.rm:

aggregate(mundata$beds,
          by=list(Estado=mundata$nom_ent),
          mean,
          na.rm=T)
##                 Estado           x
## 1       Aguascalientes  114.272727
## 2      Baja California  797.200000
## 3  Baja California Sur  218.400000
## 4             Campeche   82.000000
## 5              Chiapas   29.686441
## 6            Chihuahua   68.611940
## 7     Ciudad de México 1365.875000
## 8             Coahuila   93.447368
## 9               Colima   88.300000
## 10             Durango   51.230769
## 11          Guanajuato   99.021739
## 12            Guerrero   29.049383
## 13             Hidalgo   35.166667
## 14             Jalisco   73.920000
## 15              México   86.424000
## 16           Michoacán   46.053097
## 17             Morelos   46.272727
## 18             Nayarit   62.350000
## 19          Nuevo León  134.823529
## 20              Oaxaca    4.457505
## 21              Puebla   34.262673
## 22           Querétaro  121.666667
## 23        Quintana Roo  140.900000
## 24     San Luis Potosí   49.827586
## 25             Sinaloa  198.388889
## 26              Sonora   50.833333
## 27             Tabasco  118.764706
## 28          Tamaulipas  107.883721
## 29            Tlaxcala   18.416667
## 30            Veracruz   29.117925
## 31             Yucatán   23.742857
## 32           Zacatecas   19.241379
mean.camas.mun <- aggregate(mundata$beds,
                            by=list(Estado=mundata$nom_ent),
                            mean,
                            na.rm=T)

Tenemos que arreglar los nombres:

mean.camas.mun <- set_names(mean.camas.mun, c("Estado", "media.camas"))

Hacemos ahora un subgrupo del data frame, tomando estados de la peninsula de Baja California

mundata.baja <- subset(mundata,
                       nom_ent %in% c("Baja California","Baja California Sur"),
                       select=c(nom_ent,mun, pop, beds, icu))

Y luego podemos calcular la media entre municipios de cada uno de los dos estados:

mean.camas.baja <- aggregate(mundata.baja$beds,
                             by=list(Estado=mundata.baja$nom_ent),
                             mean,
                             na.rm=T)

Y tendriamos que arreglar los nombres

Todo esto es más fácil con las pipas

subset(mundata,
       nom_ent %in% c("Baja California","Baja California Sur"),
       select=c(nom_ent,mun, pop, beds, icu)) %>% 
  group_by(nom_ent) %>% 
  summarise(media.camas=mean(beds)) %>% 
  ungroup()
## # A tibble: 2 x 2
##   nom_ent             media.camas
##   <chr>                     <dbl>
## 1 Baja California            797.
## 2 Baja California Sur        218.

Podemos calcular varias estadisticas

tabla.desc <- subset(mundata,
                     nom_ent %in% c("Baja California","Baja California Sur"),
                     select=c(nom_ent,mun, pop, beds, icu)) %>% 
  group_by(nom_ent) %>% 
  summarise(media.camas=mean(beds),
            de.camas=sd(beds),
            obs.camas=n(),
            min.camas=min(beds),
            max.camas=max(beds)) %>% 
  ungroup()

Estadística a distintos niveles

A nivel SUN

sundata <- mundata %>% 
  filter(!is.na(cve_sun)) %>% 
  group_by(cve_sun, nom_sun) %>% 
  summarise(pop=sum(pop,na.rm=TRUE),
            beds=sum(beds,na.rm=TRUE),
            icu=sum(icu,na.rm=TRUE)) %>% 
  ungroup()
## `summarise()` has grouped output by 'cve_sun'. You can override using the `.groups` argument.

A nivel estado

statedata <- mundata %>% 
  group_by(clave_ent, nom_ent) %>% 
  summarise(pop=sum(pop,na.rm=TRUE),
            beds=sum(beds,na.rm=TRUE),
            icu=sum(icu,na.rm=TRUE)) %>% 
  arrange(clave_ent) %>%
  ungroup() 
## `summarise()` has grouped output by 'clave_ent'. You can override using the `.groups` argument.

Total nacional

statedata %>% 
  summarise(pop=sum(pop,na.rm=TRUE),
            beds=sum(beds,na.rm=TRUE),
            icu=sum(icu,na.rm=TRUE)) 
## # A tibble: 1 x 3
##         pop   beds   icu
##       <dbl>  <dbl> <dbl>
## 1 127792286 129547  3826

Ejercicio 9

Genere un nuevo data frame que incluya el total de poblacion, camas y UCI de cada estado y su participacion porcentual respecto a los totales nacionalesda variable o columna tiene media 0 y desviacion estandar 1

Solución

statedata.con.porcentajes <- statedata %>% 
  mutate(pop.nal=sum(pop,na.rm=TRUE),
            beds.nal=sum(beds,na.rm=TRUE),
            icu.nal=sum(icu,na.rm=TRUE)) %>% 
  mutate(p.pop=pop/pop.nal,
         p.beds=beds/beds.nal,
         p.icu=icu/icu.nal)

Gráficos

Volvemos a cargar nuestra base de dtos para elminar todas las modificaciones

mundata <- read_csv(file = "./mundata.csv",
                                      locale = locale(encoding = "latin1"))
## Rows: 2457 Columns: 9
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (4): nom_ent, mun, cve_sun, nom_sun
## dbl (5): clave, clave_ent, pop, icu, beds
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Ggplot es una de las libreria más complet para garaficar. Podemos crear diferentes tipos de grafico:

Gráfico de puntos

ggplot(data=mundata)+
  geom_point(mapping = aes(x=pop, y=beds))
## Warning: Removed 18 rows containing missing values (geom_point).

Podemos cambiar el color del punto

ggplot(data=mundata)+
  geom_point(mapping = aes(x=pop, y=beds),
             color = "lightsalmon1")
## Warning: Removed 18 rows containing missing values (geom_point).

Cambiamos el tamaño del marcador:

ggplot(data=mundata)+
  geom_point(mapping = aes(x=pop, y=beds),
             color = "lightsalmon1",
             size = 4)
## Warning: Removed 18 rows containing missing values (geom_point).

Graficamos la tendencia lineal

ggplot(data=mundata)+
  geom_smooth(method="lm",
              mapping = aes(x=pop, y=beds))
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 18 rows containing non-finite values (stat_smooth).

PPodemos poner los dos tipos de grafico juntos:

ggplot(data=mundata)+
  geom_point(mapping = aes(x=pop, y=beds),
             size = 2)+
  geom_smooth(method="lm",
              mapping = aes(x=pop, y=beds))
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 18 rows containing non-finite values (stat_smooth).
## Warning: Removed 18 rows containing missing values (geom_point).

La tendenciaa por defecto es un “suavizador”, que estudiaremos con detalle en metodos no parametricos

ggplot(data=mundata,
       aes(x=pop, y=beds))+
  geom_point(color = "blue",
             size = 1)+
  geom_smooth(color = "red",
              linetype="dotted")
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
## Warning: Removed 18 rows containing non-finite values (stat_smooth).
## Warning: Removed 18 rows containing missing values (geom_point).

Para apreciar mejor el suavizador, restringimos a los municipios con más de 200,000 habitantes

ggplot(data=filter(mundata,pop>200000),
       aes(x=pop, y=beds))+
  geom_point(color = "blue",
             size = 1)+
  geom_smooth(color = "red",
              linetype="dotted")
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Facetas

A veces nos es útil graficar por grupos

estados.norte <- c("Baja California",
                   "Baja California Sur", 
                   "Chihuahua",
                   "Coahuila",
                   "Durango",
                   "Nuevo León",
                   "Sinaloa",
                   "Sonora",
                   "Tamaulipas")

estados.centro <- c("Ciudad de México",
                    "Guerrero",
                    "Hidalgo",
                    "México",
                    "Morelos",
                    "Puebla",
                    "Tlaxcala",
                    "Oaxaca")

estados.centroocc <- c("Aguascalientes",
                       "Colima",
                       "Guanajuato",
                       "Jalisco",
                       "Michoacán",
                       "Nayarit",
                       "Querétaro",
                       "San Luis Potosí",
                       "Zacatecas")

estados.sureste <- c("Campeche",
                     "Chiapas",
                     "Quintana Roo",
                     "Tabasco",
                     "Veracruz",
                     "Yucatán")

Le asignamos el nombre de la región correspondiente:

mundata <- mutate(mundata,
                  region=case_when(nom_ent %in% estados.norte ~ "Norte", 
                                   nom_ent %in% estados.centro ~ "Centro",
                                   nom_ent %in% estados.centroocc ~ "Centro - occidente",
                                   nom_ent %in% estados.sureste ~ "Sureste"))

Y entonces podemos hacer cuatro gráficos, uno para cada región

ggplot(data=mundata,
       aes(x=pop, y=beds))+
  geom_point(color="red")+
  facet_wrap(~ region, ncol=2)
## Warning: Removed 18 rows containing missing values (geom_point).

Recuerden que no es necesario poner siempre el nombre de los argumentos:

ggplot(mundata,
       aes(pop, beds))+
  geom_point(color="red", size=2)+
  geom_smooth(method="lm", color="black")+
  facet_wrap(~ region, ncol=2)
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 18 rows containing non-finite values (stat_smooth).
## Warning: Removed 18 rows containing missing values (geom_point).

Gráficas de barras

Gráfico básico: cuenta el número de casos en cada categoría

ggplot(data=mundata)+
  geom_bar(aes(x=region))

De nuevo podemos modificar el color de relleno:

ggplot(data=mundata)+
  geom_bar(aes(x=region),
           fill="red")

Y podemos poner la proporción:

ggplot(data=mundata)+
  geom_bar(aes(x=region,
               y=stat(prop),
               group=1))

Podemos hacer que cada barra tenga su color:

ggplot(data=mundata)+
  geom_bar(aes(x=region,
               fill=region))

Boxplot

Para que no haya tantos puntos, voy a usar solo municipios que se consideran parte del sistema urbano nacional

ggplot(filter(mundata,!is.na(nom_sun))) + 
  geom_boxplot(aes(region,pop))

A veces tiene sentido rotar los ejes

ggplot(filter(mundata,!is.na(nom_sun))) + 
  geom_boxplot(aes(region,pop))+
  coord_flip()

En ?geom_boxplot^ para saber más sobre esta grafíca:

  • La caja: cuantiles 1 y 3 (25 y 75% de la distribución)
  • Línea en medio de la caja: mediana
  • Cada recta se extiende desde el extremo de la caja y hasta 1.5 veces el rango inter cuartil

Tenemos una base que reporta estadísticas agregadas de COVID-19 en México por oleada

waves.data <- read_csv(file = "./waves_data.csv",
                       locale = locale(encoding = "latin1"))
## Rows: 27 Columns: 3
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (2): wave, type
## dbl (1): hospital.stats
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.

Estetica

Ahora exploremos como combinar la información de variables para dar formato a las gráficas. aes() controla la estetica

La estetica controla las propiedades visuales

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_point(mapping = aes(x=pop,
                           y=beds,
                           color=region))

Otra estetica es la forma del marcador

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_point(mapping = aes(x=pop,
                           y=beds,
                           shape=region))
## Warning: Removed 103 rows containing missing values (geom_point).

La transparencia del marcador

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_point(mapping = aes(x=pop,
                           y=beds,
                           alpha=region))
## Warning: Using alpha for a discrete variable is not advised.

Podemos combinarlos

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_point(mapping = aes(x=pop,
                           y=beds,
                           shape=region,
                           color=region))
## Warning: Removed 103 rows containing missing values (geom_point).

Histograma

Más empleado cuando tenemos una variable continua

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_histogram(aes(pop))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Binwidth controla el ancho de cada barra:

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_histogram(aes(pop), binwidth = 100000)

Usamos lineas

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_freqpoly(aes(pop), binwidth = 100000)

Podemos usar ambos juntos

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_histogram(aes(pop), binwidth = 100000)+
  geom_freqpoly(aes(pop), binwidth = 100000)

Agreguemos ahora una dimensión categórica

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_freqpoly(aes(pop, color=region),
                binwidth = 100000)

Ahora con el tipo de línea

ggplot(filter(mundata,!is.na(nom_sun)))+
  geom_freqpoly(aes(pop, linetype=region),
                binwidth = 100000)

Formato

Damos un poco de formato a la gráfica para hacerla #más fácil de leer

Relación básica

ggplot(filter(mundata,!is.na(nom_sun))) +
  geom_point(mapping = aes(x=pop, y=beds))

Nombres de los ejes:

ggplot(filter(mundata,!is.na(nom_sun))) +
  geom_point(mapping = aes(x=pop, y=beds)) +
  xlab("Población municipal") +
  ylab("Número de camas")

Añadimos colores para las regiones y coloquemos un título apropiado a la leyenda

ggplot(filter(mundata,!is.na(nom_sun))) +
  geom_point(mapping = aes(x=pop, y=beds, color=region)) +
  xlab("Población municipal") +
  ylab("Número de camas")+
  labs(colour="Región")

Podemos incluir líneas de referencia

ggplot(filter(mundata,!is.na(nom_sun))) +
  geom_point(mapping = aes(x=pop, y=beds, color=region)) +
  xlab("Población municipal") +
  ylab("Número de camas")+
  labs(colour="Región")+
  geom_hline(aes(yintercept=2000), color="black", linetype="dashed")

Agregamos título, subtítulo y notas

ggplot(filter(mundata,!is.na(nom_sun))) +
  geom_point(mapping = aes(x=pop, y=beds, color=region)) +
  xlab("Población municipal") +
  ylab("Número de camas")+
  geom_hline(aes(yintercept=2000), color="black", linetype="dashed") +
  labs(colour="Región",
       title="Relación entre población y camas de hospital en los municipios de México",
       subtitle="Municipios que pertenecen a una ciudad del SUN",
       caption="Nota: ver Hernández y Rojas (2020) para mayores detalles.")

Usemos guides y theme para darle formato a la legenda

ggplot(filter(mundata,!is.na(nom_sun))) +
  geom_point(mapping = aes(x=pop, y=beds, color=region)) +
  xlab("Población municipal") +
  ylab("Número de camas")+
  geom_hline(aes(yintercept=2000), color="black", linetype="dashed") +
  labs(colour="Región",
       title="Relación entre población y camas de hospital en los municipios de México",
       subtitle="Municipios que pertenecen a una ciudad del SUN",
       caption="Nota: ver Hernández y Rojas (2020) para mayores detalles.")+
  theme(legend.position="bottom")+
  guides(colour=guide_legend(nrow=2))

Finalmente, para guardar nuestra grafica:

ggsave("./vuelos.png")
## Saving 7 x 5 in image