library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.3 ✓ purrr 0.3.4
## ✓ tibble 3.1.1 ✓ dplyr 1.0.6
## ✓ tidyr 1.1.3 ✓ stringr 1.4.0
## ✓ readr 1.4.0 ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
Para solucionar estos problemas necesitarás las dos funciones más importantes de tidyr:
pivot_longer() (pivotar a lo largo), y pivot_wider() (pivotar a lo ancho).
Datos largos:
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.
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:
El conjunto de columnas cuyos nombres son valores y no variables. En este ejemplo son las columnas 1999 y 2000. El nombre de la variable al que moveremos los nombres de las columnas. En este caso es year El nombre de la variable al que moveremos los valores de las columnas. En este caso cases
Con 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)
## Joining, by = c("country", "year")
## # 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
Datos “anchos”
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.
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:
La columna desde la que obtener los nombres de las variables. En este caso corresponde a type. La columna desde la que obtener los valores. En este caso corresponde a 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
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.
Separar
separate() desarma una columna en varias columnas, dividiendo de acuerdo a la posición de un carácter separador. 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
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
Unir
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.
Usando el set de datos “sida_mujeres_peru.csv”:
Convertir el dataset a un formato tidy
sida_mujeres <- read_csv ("data/sida_mujeres_peru.csv", col_types = "cccccc")
sida_mujeres
## # A tibble: 29 x 6
## año `De 0 a 14 años` `De 15 a 24 años` `De 25 a 49 años` `De 50 a 59 años`
## <chr> <chr> <chr> <chr> <chr>
## 1 1990 2 9 19 1
## 2 1991 3 13 31 -
## 3 1992 4 26 57 7
## 4 1993 15 32 51 5
## 5 1994 14 44 84 4
## 6 1995 16 49 143 16
## 7 1996 22 69 176 16
## 8 1997 19 60 175 15
## 9 1998 18 95 207 6
## 10 1999 17 78 205 20
## # … with 19 more rows, and 1 more variable: De 60 años y más <chr>
sida_mujeres %>%
pivot_longer(c(`De 0 a 14 años`, `De 15 a 24 años`, `De 25 a 49 años`,`De 50 a 59 años`, `De 60 años y más`), names_to = "gruposdedad", values_to = "cases")
## # A tibble: 145 x 3
## año gruposdedad cases
## <chr> <chr> <chr>
## 1 1990 De 0 a 14 años 2
## 2 1990 De 15 a 24 años 9
## 3 1990 De 25 a 49 años 19
## 4 1990 De 50 a 59 años 1
## 5 1990 De 60 años y más 1
## 6 1991 De 0 a 14 años 3
## 7 1991 De 15 a 24 años 13
## 8 1991 De 25 a 49 años 31
## 9 1991 De 50 a 59 años -
## 10 1991 De 60 años y más -
## # … with 135 more rows