- Paquetes:
dplyrotidyversegapminder
dplyr o tidyversegapminderCrea un nuevo proyecto llamado: 06-ejercicios
Crea un nuevo documento R Markdown en el que vas a tomar nota e ir resolviendo los ejercicios.
Carguemos los paquetes que necesitaremos en esta sesión.
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5 v purrr 0.3.4 ## v tibble 3.1.2 v dplyr 1.0.7 ## v tidyr 1.1.3 v stringr 1.4.0 ## v readr 1.4.0 v forcats 0.5.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() -- ## x dplyr::filter() masks stats::filter() ## x dplyr::lag() masks stats::lag()
library(gapminder)
Hasta el momento hemos aprendido a:
rename()relocate()select().filter().arrange().En esta sesión aprenderás a:
mutate().summarise().group_by().Adicionalmente, aprenderás a usar el operador pipe (%>%), que permite combinar todas las operaciones en un solo flujo.
Para entender lo que sucede con estas funciones, crearemos el conjunto gapminder_subset. Obtenemos observaciones para cuatro países en dos años observados.
gapminder_subset <- filter(gapminder,
country %in% c("Peru", "Mexico", "United Kingdom", "France"),
year >= 2002)
gapminder_subset
## # A tibble: 8 x 6 ## country continent year lifeExp pop gdpPercap ## <fct> <fct> <int> <dbl> <int> <dbl> ## 1 France Europe 2002 79.6 59925035 28926. ## 2 France Europe 2007 80.7 61083916 30470. ## 3 Mexico Americas 2002 74.9 102479927 10742. ## 4 Mexico Americas 2007 76.2 108700891 11978. ## 5 Peru Americas 2002 69.9 26769436 5909. ## 6 Peru Americas 2007 71.4 28674757 7409. ## 7 United Kingdom Europe 2002 78.5 59912431 29479. ## 8 United Kingdom Europe 2007 79.4 60776238 33203.
mutate()Esta función se usa para modificar las variables de nuestro conjunto de datos, ya sea para transformar una variable existente o para crear una nueva. Debemos identificar dos cosas:
mutate(data, var_objetivo = operacion(var_existente))
La operación debe hacerse en una variable existente. Si la variable objetivo ya existe en el conjunto de datos, la será sobreescrita.
En gapminder_subset contamos con información del PBI per cápita y población. Multiplicando ambas podemos tener el PBI total de un país para determinado año.
mutate(gapminder_subset, pbi_total = pop * gdpPercap)
## # A tibble: 8 x 7 ## country continent year lifeExp pop gdpPercap pbi_total ## <fct> <fct> <int> <dbl> <int> <dbl> <dbl> ## 1 France Europe 2002 79.6 59925035 28926. 1.73e12 ## 2 France Europe 2007 80.7 61083916 30470. 1.86e12 ## 3 Mexico Americas 2002 74.9 102479927 10742. 1.10e12 ## 4 Mexico Americas 2007 76.2 108700891 11978. 1.30e12 ## 5 Peru Americas 2002 69.9 26769436 5909. 1.58e11 ## 6 Peru Americas 2007 71.4 28674757 7409. 2.12e11 ## 7 United Kingdom Europe 2002 78.5 59912431 29479. 1.77e12 ## 8 United Kingdom Europe 2007 79.4 60776238 33203. 2.02e12
Hemos logrado calcular una nueva variable en base a otras ya existentes.
Ya que la población es un número bastante grande, R nos muestra el tibble en notación científica (1.73e12 significa que el punto decimal ha sido “adelantado” 12 cifras).
Ten en cuenta que si la operación retorna un solo valor, este será repetido en todas las filas de esa variable.
mutate(gapminder_subset, maxima_pob = max(pop))
## # A tibble: 8 x 7 ## country continent year lifeExp pop gdpPercap maxima_pob ## <fct> <fct> <int> <dbl> <int> <dbl> <int> ## 1 France Europe 2002 79.6 59925035 28926. 108700891 ## 2 France Europe 2007 80.7 61083916 30470. 108700891 ## 3 Mexico Americas 2002 74.9 102479927 10742. 108700891 ## 4 Mexico Americas 2007 76.2 108700891 11978. 108700891 ## 5 Peru Americas 2002 69.9 26769436 5909. 108700891 ## 6 Peru Americas 2007 71.4 28674757 7409. 108700891 ## 7 United Kingdom Europe 2002 78.5 59912431 29479. 108700891 ## 8 United Kingdom Europe 2007 79.4 60776238 33203. 108700891
Cuando queremos recategorizar una variable de manera dicotómica, podemos usar la función if_else(). Sirve para testear una condición, que de ser verdadera asume el primer valor, y en caso contrario el segundo.
Por ejemplo, para traducir el nombre de nuestros continentes.
mutate(gapminder_subset, traduccion = if_else(continent == "Europe", "Europa", "América"))
## # A tibble: 8 x 7 ## country continent year lifeExp pop gdpPercap traduccion ## <fct> <fct> <int> <dbl> <int> <dbl> <chr> ## 1 France Europe 2002 79.6 59925035 28926. Europa ## 2 France Europe 2007 80.7 61083916 30470. Europa ## 3 Mexico Americas 2002 74.9 102479927 10742. América ## 4 Mexico Americas 2007 76.2 108700891 11978. América ## 5 Peru Americas 2002 69.9 26769436 5909. América ## 6 Peru Americas 2007 71.4 28674757 7409. América ## 7 United Kingdom Europe 2002 78.5 59912431 29479. Europa ## 8 United Kingdom Europe 2007 79.4 60776238 33203. Europa
Si usamos el mismo nombre que el de una variable existente, nuestra variable será sobreescrita con sus nuevos valores.
mutate(gapminder_subset, lifeExp = if_else(lifeExp >= 75, "70 o más", "Menos que 70"))
## # A tibble: 8 x 6 ## country continent year lifeExp pop gdpPercap ## <fct> <fct> <int> <chr> <int> <dbl> ## 1 France Europe 2002 70 o más 59925035 28926. ## 2 France Europe 2007 70 o más 61083916 30470. ## 3 Mexico Americas 2002 Menos que 70 102479927 10742. ## 4 Mexico Americas 2007 70 o más 108700891 11978. ## 5 Peru Americas 2002 Menos que 70 26769436 5909. ## 6 Peru Americas 2007 Menos que 70 28674757 7409. ## 7 United Kingdom Europe 2002 70 o más 59912431 29479. ## 8 United Kingdom Europe 2007 70 o más 60776238 33203.
En ocasiones, será necesario que la recategorización asuma más de dos posibles valores. En estos casos, usamos la función case_when() que permite testear múltiples condiciones. Para abarcar las observaciones que no cumplan ninguna condición, se usa el valor TRUE.
mutate(gapminder_subset, exp_recat = case_when(lifeExp <= 70 ~ "Menor o igual a 70",
lifeExp <= 75 ~ "Entre 71 y 75",
TRUE ~ "Mayor que 75"))
## # A tibble: 8 x 7 ## country continent year lifeExp pop gdpPercap exp_recat ## <fct> <fct> <int> <dbl> <int> <dbl> <chr> ## 1 France Europe 2002 79.6 59925035 28926. Mayor que 75 ## 2 France Europe 2007 80.7 61083916 30470. Mayor que 75 ## 3 Mexico Americas 2002 74.9 102479927 10742. Entre 71 y 75 ## 4 Mexico Americas 2007 76.2 108700891 11978. Mayor que 75 ## 5 Peru Americas 2002 69.9 26769436 5909. Menor o igual a 70 ## 6 Peru Americas 2007 71.4 28674757 7409. Entre 71 y 75 ## 7 United Kingdom Europe 2002 78.5 59912431 29479. Mayor que 75 ## 8 United Kingdom Europe 2007 79.4 60776238 33203. Mayor que 75
Es posible testear condiciones en valores que se calculan “al vuelo”. Por ejemplo, recategorizar valores que son mayores que el promedio.
mutate(gapminder_subset, mayor_que_promedio = if_else(lifeExp > mean(lifeExp), "Es mayor", "No es mayor"))
## # A tibble: 8 x 7 ## country continent year lifeExp pop gdpPercap mayor_que_promedio ## <fct> <fct> <int> <dbl> <int> <dbl> <chr> ## 1 France Europe 2002 79.6 59925035 28926. Es mayor ## 2 France Europe 2007 80.7 61083916 30470. Es mayor ## 3 Mexico Americas 2002 74.9 102479927 10742. No es mayor ## 4 Mexico Americas 2007 76.2 108700891 11978. No es mayor ## 5 Peru Americas 2002 69.9 26769436 5909. No es mayor ## 6 Peru Americas 2007 71.4 28674757 7409. No es mayor ## 7 United Kingdom Europe 2002 78.5 59912431 29479. Es mayor ## 8 United Kingdom Europe 2007 79.4 60776238 33203. Es mayor
summarise()Es una función que nos permite obtener datos resumen de nuestras variables. Algo a tener en cuenta es que al hacer nuestro conjunto de datos sólo retendrá los datos de resumen, obviando la data de la cual fueron obtenidos. Debemos identificar dos cosas:
summarise(data, var_objetivo = operacion(var_existente))
Por ejemplo, podemos obtener el recuento de observaciones de nuestra tabla si usamos n(). Esta función nos devuelve la cantidad de observaciones en nuestros conjunto de datos. En el mismo código podemos asignarle un nombre a la columna, en este caso le ponemos recuento.
summarise(gapminder_subset, recuento = n())
## # A tibble: 1 x 1 ## recuento ## <int> ## 1 8
Podemos obtener más de una medida en un solo llamado a summarise(). Por ejemplo, podemos obtener el promedio y mediana del PBI per cápita. Además, podemos aprovechar para obtener la diferencia entre ambas medidas dentro del mismo llamado.
summarise(gapminder_subset,
promedio = mean(gdpPercap),
mediana = median(gdpPercap),
diferencia = promedio - mediana)
## # A tibble: 1 x 3 ## promedio mediana diferencia ## <dbl> <dbl> <dbl> ## 1 19765. 20452. -687.
Esto también es válido en el contexto de mutate().
group_by()Existe una gran cantidad de datos de resumen que se pueden obtener en nuestro análisis, pero no siempre vamos a querer que los datos sean generales. La función group_by() nos permite seleccionar variables para agruparlas y obtener datos de resumen diferenciados. Debemos identificar dos cosas:
Aunque es posible utilizarla en conjunto con otras funciones de dplyr(), usarla junto con summarise() nos demuestra claramente su poder.
Podemos obtener el recuento de observaciones por país si primero agrupamos nuestros datos. Nótese que uso el mismo nombre de gapminder_subset para evitar crear un nuevo objeto en el Environment.
gapminder_subset <- group_by(gapminder_subset, country)
gapminder_subset
## # A tibble: 8 x 6 ## # Groups: country [4] ## country continent year lifeExp pop gdpPercap ## <fct> <fct> <int> <dbl> <int> <dbl> ## 1 France Europe 2002 79.6 59925035 28926. ## 2 France Europe 2007 80.7 61083916 30470. ## 3 Mexico Americas 2002 74.9 102479927 10742. ## 4 Mexico Americas 2007 76.2 108700891 11978. ## 5 Peru Americas 2002 69.9 26769436 5909. ## 6 Peru Americas 2007 71.4 28674757 7409. ## 7 United Kingdom Europe 2002 78.5 59912431 29479. ## 8 United Kingdom Europe 2007 79.4 60776238 33203.
En principio, los datos no han sufrido ninguna modificación, pero podemos observar que ahora además de las filas y columnas, obtenemos los grupos formados.
Si calculamos el recuento de observaciones, ahora obtenemos un valor para cada uno de nuestros grupos.
summarise(gapminder_subset, recuento = n())
## # A tibble: 4 x 2 ## country recuento ## <fct> <int> ## 1 France 2 ## 2 Mexico 2 ## 3 Peru 2 ## 4 United Kingdom 2
Debido a que sólo contábamos con una variable de agrupación, summarise() genera un nuevo tibble que ya no está agrupado.
ungroup()Los datos permanecerán agrupados hasta que le indiquemos al df que se debe desagrupar, a través de ungroup(). Debemos especificar:
gapminder_subset <- ungroup(gapminder_subset)
Esto es particularmente útil si posteriormente queremos encadenar otra operación, como filter() o mutate() en los nuevos valores calculados.
Con la información de gapminder_subset es posible calcular el promedio y mediana del PBI per cápita por año. Hacemos esto usando group_by() y summarise.
gapminder_subset <- group_by(gapminder_subset, year)
summarise(gapminder_subset, promedio = mean(gdpPercap), mediana = median(gdpPercap))
## # A tibble: 2 x 3 ## year promedio mediana ## <int> <dbl> <dbl> ## 1 2002 18764. 19834. ## 2 2007 20765. 21224.
gapminder_subset <- ungroup(gapminder_subset)
## # A tibble: 1 x 1 ## promedio_exp_vida ## <dbl> ## 1 49.1
Usando gapminder, responder la siguiente pregunta:
## # A tibble: 1 x 1 ## promedio_pbi_total ## <dbl> ## 1 316507473546.
Usando gapminder, responder la siguiente pregunta:
## # A tibble: 5 x 2 ## continent suma_pbi_total ## <fct> <dbl> ## 1 Americas 1.22e13 ## 2 Europe 1.03e13 ## 3 Asia 1.01e13 ## 4 Africa 1.37e12 ## 5 Oceania 4.73e11
Usando gapminder, recrea el siguiente gráfico.
Es importante notar una característica común entre todas las funciones de dplyr() que hemos conocido: el primer argumento siempre es el conjunto de datos al que se le va a aplicar la transformación. Esta es una característica consistente con todos los paquetes del tidyverse, que permite tener un flujo de trabajo pipeable.
filter(gapminder, country == "Peru") select(gapminder, continent, year, pop) arrange(gapminder, desc(gdpPercap)) mutate(gapminder, pbi_total = pop * gdpPercap) summarise(gapminder, promedio_pbi_pc = mean(gdpPercap)) group_by(gapminder, continent) ungroup(gapminder)
Lo que esto quiere decir concretamente es que las funciones se pueden encadenar a través de un operador llamado pipe (%>%), cuyo valor en el lado izquierdo se convierte en el primer argumento de la función del lado derecho.
Por ejemplo:
filter(gapminder_subset, country == "Peru")
## # A tibble: 2 x 6 ## country continent year lifeExp pop gdpPercap ## <fct> <fct> <int> <dbl> <int> <dbl> ## 1 Peru Americas 2002 69.9 26769436 5909. ## 2 Peru Americas 2007 71.4 28674757 7409.
Es lo mismo que:
gapminder_subset %>% filter(country == "Peru")
## # A tibble: 2 x 6 ## country continent year lifeExp pop gdpPercap ## <fct> <fct> <int> <dbl> <int> <dbl> ## 1 Peru Americas 2002 69.9 26769436 5909. ## 2 Peru Americas 2007 71.4 28674757 7409.
Atajo de teclado para insertar el pipe:
Usar esto en una sola función no parece muy útil, así que veamos un ejemplo un poco más extenso.
En gapminder tengo todo lo necesario para obtener el ranking del promedio del PBI nacional para cada uno de los cinco continentes en los años 1987 y 2007 (esto me permitirá comparar los cambios en la economía mundial en esos veinte años).
Para ello voy a requerir usar todas las funciones de dplyr que he aprendido hasta el momento. Primero lo haremos paso por paso y luego convertiremos todo en el flujo de unos cuantos pipes.
Debido a que sólo necesito los años 1987 y 2007, filtro mis datos. Al objeto modificado lo llamaré gapminder_modificado.
gapminder_modificado <- filter(gapminder, year %in% c(1987, 2007))
gapminder_modificado
## # A tibble: 284 x 6 ## country continent year lifeExp pop gdpPercap ## <fct> <fct> <int> <dbl> <int> <dbl> ## 1 Afghanistan Asia 1987 40.8 13867957 852. ## 2 Afghanistan Asia 2007 43.8 31889923 975. ## 3 Albania Europe 1987 72 3075321 3739. ## 4 Albania Europe 2007 76.4 3600523 5937. ## 5 Algeria Africa 1987 65.8 23254956 5681. ## 6 Algeria Africa 2007 72.3 33333216 6223. ## 7 Angola Africa 1987 39.9 7874230 2430. ## 8 Angola Africa 2007 42.7 12420476 4797. ## 9 Argentina Americas 1987 70.8 31620918 9140. ## 10 Argentina Americas 2007 75.3 40301927 12779. ## # ... with 274 more rows
El siguiente paso es quedarme sólo con las variables que necesito. En este caso son continente, año, PBI per cápita y población.
gapminder_modificado <- select(gapminder_modificado, continent, year, gdpPercap, pop)
gapminder_modificado
## # A tibble: 284 x 4 ## continent year gdpPercap pop ## <fct> <int> <dbl> <int> ## 1 Asia 1987 852. 13867957 ## 2 Asia 2007 975. 31889923 ## 3 Europe 1987 3739. 3075321 ## 4 Europe 2007 5937. 3600523 ## 5 Africa 1987 5681. 23254956 ## 6 Africa 2007 6223. 33333216 ## 7 Africa 1987 2430. 7874230 ## 8 Africa 2007 4797. 12420476 ## 9 Americas 1987 9140. 31620918 ## 10 Americas 2007 12779. 40301927 ## # ... with 274 more rows
A continuación, debo obtener el PBI nacional multiplicando el PBI per cápita por la población.
gapminder_modificado <- mutate(gapminder_modificado,
PBI_nacional = pop * gdpPercap)
gapminder_modificado
## # A tibble: 284 x 5 ## continent year gdpPercap pop PBI_nacional ## <fct> <int> <dbl> <int> <dbl> ## 1 Asia 1987 852. 13867957 11820990309. ## 2 Asia 2007 975. 31889923 31079291949. ## 3 Europe 1987 3739. 3075321 11498418358. ## 4 Europe 2007 5937. 3600523 21376411360. ## 5 Africa 1987 5681. 23254956 132119742845. ## 6 Africa 2007 6223. 33333216 207444851958. ## 7 Africa 1987 2430. 7874230 19136019189. ## 8 Africa 2007 4797. 12420476 59583895818. ## 9 Americas 1987 9140. 31620918 289004799539. ## 10 Americas 2007 12779. 40301927 515033625357. ## # ... with 274 more rows
Ahora que tengo el PBI nacional, puedo obtener el promedio por año y continente.
gapminder_modificado <- group_by(gapminder_modificado, continent, year) gapminder_modificado <- summarise(gapminder_modificado, promedio = mean(PBI_nacional)) gapminder_modificado <- ungroup(gapminder_modificado)
gapminder_modificado
## # A tibble: 10 x 3 ## continent year promedio ## <fct> <int> <dbl> ## 1 Africa 1987 24107264108. ## 2 Africa 2007 45778570846. ## 3 Americas 1987 439447790357. ## 4 Americas 2007 776723426068. ## 5 Asia 1987 241784763369. ## 6 Asia 2007 627513635079. ## 7 Europe 1987 316507473546. ## 8 Europe 2007 493183311052. ## 9 Oceania 1987 209451563998. ## 10 Oceania 2007 403657044512.
Ahora sólo me falta ordenar mis datos de manera descendente según el promedio del PBI.
gapminder_modificado <- arrange(gapminder_modificado, year, desc(promedio))
gapminder_modificado
## # A tibble: 10 x 3 ## continent year promedio ## <fct> <int> <dbl> ## 1 Americas 1987 439447790357. ## 2 Europe 1987 316507473546. ## 3 Asia 1987 241784763369. ## 4 Oceania 1987 209451563998. ## 5 Africa 1987 24107264108. ## 6 Americas 2007 776723426068. ## 7 Asia 2007 627513635079. ## 8 Europe 2007 493183311052. ## 9 Oceania 2007 403657044512. ## 10 Africa 2007 45778570846.
Listo. Con el flujo de análisis terminado, puedo verificar que en esos veinte años, Asia superó a Europa en el promedio de su PBI nacional.
Podría juntar todos estos pasos en un solo bloque para que quede claro lo que sucedió.
gapminder_modificado <- filter(gapminder, year %in% c(1987, 2007)) gapminder_modificado <- select(gapminder_modificado, continent, year, gdpPercap, pop) gapminder_modificado <- mutate(gapminder_modificado, PBI_nacional = pop * gdpPercap) gapminder_modificado <- group_by(gapminder_modificado, continent, year) gapminder_modificado <- summarise(gapminder_modificado, promedio = mean(PBI_nacional)) gapminder_modificado <- ungroup(gapminder_modificado) gapminder_modificado <- arrange(gapminder_modificado, year, desc(promedio))
Podemos hacer todo el análisis usando pipes.
gapminder %>% filter(year %in% c(1987, 2007)) %>% select(continent, year, gdpPercap, pop) %>% mutate(PBI_nacional = pop * gdpPercap) %>% group_by(continent, year) %>% summarise(promedio = mean(PBI_nacional)) %>% ungroup() %>% arrange(year, desc(promedio))
## # A tibble: 10 x 3 ## continent year promedio ## <fct> <int> <dbl> ## 1 Americas 1987 439447790357. ## 2 Europe 1987 316507473546. ## 3 Asia 1987 241784763369. ## 4 Oceania 1987 209451563998. ## 5 Africa 1987 24107264108. ## 6 Americas 2007 776723426068. ## 7 Asia 2007 627513635079. ## 8 Europe 2007 493183311052. ## 9 Oceania 2007 403657044512. ## 10 Africa 2007 45778570846.
Hemos obtenido el mismo resultado escribiendo mucho menos código y sin crear ningún objeto intermedio. Además, podemos seguir el proceso de análisis como si fuera una secuencia de pasos. Piensa el pipe como un luego en la secuencia.
gapminder %>% filter(year %in% c(1987, 2007)) %>% select(continent, year, gdpPercap, pop) %>% mutate(PBI_nacional = pop * gdpPercap) %>% group_by(continent, year) %>% summarise(promedio = mean(PBI_nacional)) %>% ungroup() %>% arrange(year, desc(promedio))
gapminderUtilizando gapminder y las funciones de dplyr, obtén el ranking del PBI nacional de Perú, México, Colombia y Chile en los años 1967, 1987 y 2007.
Guíate de esta secuencia:
Realiza un análisis que permita responder a la pregunta:
¿Qué continentes tuvieron la mejor y peor expectativa de vida mediana en 1992?