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).
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:
Luego definimos la directory donde iremos trabajando:
Si preferimos podemos evitar el utilizo de la notación cientifica de default:
Y pasar los elementos graficos a una ventana independiente:
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:
## 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()
Cuando queremos asignar un valor a una constante lo haremos de la siguiente forma:
El sistema asignará a las constantes designada los valores correspectivos y podremos utilizarlas para hacer las operaciones que queremos:
Que resultados obtendremos?
## [1] 13
## [1] -1
## [1] 42
## [1] 0.8571429
## [1] 279936
Para imprimir un elemento es suficiente escribirlo en el editor del codigo o en la consola.
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
¿Que pasa si el rectangulo ahora tiene una altura de 5? Genere la nueva area area.rect.2
Podemos definir un vector de la siguiente forma
Podemos hacer operaciones con los vectores, como multiplicarlo por un escalar:
## [1] 6 8 10
Nuestros vectores pueden ser compuestos por cadenas:
## [1] "Pedro" "Andrea" "Ana"
Para obtner una matriz especificamos un vector y las dimeniones de la matriz misma:
## [,1] [,2] [,3]
## [1,] 4 1 0
## [2,] -2 6 5
No es necesario siempre especificar el nombre del argumento:
## [,1] [,2] [,3]
## [1,] 4 1 0
## [2,] -2 6 5
Se pueden hacer operaciones con las matrices así como hicimos con los vectores:
## [,1] [,2] [,3]
## [1,] 8 2 0
## [2,] -4 12 10
R incluye en su funciones basicas unas para obtener informaciones estadisticas con respecto a nuestras variables (i.e. vectores)
Media
## [1] 4
si no conocemos la sintaxis y las caracteristicas de una funcion podemos utilizar la siguiente expresión:
## starting httpd help server ... done
Mediana, Varianza, Desviación Estandar, Standard Score (Z-Score)
## [1] 4
## [1] 1
## [1] 1
## [,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
Que curva obtendremos?
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:
## 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:
## 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:
## [1] "clave" "clave_ent" "nom_ent" "mun" "pop" "icu"
## [7] "beds" "cve_sun" "nom_sun"
Las primeras filas:
## # 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:
## # 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:
## # 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:
## [1] 2457 9
Si quermos saber el numero de filas de nuestra matriz podemos utilizar la siguinete función:
## [1] 2457
Mintras para las columnas será:
## [1] 9
Para saber la estructura de nuestro database podemos utilizar:
## 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>
Podemos filtrar nuestra base de datos:
## # 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:
Se pueden poenr más de una condición:
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:
Para calcular el promedio de los habitantes que viven en Baja California será suficiente hacer:
## # A tibble: 1 x 1
## mpop
## <dbl>
## 1 83299.
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
Arrange srive para ordenar los datos de acuerdo a una variable
## # 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
Si añadimos la opcion desc obtenemos el orden descendente
Select permite seleccionar variables (columnas)
Mutate permite crear nuevas variables o columnas
if_else nos permite evaluar condicionales (lo veremos de nuevo en funciones)
#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
Con summarise podemos obtener estadisticas basicas:
Media
## # A tibble: 1 x 1
## media.pop
## <dbl>
## 1 52012.
Desviacion Estadar
## # A tibble: 1 x 1
## sd.pop
## <dbl>
## 1 147554.
Con group_by podemos implementar funciones por subgrupos
## # 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
Volvemos a cargar los datos para tener nuestra base original
## 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
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"
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
cargamos una nueva base con la Población municipal en dos bases de datos del CONAPO:
## 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:
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:
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
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
La aplicamos para un circulo de 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”)
## [1] 50.26548
Que equivale a:
## [1] 50.26548
Genere una funcion para calcular el area de un rectangulo y aplicala en caso de un rectangulo con base 6 y altura 4
## [1] 24
## [1] 24
Que pasaría si le paso solo un argumento?
Generemos un vector aleatorio
## [1] 53.46325
¿Que pasa si lo volvemos a generar
## [1] 52.42434
Siendo que tenemos una componente aleatoria fijamos una semilla para poder replicar los numeros (semi) aleatorios
## [1] 55.08084
Y si los volvemos a generar
## [1] 57.67208
Simulamos una base de datos
Y obtenemos su media y varainza:
## [1] -0.009794948
## [1] 0.881015
A veces necesitamos presentar las variables estandardizadas, osea con media cero y desciacion estandar 1
Controlamos los resultados
## [1] -0.00000000000000001141665
## [1] 1
Podemos crear una función que estandardice cada variables
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
## [1] 0.00000000000000001361758
## [1] 1
Creamos una funcion para para sacar el promedio de un vector de calificaciones
Dado un vector de calificaciones
Pasamos ahora el vector a la funcion
## [1] 7.925
A veces pero algun profesor no entrega a tiempo
Como esta nuestra funcion, el resultado es…
## [1] NA
Tenemos por lo tanto arreglar la función
Y tendremos:
## [1] 7.566667
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:
## [1] "Reprobado"
Si pero pasamos un vector de calificaciones distinto, obtendremos:
## [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:
## [1] "Nervio"
O en el casodel segundo vector:
## [1] "Aprobado"
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
Creamos el cevtor de datos
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)")
Para el siguiente vector de promedios de alumnos, use ifelse para encontrar el mensaje que se le dara a cada uno
Nos permite realizar una operacion para un conjunto o rango de valores. A esto componemtes le conocemos como bacles, ciclos o “loops”
## [1] 1
## [1] 4
## [1] 0
## [1] 1
## [1] 4
En algunas aplicaciones nos será util ir guardando los resultados de la evaluacion
## [1] 1 4 0 1 4
Casi nunca hacemos esto pues muchas operaciones estan vectorizadas o podemos vectorizar las funciones
## [1] 1 4 0 1 4
Otra opción para hacer loops es el utlizo del while. Este ciclo sigue hasta que se llegue a una condicion especifica / umbral.
## [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.
Facilitan el trabajo: pasamos argumentos y funciones
Recordemos que tenemos
## # 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
## [1] -0.009794948
## [1] 0.881015
Y que tenemos una funcion para estandarizar
Noten que el objeto que nos regresa apply es una matrix
## [1] "matrix" "array"
Corroboramos los resultados
## [1] 0.00000000000000003159853
## [1] 1
Recuerda,ps que siempre MARGIN se refiere a: 1==filas y 2==columnas
Usando apply, corrobore que en el data frame estandarizado, cada variable o columna tiene media 0 y desviacion estandar 1
## a b
## -0.000000000000000011416649 -0.000000000000000007836613
## c d
## 0.000000000000000031598530 0.000000000000000013617579
## 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
## [1] "matrix" "array"
De algun modo hay que ponerlo de nuevo en data frame
Ahora nuestro objeto será:
## [1] "tbl_df" "tbl" "data.frame"
Funciona como apply, pero nos devuelve una lista:
Controlamos el tipo de objeto:
## [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
Como vimos precedentemente cuando tenemos un dataframe podemos obrtener algunas caracteristicas utiles del mismo:
## # 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>
## [1] 2457 9
## [1] 2457
## [1] 9
## [1] NA
## [1] 53.1148
## [1] 53.1148
## [1] 269.638
## [1] 5337
Si queremos una base que indique el promedio de camas por estado:
## 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
El problemas es que hay nan, entonces arreglamos con na.rm:
## 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
Tenemos que arreglar los nombres:
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
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
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
Volvemos a cargar nuestra base de dtos para elminar todas las modificaciones
## 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
## Warning: Removed 18 rows containing missing values (geom_point).
Podemos cambiar el color del punto
## Warning: Removed 18 rows containing missing values (geom_point).
Cambiamos el tamaño del marcador:
## Warning: Removed 18 rows containing missing values (geom_point).
Graficamos la tendencia lineal
## `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'
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
## 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áfico básico: cuenta el número de casos en cada categoría
De nuevo podemos modificar el color de relleno:
Y podemos poner la proporción:
Podemos hacer que cada barra tenga su color:
Para que no haya tantos puntos, voy a usar solo municipios que se consideran parte del sistema urbano nacional
A veces tiene sentido rotar los ejes
En ?geom_boxplot^ para saber más sobre esta grafíca:
Tenemos una base que reporta estadísticas agregadas de COVID-19 en México por oleada
## 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.
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
Otra estetica es la forma del marcador
## Warning: Removed 103 rows containing missing values (geom_point).
La transparencia del marcador
## 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).
Más empleado cuando tenemos una variable continua
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Binwidth controla el ancho de cada barra:
Usamos lineas
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
Ahora con el tipo de línea
Damos un poco de formato a la gráfica para hacerla #más fácil de leer
Relación básica
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:
## Saving 7 x 5 in image