- Data:
- “Licenciamiento institucional_5.xlsx”
- “tabla1.csv”
- “tabla2.csv”
- “tabla3.csv”
- “tabla4a.csv”
- “tabla4b.csv”
- “sida_mujeres_peru.csv”
- “fallecidos_covid.csv”
En esta sesión aprenderás una manera consistente para organizar tus datos en R a la que llamaremos tidy data (datos ordenados).
Llevar tus datos a este formato requiere algo de trabajo previo; sin embargo, dicho trabajo tiene ventajas en el largo plazo. Una vez que tengas tus datos ordenados y las herramientas para ordenar datos que provee el tidyverse, vas a gastar mucho menos tiempo pasando de una forma de representar datos a otra, lo que te permitirá destinar más tiempo a las preguntas analíticas.
Esta sesión trabaja con el contenido del capítulo 12 (Tidy data) del libro R for data science y su traducción al castellano.
Cierta agencia de financiamiento está interesada en invertir en el sector educativo peruano, específicamente, en el sector universitario. Ingresaron a la Plataforma Nacional de Datos Abiertos y encontraron el set de datos “Licenciamiento Institucional_5.xls” elaborado por SUNEDU.
Te encargan elaborar un pequeño reporte que les resuelva dudas muy puntuales. Además de las respuestas, la agencia está interesada en conocer el código que usaste para obtener los resultados.
Debes responder las siguientes preguntas:
Las respuestas deben ser redactadas en uno o varios párrafos de texto. No basta con generar las tablas o gráficos.
“Todas las familias felices se parecen unas a otras, pero cada familia infeliz lo es a su manera.” –– León Tolstoy
“Todos los set de datos ordenados se parecen unos a otros, pero cada set de datos desordenado lo es a su manera” — Hadley Wickham
Esta sesión te dará una introducción práctica a los datos ordenados (o tidy data) y a las herramientas que provee el paquete tidyr. Si deseas aprender más acerca de la teoría subyacente, puede que te guste el artículo Tidy Data publicado en la revista Journal of Statistical Software.
Descarga: http://www.jstatsoft.org/v59/i10/paper
Puedes representar los mismos datos subyacentes de múltiples formas. El ejemplo a continuación muestra los mismos datos organizados de cuatro maneras distintas. Cada set de datos muestra los mismos valores de cuatro variables country, year, cases, population, pero cada uno organiza los valores de forma distinta.
tabla1
## # A tibble: 6 x 4 ## country year cases population ## <chr> <dbl> <dbl> <dbl> ## 1 Afghanistan 1999 745 19987071 ## 2 Afghanistan 2000 2666 20595360 ## 3 Brazil 1999 37737 172006362 ## 4 Brazil 2000 80488 174504898 ## 5 China 1999 212258 1272915272 ## 6 China 2000 213766 1280428583
tabla2
## # A tibble: 12 x 4 ## country year type count ## <chr> <dbl> <chr> <dbl> ## 1 Afghanistan 1999 cases 745 ## 2 Afghanistan 1999 population 19987071 ## 3 Afghanistan 2000 cases 2666 ## 4 Afghanistan 2000 population 20595360 ## 5 Brazil 1999 cases 37737 ## 6 Brazil 1999 population 172006362 ## 7 Brazil 2000 cases 80488 ## 8 Brazil 2000 population 174504898 ## 9 China 1999 cases 212258 ## 10 China 1999 population 1272915272 ## 11 China 2000 cases 213766 ## 12 China 2000 population 1280428583
tabla3
## # A tibble: 6 x 3 ## country year rate ## <chr> <dbl> <chr> ## 1 Afghanistan 1999 745/19987071 ## 2 Afghanistan 2000 2666/20595360 ## 3 Brazil 1999 37737/172006362 ## 4 Brazil 2000 80488/174504898 ## 5 China 1999 212258/1272915272 ## 6 China 2000 213766/1280428583
tabla4a
## # A tibble: 3 x 3 ## country `1999` `2000` ## <chr> <dbl> <dbl> ## 1 Afghanistan 745 2666 ## 2 Brazil 37737 80488 ## 3 China 212258 213766
tabla4b
## # A tibble: 3 x 3 ## country `1999` `2000` ## <chr> <dbl> <dbl> ## 1 Afghanistan 19987071 20595360 ## 2 Brazil 172006362 174504898 ## 3 China 1272915272 1280428583
Las anteriores son representaciones de los mismos datos subyacentes, pero no todas son igualmente fáciles de usar. Un tipo de conjunto de datos, el conjunto de datos tidy (ordenado) será mucho más fácil de trabajar dentro del tidyverse.
Existen tres reglas interrelacionadas que hacen que un conjunto de datos sea ordenado:
Estas reglas están interrelacionadas ya que es imposible cumplir solo dos de las tres. Esta interrelación lleva a un conjunto práctico de instrucciones más simple aún:
En este ejemplo, solo la tabla1 es tidy. Es la única representación en que cada columna es una variable.
¿Por qué asegurarse de que los datos estén ordenados? Existen dos ventajas principales:
dplyr, ggplot2 y el resto de los paquetes del tidyverse están diseñados para trabajar con datos ordenados. Aquí hay algunos ejemplos de cómo podrías trabajar con tabla1.
# Calcular tasa por cada 10,000 habitantes tabla1 %>% mutate(tasa = cases / population * 10000)
## # A tibble: 6 x 5 ## country year cases population tasa ## <chr> <dbl> <dbl> <dbl> <dbl> ## 1 Afghanistan 1999 745 19987071 0.373 ## 2 Afghanistan 2000 2666 20595360 1.29 ## 3 Brazil 1999 37737 172006362 2.19 ## 4 Brazil 2000 80488 174504898 4.61 ## 5 China 1999 212258 1272915272 1.67 ## 6 China 2000 213766 1280428583 1.67
# Calcular casos por año
tabla1 %>%
group_by(year) %>%
summarise(cases = sum(cases)) %>%
ungroup()
## # A tibble: 2 x 2 ## year cases ## <dbl> <dbl> ## 1 1999 250740 ## 2 2000 296920
# Visualizar cambios en el tiempo library(ggplot2) ggplot(tabla1, aes(year, cases)) + geom_line(aes(group = country), colour = "grey50") + geom_point(aes(colour = country))
Los principios sobre datos ordenados parecen tan obvios que te podrías preguntar si alguna vez encontrarás un set de datos que no esté ordenado. Desafortunadamente, gran parte de los datos que vas a encontrar están desordenados. Existen dos principales razones para esto:
Esto significa que para la mayoría de los análisis necesitarás hacer algún tipo de orden. El primer paso es entender siempre cuáles son las variables y las observaciones. ¿Qué es lo que está midiendo el set de datos? Esto a veces es fácil; otras veces deberás consultar con quienes crearon el set de datos.
El segundo paso es resolver uno de los siguientes problemas frecuentes:
Típicamente, un set de datos tiene uno de estos problemas. Si contiene ambos ¡significa que tienes muy mala suerte!
Para solucionar estos problemas necesitarás las dos funciones más importantes de tidyr:
pivot_longer() (pivotar a lo largo), ypivot_wider() (pivotar a lo ancho).Un problema común es cuando en un dataset los nombres de las columnas no representan nombres de variables, sino que representan los valores de una variable. Tomando el caso de la tabla4a: los nombres de las columnas 1999 y 2000 representan los valores de la variable year, los valores en las columnas 1999 y 2000 representan valores de la variable cases y cada fila representa dos observaciones en lugar de una.
tabla4a
## # A tibble: 3 x 3 ## country `1999` `2000` ## <chr> <dbl> <dbl> ## 1 Afghanistan 745 2666 ## 2 Brazil 37737 80488 ## 3 China 212258 213766
Para ordenar un dataset como este necesitamos pivotar las columnas que no se ajustan, en un nuevo par de variables. Para describir dicha operación necesitamos tres parámetros:
yearcasesCon estos parámetros podemos utilizar la función pivot_longer() (pivotar a lo largo):
table4a %>% pivot_longer(c(`1999`, `2000`), names_to = "year", values_to = "cases")
## # A tibble: 6 x 3 ## country year cases ## <chr> <chr> <int> ## 1 Afghanistan 1999 745 ## 2 Afghanistan 2000 2666 ## 3 Brazil 1999 37737 ## 4 Brazil 2000 80488 ## 5 China 1999 212258 ## 6 China 2000 213766
Las columnas a pivotar quedan seleccionadas siguiendo el estilo de notación de dplyr::select(). En este caso hay solo dos columnas, por lo que las listamos individualmente. Ten en consideración que “1999” y “2000” son nombres no-sintáxicos (debido a que no comienzan con una letra) por lo que los rodeamos con acentos graves (o backticks).
Las variables “year” y “cases” no existen todavía en la tabla4a, por lo que tenemos que poner sus nombres entre comillas.
En el resultado final, las columnas pivotadas se eliminan y obtenemos la nuevas columnas year y cases. La relación entre las variables originales se mantiene, tal como se puede observar en la imagen anterior.
Podemos usar pivot_longer() para ordenar tabla4b de modo similar. La única diferencia es la variable almacenada en los valores de las celdas.
table4b %>% pivot_longer(c(`1999`, `2000`), names_to = "year", values_to = "population")
## # A tibble: 6 x 3 ## country year population ## <chr> <chr> <int> ## 1 Afghanistan 1999 19987071 ## 2 Afghanistan 2000 20595360 ## 3 Brazil 1999 172006362 ## 4 Brazil 2000 174504898 ## 5 China 1999 1272915272 ## 6 China 2000 1280428583
Para combinar las versiones ordenadas de tabla4a y tabla4b en un único tibble, necesitamos usar dplyr::left_join(), función necesaria para trabajar con datos relacionales.
tidy4a <- table4a %>% pivot_longer(c(`1999`, `2000`), names_to = "year", values_to = "cases") tidy4b <- table4b %>% pivot_longer(c(`1999`, `2000`), names_to = "year", values_to = "population") left_join(tidy4a, tidy4b)
## # A tibble: 6 x 4 ## country year cases population ## <chr> <chr> <int> <int> ## 1 Afghanistan 1999 745 19987071 ## 2 Afghanistan 2000 2666 20595360 ## 3 Brazil 1999 37737 172006362 ## 4 Brazil 2000 80488 174504898 ## 5 China 1999 212258 1272915272 ## 6 China 2000 213766 1280428583
pivot_wider() (pivotar a lo ancho) es lo opuesto de pivot_longer(). Se usa cuando una observación aparece en múltiples filas. Por ejemplo, considera la tabla2: una observación es un país en un año, pero cada observación aparece en dos filas.
tabla2
## # A tibble: 12 x 4 ## country year type count ## <chr> <dbl> <chr> <dbl> ## 1 Afghanistan 1999 cases 745 ## 2 Afghanistan 1999 population 19987071 ## 3 Afghanistan 2000 cases 2666 ## 4 Afghanistan 2000 population 20595360 ## 5 Brazil 1999 cases 37737 ## 6 Brazil 1999 population 172006362 ## 7 Brazil 2000 cases 80488 ## 8 Brazil 2000 population 174504898 ## 9 China 1999 cases 212258 ## 10 China 1999 population 1272915272 ## 11 China 2000 cases 213766 ## 12 China 2000 population 1280428583
Para ordenar esto, primero analizamos la representación de un modo similar a cómo se haría con pivot_longer(). Esta vez, sin embargo, necesitamos únicamente dos parámetros:
type.count.Una vez resuelto esto, podemos usar pivot_wider(), como se muestra debajo.
table2 %>%
pivot_wider(names_from = type, values_from = count)
## # A tibble: 6 x 4 ## country year cases population ## <chr> <int> <int> <int> ## 1 Afghanistan 1999 745 19987071 ## 2 Afghanistan 2000 2666 20595360 ## 3 Brazil 1999 37737 172006362 ## 4 Brazil 2000 80488 174504898 ## 5 China 1999 212258 1272915272 ## 6 China 2000 213766 1280428583
Veámoslo gráficamente:
table2 %>%
pivot_wider(names_from = type, values_from = count)
Como te habrás dado cuenta a partir de sus nombres, las funciones pivot_longer() y pivot_wider() son complementarias. pivot_longer() genera tablas angostas y largas, pivot_wider() genera tablas anchas y cortas.
Hasta ahora has aprendido a ordenar las tablas tabla2 y tabla4, pero no la tabla3, que tiene un problema diferente: tenemos una columna (rate) que contiene dos variables (casos y población).
Para solucionar este problema, necesitamos la función separate() (separar). También aprenderás acerca del complemento de separate(): unite() (unir), que se usa cuando una única variable se reparte en varias columnas.
separate() desarma una columna en varias columnas, dividiendo de acuerdo a la posición de un carácter separador. Tomemos la tabla3:
tabla3
## # A tibble: 6 x 3 ## country year rate ## <chr> <dbl> <chr> ## 1 Afghanistan 1999 745/19987071 ## 2 Afghanistan 2000 2666/20595360 ## 3 Brazil 1999 37737/172006362 ## 4 Brazil 2000 80488/174504898 ## 5 China 1999 212258/1272915272 ## 6 China 2000 213766/1280428583
La columna rate contiene tanto los casos como la población, por lo que necesitamos dividirla en dos variables. La función separate()toma el nombre de la columna a separar y el nombre de las columnas a donde irá el resultado, tal como se muestra en el código a continuación.
table3 %>%
separate(rate, into = c("cases", "population"))
## # A tibble: 6 x 4 ## country year cases population ## <chr> <int> <chr> <chr> ## 1 Afghanistan 1999 745 19987071 ## 2 Afghanistan 2000 2666 20595360 ## 3 Brazil 1999 37737 172006362 ## 4 Brazil 2000 80488 174504898 ## 5 China 1999 212258 1272915272 ## 6 China 2000 213766 1280428583
Podemos representarlo así:
Por defecto, separate() dividirá una columna donde encuentre un carácter no alfanumérico (esto es, un carácter que no es un número o letra). Por ejemplo, en el siguiente código, separate() divide los valores de rate donde aparece una barra (/). Si deseas usar un carácter específico para separar una columna, puedes especificarlo en el argumento sep de separate().
Por ejemplo, el código anterior se puede re-escribir del siguiente modo:
table3 %>%
separate(rate, into = c("cases", "population"), sep = "/")
## # A tibble: 6 x 4 ## country year cases population ## <chr> <int> <chr> <chr> ## 1 Afghanistan 1999 745 19987071 ## 2 Afghanistan 2000 2666 20595360 ## 3 Brazil 1999 37737 172006362 ## 4 Brazil 2000 80488 174504898 ## 5 China 1999 212258 1272915272 ## 6 China 2000 213766 1280428583
Mira atentamente los tipos de columna: notarás que cases y population son columnas de tipo carácter. Este es el comportamiento por defecto en separate(): preserva el tipo de columna. Aquí, sin embargo, no es muy útil, ya que se trata de números. Podemos pedir a separate() que intente convertir a un tipo más adecuado usando convert = TRUE:
table3 %>%
separate(rate, into = c("cases", "population"), convert = TRUE)
## # A tibble: 6 x 4 ## country year cases population ## <chr> <int> <int> <int> ## 1 Afghanistan 1999 745 19987071 ## 2 Afghanistan 2000 2666 20595360 ## 3 Brazil 1999 37737 172006362 ## 4 Brazil 2000 80488 174504898 ## 5 China 1999 212258 1272915272 ## 6 China 2000 213766 1280428583
unite() es el inverso de separate(): combina múltiples columnas en una única columna. Necesitarás esta función con mucha menos frecuencia que separate(), pero aún así es una buena herramienta para conocer.
Podemos usar unite() para volver a unir las columnas que acabamos de separar.
Usamos col = rate para indicar que la nueva columna debe llamarse rate.
tabla1 %>% unite(col = rate, cases, population, sep = "/")
## # A tibble: 6 x 3 ## country year rate ## <chr> <dbl> <chr> ## 1 Afghanistan 1999 745/19987071 ## 2 Afghanistan 2000 2666/20595360 ## 3 Brazil 1999 37737/172006362 ## 4 Brazil 2000 80488/174504898 ## 5 China 1999 212258/1272915272 ## 6 China 2000 213766/1280428583
Usando el set de datos “sida_mujeres_peru.csv”:
Usando el set de datos “fallecidos_covid.csv”
El trabajo debe hacerse en un nuevo proyecto: “ejercicios-tidy”. Pueden estar incluidos en el mismo documento R Markdown.
Existirán ocasiones en que nuestros datos no vengan todos en un solo archivo. Para ello, es necesario aprender tres maneras en que típicamente vamos a necesitar unirlos o combinarlos.
Veamos el caso de estos dos df. Contienen información de todos los países de un continente en gapminder.
gapminder_africa <- read_csv("data/gapminder_africa.csv")
gapminder_asia <- read_csv("data/gapminder_asia.csv")
gapminder_africa
## # A tibble: 624 x 6 ## country continent year lifeExp pop gdpPercap ## <chr> <chr> <dbl> <dbl> <dbl> <dbl> ## 1 Algeria Africa 1952 43.1 9279525 2449. ## 2 Algeria Africa 1957 45.7 10270856 3014. ## 3 Algeria Africa 1962 48.3 11000948 2551. ## 4 Algeria Africa 1967 51.4 12760499 3247. ## 5 Algeria Africa 1972 54.5 14760787 4183. ## 6 Algeria Africa 1977 58.0 17152804 4910. ## 7 Algeria Africa 1982 61.4 20033753 5745. ## 8 Algeria Africa 1987 65.8 23254956 5681. ## 9 Algeria Africa 1992 67.7 26298373 5023. ## 10 Algeria Africa 1997 69.2 29072015 4797. ## # ... with 614 more rows
gapminder_asia
## # A tibble: 396 x 6 ## country continent year lifeExp pop gdpPercap ## <chr> <chr> <dbl> <dbl> <dbl> <dbl> ## 1 Afghanistan Asia 1952 28.8 8425333 779. ## 2 Afghanistan Asia 1957 30.3 9240934 821. ## 3 Afghanistan Asia 1962 32.0 10267083 853. ## 4 Afghanistan Asia 1967 34.0 11537966 836. ## 5 Afghanistan Asia 1972 36.1 13079460 740. ## 6 Afghanistan Asia 1977 38.4 14880372 786. ## 7 Afghanistan Asia 1982 39.9 12881816 978. ## 8 Afghanistan Asia 1987 40.8 13867957 852. ## 9 Afghanistan Asia 1992 41.7 16317921 649. ## 10 Afghanistan Asia 1997 41.8 22227415 635. ## # ... with 386 more rows
En este caso, podemos juntar información de ambos continentes usando bind_rows(), donde cada df a combinar pasa a ser un argumento de la función.
bind_rows(gapminder_africa, gapminder_asia)
## # A tibble: 1,020 x 6 ## country continent year lifeExp pop gdpPercap ## <chr> <chr> <dbl> <dbl> <dbl> <dbl> ## 1 Algeria Africa 1952 43.1 9279525 2449. ## 2 Algeria Africa 1957 45.7 10270856 3014. ## 3 Algeria Africa 1962 48.3 11000948 2551. ## 4 Algeria Africa 1967 51.4 12760499 3247. ## 5 Algeria Africa 1972 54.5 14760787 4183. ## 6 Algeria Africa 1977 58.0 17152804 4910. ## 7 Algeria Africa 1982 61.4 20033753 5745. ## 8 Algeria Africa 1987 65.8 23254956 5681. ## 9 Algeria Africa 1992 67.7 26298373 5023. ## 10 Algeria Africa 1997 69.2 29072015 4797. ## # ... with 1,010 more rows
También se puede usar pipes.
gapminder_africa %>%
bind_rows(gapminder_asia)
## # A tibble: 1,020 x 6 ## country continent year lifeExp pop gdpPercap ## <chr> <chr> <dbl> <dbl> <dbl> <dbl> ## 1 Algeria Africa 1952 43.1 9279525 2449. ## 2 Algeria Africa 1957 45.7 10270856 3014. ## 3 Algeria Africa 1962 48.3 11000948 2551. ## 4 Algeria Africa 1967 51.4 12760499 3247. ## 5 Algeria Africa 1972 54.5 14760787 4183. ## 6 Algeria Africa 1977 58.0 17152804 4910. ## 7 Algeria Africa 1982 61.4 20033753 5745. ## 8 Algeria Africa 1987 65.8 23254956 5681. ## 9 Algeria Africa 1992 67.7 26298373 5023. ## 10 Algeria Africa 1997 69.2 29072015 4797. ## # ... with 1,010 more rows
Une todos los gapminder continentales en un solo gapminder
Puede darse el caso de que nuestra información tiene las columnas divididas en distintos archivos.
gapminder_parte1 <- gapminder %>%
select(country, continent, year)
gapminder_parte2 <- gapminder %>%
select(lifeExp, pop, gdpPercap)
gapminder_parte1
## # A tibble: 1,704 x 3 ## country continent year ## <chr> <chr> <dbl> ## 1 Afghanistan Asia 1952 ## 2 Afghanistan Asia 1957 ## 3 Afghanistan Asia 1962 ## 4 Afghanistan Asia 1967 ## 5 Afghanistan Asia 1972 ## 6 Afghanistan Asia 1977 ## 7 Afghanistan Asia 1982 ## 8 Afghanistan Asia 1987 ## 9 Afghanistan Asia 1992 ## 10 Afghanistan Asia 1997 ## # ... with 1,694 more rows
gapminder_parte2
## # A tibble: 1,704 x 3 ## lifeExp pop gdpPercap ## <dbl> <dbl> <dbl> ## 1 28.8 8425333 779. ## 2 30.3 9240934 821. ## 3 32.0 10267083 853. ## 4 34.0 11537966 836. ## 5 36.1 13079460 740. ## 6 38.4 14880372 786. ## 7 39.9 12881816 978. ## 8 40.8 13867957 852. ## 9 41.7 16317921 649. ## 10 41.8 22227415 635. ## # ... with 1,694 more rows
En este caso, en lugar de unir los df por filas, las unimos por columnas usando bind_cols()
bind_cols(gapminder_parte1, gapminder_parte2)
## # A tibble: 1,704 x 6 ## country continent year lifeExp pop gdpPercap ## <chr> <chr> <dbl> <dbl> <dbl> <dbl> ## 1 Afghanistan Asia 1952 28.8 8425333 779. ## 2 Afghanistan Asia 1957 30.3 9240934 821. ## 3 Afghanistan Asia 1962 32.0 10267083 853. ## 4 Afghanistan Asia 1967 34.0 11537966 836. ## 5 Afghanistan Asia 1972 36.1 13079460 740. ## 6 Afghanistan Asia 1977 38.4 14880372 786. ## 7 Afghanistan Asia 1982 39.9 12881816 978. ## 8 Afghanistan Asia 1987 40.8 13867957 852. ## 9 Afghanistan Asia 1992 41.7 16317921 649. ## 10 Afghanistan Asia 1997 41.8 22227415 635. ## # ... with 1,694 more rows
Nuevamente, se puede usar pipes.
gapminder_parte1 %>%
bind_cols(gapminder_parte2)
## # A tibble: 1,704 x 6 ## country continent year lifeExp pop gdpPercap ## <chr> <chr> <dbl> <dbl> <dbl> <dbl> ## 1 Afghanistan Asia 1952 28.8 8425333 779. ## 2 Afghanistan Asia 1957 30.3 9240934 821. ## 3 Afghanistan Asia 1962 32.0 10267083 853. ## 4 Afghanistan Asia 1967 34.0 11537966 836. ## 5 Afghanistan Asia 1972 36.1 13079460 740. ## 6 Afghanistan Asia 1977 38.4 14880372 786. ## 7 Afghanistan Asia 1982 39.9 12881816 978. ## 8 Afghanistan Asia 1987 40.8 13867957 852. ## 9 Afghanistan Asia 1992 41.7 16317921 649. ## 10 Afghanistan Asia 1997 41.8 22227415 635. ## # ... with 1,694 more rows
Sin embargo, debes tener cuidado al usar bind_cols(), ya que unirá las columnas sin importar si el orden en una de las tablas corresponde al mismo orden de la otra.
Existe una mejor manera de combinar tablas por columnas, haciendo uso de datos relacionales.
Imagina que sólo tuviéramos una tabla con la información que corresponde a los 142 países y su continente. La tenemos ordenada por orden alfabético de continente y país.
(gapminder_paises <- read_csv("data/gapminder_paises.csv"))
## # A tibble: 142 x 2 ## country continent ## <chr> <chr> ## 1 Algeria Africa ## 2 Angola Africa ## 3 Benin Africa ## 4 Botswana Africa ## 5 Burkina Faso Africa ## 6 Burundi Africa ## 7 Cameroon Africa ## 8 Central African Republic Africa ## 9 Chad Africa ## 10 Comoros Africa ## # ... with 132 more rows
Sin embargo, en otra tabla tenemos información de expectativa de vida de los países para todos los años que cubre gapminder. Nota que además esta información está ordenada según expectativa de vida de manera descendente.
(gapminder_life <- read_csv("data/gapminder_life.csv"))
## # A tibble: 1,704 x 3 ## country year lifeExp ## <chr> <dbl> <dbl> ## 1 Japan 2007 82.6 ## 2 Hong Kong, China 2007 82.2 ## 3 Japan 2002 82 ## 4 Iceland 2007 81.8 ## 5 Switzerland 2007 81.7 ## 6 Hong Kong, China 2002 81.5 ## 7 Australia 2007 81.2 ## 8 Spain 2007 80.9 ## 9 Sweden 2007 80.9 ## 10 Israel 2007 80.7 ## # ... with 1,694 more rows
Si quisiéramos obtener el continente de cada uno de los países presente en gapminder_life, sabemos que podemos deducirla del nombre del país guiándonos del contenido de gapminder_paises. La función left_join() nos puede ayudar a realizarlo.
(gapminder_life_paises <- left_join(gapminder_life, gapminder_paises))
## Joining, by = "country"
## # A tibble: 1,704 x 4 ## country year lifeExp continent ## <chr> <dbl> <dbl> <chr> ## 1 Japan 2007 82.6 Asia ## 2 Hong Kong, China 2007 82.2 Asia ## 3 Japan 2002 82 Asia ## 4 Iceland 2007 81.8 Europe ## 5 Switzerland 2007 81.7 Europe ## 6 Hong Kong, China 2002 81.5 Asia ## 7 Australia 2007 81.2 Oceania ## 8 Spain 2007 80.9 Europe ## 9 Sweden 2007 80.9 Europe ## 10 Israel 2007 80.7 Asia ## # ... with 1,694 more rows
Vemos que la información de continente para cada uno de los países se ha repetido para cada año. El trabajo de left_join() es repetir en el conjunto de datos primario (el de la izquierda) todos los valores presentes en el set de datos secundario (el de la derecha) para cada variable en común. Es por eso que para cada país fue asignado el continente correspondiente.
Ahora esta tabla ya permite hacer un análisis por continente.
byCuando las variables tienen nombres en común, left_join() usa por defecto todos los nombres de variable en común entre ambas tablas. Como en el ejemplo anterior el único nombre en común era country, fue la única columna usada.
Ese no es el caso para todos los set de datos
gapminder_pop tiene en común con gapminder_life_paises los nombres de variable country, year y lifeExp, sin embargo esta última variable tiene NA en todas sus observaciones.
(gapminder_pop <- read_csv("data/gapminder_pop.csv"))
## # A tibble: 1,704 x 3 ## country year pop ## <chr> <dbl> <dbl> ## 1 Afghanistan 1952 8425333 ## 2 Afghanistan 1957 9240934 ## 3 Afghanistan 1962 10267083 ## 4 Afghanistan 1967 11537966 ## 5 Afghanistan 1972 13079460 ## 6 Afghanistan 1977 14880372 ## 7 Afghanistan 1982 12881816 ## 8 Afghanistan 1987 13867957 ## 9 Afghanistan 1992 16317921 ## 10 Afghanistan 1997 22227415 ## # ... with 1,694 more rows
Si dejásemos que left_join() determinara por defecto las columnas a usar en el cruce de datos, se nos presentaría un problema.
left_join(gapminder_life_paises, gapminder_pop)
## Joining, by = c("country", "year")
## # A tibble: 1,704 x 5 ## country year lifeExp continent pop ## <chr> <dbl> <dbl> <chr> <dbl> ## 1 Japan 2007 82.6 Asia 127467972 ## 2 Hong Kong, China 2007 82.2 Asia 6980412 ## 3 Japan 2002 82 Asia 127065841 ## 4 Iceland 2007 81.8 Europe 301931 ## 5 Switzerland 2007 81.7 Europe 7554661 ## 6 Hong Kong, China 2002 81.5 Asia 6762476 ## 7 Australia 2007 81.2 Oceania 20434176 ## 8 Spain 2007 80.9 Europe 40448191 ## 9 Sweden 2007 80.9 Europe 9031088 ## 10 Israel 2007 80.7 Asia 6426679 ## # ... with 1,694 more rows
A pesar de que los nombres de variables son iguales, las observaciones de esas variables no son las mismas para cada tabla, debido a ello el cruce no permite obtener los valores adecuados para pop. Felizmente, podemos especificar que se utilicen sólo las variables que sí tienen todos los valores en común entre ambas tablas: country y year.
Para ello usamos el argumento by.
( gapminder_life_pop <- left_join(gapminder_life_paises, gapminder_pop,
by = c("country", "year")) )
## # A tibble: 1,704 x 5 ## country year lifeExp continent pop ## <chr> <dbl> <dbl> <chr> <dbl> ## 1 Japan 2007 82.6 Asia 127467972 ## 2 Hong Kong, China 2007 82.2 Asia 6980412 ## 3 Japan 2002 82 Asia 127065841 ## 4 Iceland 2007 81.8 Europe 301931 ## 5 Switzerland 2007 81.7 Europe 7554661 ## 6 Hong Kong, China 2002 81.5 Asia 6762476 ## 7 Australia 2007 81.2 Oceania 20434176 ## 8 Spain 2007 80.9 Europe 40448191 ## 9 Sweden 2007 80.9 Europe 9031088 ## 10 Israel 2007 80.7 Asia 6426679 ## # ... with 1,694 more rows
En este caso, sí pudimos obtener la información de pop correspondiente a cada año y país.
Puede ser que a pesar de que tengamos la misma información, la variable se llame distinto en la siguiente tabla. Por ejemplo, en gapminder_gdp la variable country se llama pais.
( gapminder_gdp <- read_csv("data/gapminder_gdp.csv") )
## # A tibble: 1,704 x 3 ## pais year gdpPercap ## <chr> <dbl> <dbl> ## 1 Kuwait 1957 113523. ## 2 Kuwait 1972 109348. ## 3 Kuwait 1952 108382. ## 4 Kuwait 1962 95458. ## 5 Kuwait 1967 80895. ## 6 Kuwait 1977 59265. ## 7 Norway 2007 49357. ## 8 Kuwait 2007 47307. ## 9 Singapore 2007 47143. ## 10 Norway 2002 44684. ## # ... with 1,694 more rows
Si quisiéramos unir esta información con gapminder_life_pop, sólo year sería reconocida como llave por defecto. Toda la información de gapminder gdp se repetiría para cada año presente.
left_join(gapminder_life_pop, gapminder_gdp)
## # A tibble: 241,968 x 7 ## country year lifeExp continent pop pais gdpPercap ## <chr> <dbl> <dbl> <chr> <dbl> <chr> <dbl> ## 1 Japan 2007 82.6 Asia 127467972 Norway 49357. ## 2 Japan 2007 82.6 Asia 127467972 Kuwait 47307. ## 3 Japan 2007 82.6 Asia 127467972 Singapore 47143. ## 4 Japan 2007 82.6 Asia 127467972 United States 42952. ## 5 Japan 2007 82.6 Asia 127467972 Ireland 40676. ## 6 Japan 2007 82.6 Asia 127467972 Hong Kong, China 39725. ## 7 Japan 2007 82.6 Asia 127467972 Switzerland 37506. ## 8 Japan 2007 82.6 Asia 127467972 Netherlands 36798. ## 9 Japan 2007 82.6 Asia 127467972 Canada 36319. ## 10 Japan 2007 82.6 Asia 127467972 Iceland 36181. ## # ... with 241,958 more rows
Tampoco podemos indicarle el nombre de la variable country o pais, porque no existe al mismo tiempo en ambos conjuntos de datos.
left_join(gapminder_life_pop, gapminder_gdp, by = c("country", "year"))
## Error: Join columns must be present in data. ## x Problem with `country`.
left_join(gapminder_life_pop, gapminder_gdp, by = c("pais", "year"))
## Error: Join columns must be present in data. ## x Problem with `pais`.
Necesitamos especificar que la variable de la izquierda equivale con un nombre distinto de la derecha. Seguimos usando el argumento by.
left_join(gapminder_life_pop, gapminder_gdp, by = c("country" = "pais", "year"))
## # A tibble: 1,704 x 6 ## country year lifeExp continent pop gdpPercap ## <chr> <dbl> <dbl> <chr> <dbl> <dbl> ## 1 Japan 2007 82.6 Asia 127467972 31656. ## 2 Hong Kong, China 2007 82.2 Asia 6980412 39725. ## 3 Japan 2002 82 Asia 127065841 28605. ## 4 Iceland 2007 81.8 Europe 301931 36181. ## 5 Switzerland 2007 81.7 Europe 7554661 37506. ## 6 Hong Kong, China 2002 81.5 Asia 6762476 30209. ## 7 Australia 2007 81.2 Oceania 20434176 34435. ## 8 Spain 2007 80.9 Europe 40448191 28821. ## 9 Sweden 2007 80.9 Europe 9031088 33860. ## 10 Israel 2007 80.7 Asia 6426679 25523. ## # ... with 1,694 more rows