TP1 - tidyverse olímpico
En este práctico vamos a usar los paquetes del {tidyverse} para explorar los datos históricos de los Juegos Olímpicos desde Atenas 1896 a Rio 2016 (faltan Tokio 2020 y Pekín 2022).
Antes de empezar les recordamos que tienen que instalar los paquetes del {tidyverse} y adjuntarlo a la sesión de R ejecutando las dos líneas a continuación (si ya instalaron los paquetes del {tidyverse} no hace falta que corran la primera línea):
#install.packages("tidyverse")
library(tidyverse)Cómo cargar los datos
Los datos históricos de los Juegos Olímpicos son un dataset de
Kaggle. Para cargarlos a su sesión de R los pueden
encontrar en el repositorio de la materia, en las carpetas
docs/Practicos/tidyverse/data, copiarlos en su carpeta de
trabajo y leerlos utilizando la función read_csv() del
paquete {readr}.
dictionary_tbl <- read_csv("./data/dictionary.csv")
summer_tbl <- read_csv("./data/summer.csv")
winter_tbl <- read_csv("./data/winter.csv")Los datos
dictionary_tbl, winter_tbl y
summer_tbl son tres (tristes) tibbles que
contienen información sobre los países participantes de los juegos
Olímpicos y resultados de los juegos de invierno y de verano,
respectivamente.
Les dejamos la exploración de las observaciones y las variables a
ustedes. Recuerden que tienen funciones como str(),
summary(), head() o View() que
pueden resultar muy útiles para empezar a entender el contenido de cada
tibble.
Las consignas
La idea es que pongan en práctica todas las funcionalidades del
tidyverse que vimos en las clases, cosas como el piping o
los verbos de {dplyr}. Es por eso que les recomendamos que,
aunque existan métodos alternativos para obtener las respuestas a estas
consignas, intenten utilizar las herramientas que les acabamos de
mencionar.
Por supuesto que con lo que vimos en las clases no les va a alcanzar para resolver las consignas, pero para todo lo que no está en las clases existe google.
Vamos a ver qué jugo🥤les podemos sacar a estos datos…
Empecemos con algo sencillo: ¿Qué simboliza cada fila del
tibble? ¿Es una medalla por país o por atleta?.Pista: usemos
View()para visualizarsummer_tblantes de hacer ninguna operación. En la columnaAthlete¿Qué pasa en los deportes de equipo? Si de ahora en adelante vamos a estar interesados en las medallas por país ¿Esta bien calcular las medallas totales sumando las filas deltibble? ¿Cómo podemos hacer para solucionarlo?.Acá una propuesta (hagan lo mismo para
winter_tbl):
# Acomodemos el tibble
summer_por_disciplina_tbl <- summer_tbl %>%
group_by(Year, City, Sport, Country, Discipline, Event, Gender, Medal) %>%
summarise() # No hace ninguna operación, simplemente se queda con una sola de las ocurrencias# Acomodemos el tibble
winter_por_disciplina_tbl <- winter_tbl %>%
group_by(Year, City, Sport, Country, Discipline, Event, Gender, Medal) %>%
summarise() # No hace ninguna operación, simplemente se queda con una sola de las ocurrenciasAhora que ya tenemos las medallas por país (y no por atleta 😉) para cada disciplina, usando
group_by()y los verbos de {dplyr}, creen un nuevo tibble (oro_por_pais) que tenga, de forma ordenada, la cantidad de medallas de oro que ganó cada país en toda la historia de los Juegos Olímpicos de verano.Pista: Si queremos ordenar algo de forma descendente en
dplyrtenemos que usararrange(desc(variable)).
# Solución
gold_by_country <- summer_por_disciplina_tbl %>%
filter(Medal=="Gold") %>%
group_by(Country) %>%
count(name = "N") %>% # o summarise(N = n())
arrange(desc(N))
head(gold_by_country)
#> # A tibble: 6 × 2
#> # Groups: Country [6]
#> Country N
#> <chr> <int>
#> 1 USA 979
#> 2 URS 396
#> 3 GBR 241
#> 4 FRA 202
#> 5 CHN 200
#> 6 ITA 197- ¿Y si ahora queremos ver cuántas de Oro, de Plata y de Bronce? ¿Cómo
deberíamos modificar el pipe
%>%de análisis?
# Solución
medal_by_country <- summer_por_disciplina_tbl %>%
group_by(Country, Medal) %>%
count(name = "N")# o summarise(N = n())
head(medal_by_country)
#> # A tibble: 6 × 3
#> # Groups: Country, Medal [6]
#> Country Medal N
#> <chr> <chr> <int>
#> 1 AFG Bronze 2
#> 2 AHO Silver 1
#> 3 ALG Bronze 8
#> 4 ALG Gold 5
#> 5 ALG Silver 2
#> 6 ANZ Bronze 5- ¿Y para quedarnos con los países en
oro_por_paiscon más de 5 medallas de oro? ¿Está Argentina🇦🇷 (ARG) en ese grupo?
# Solución
gold_by_country <- summer_por_disciplina_tbl %>%
filter(Medal=="Gold") %>%
group_by(Country) %>%
count(name = "N") %>% # o summarise(N = n())
filter(N>5)
head(gold_by_country)
#> # A tibble: 6 × 2
#> # Groups: Country [6]
#> Country N
#> <chr> <int>
#> 1 ARG 18
#> 2 AUS 141
#> 3 AUT 18
#> 4 AZE 6
#> 5 BEL 37
#> 6 BLR 13¿Quién ganó más medallas de oro en Hockey sobre hielo (
Ice Hockey) masculino, Canadá (CAN) o la Unión Soviética (URS)?Pista: Para filtrar una columna de acuerdo a varios posibles valores discretos les recomiendo investigar el operador %in%.
# Solución
medallas_hockey_tbl <- winter_por_disciplina_tbl %>%
filter(Country %in% c("URS", "CAN")) %>%
filter(Discipline == "Ice Hockey") %>%
filter(Medal == "Gold") %>%
filter(Gender == "Men") %>%
group_by(Country) %>%
count(name = "N") # o summarise(N = n())
head(medallas_hockey_tbl)
#> # A tibble: 2 × 2
#> # Groups: Country [2]
#> Country N
#> <chr> <int>
#> 1 CAN 8
#> 2 URS 7Armemos un
tibblecon los nombres de los medallistas olímpicos argentinos en deportes acuáticos y la disciplina, evento, juego y medalla que ganaron.Pista: Para seleccionar más de una columna hay que hacer una lista usando
c()y se recomienda utilizar all_of().
# Solución
nombres_natacion_tbl <- summer_tbl %>%
filter(Sport == "Aquatics") %>%
filter(Country == "ARG") %>%
select(all_of(c("Year", "Athlete", "Discipline", "Event", "Medal")))
nombres_natacion_tbl
#> # A tibble: 3 × 5
#> Year Athlete Discipline Event Medal
#> <dbl> <chr> <chr> <chr> <chr>
#> 1 1928 ZORRILLA, Victoriano Swimming 400M Freestyle Gold
#> 2 1936 CAMPBELL, Jeanette Morven Swimming 100M Freestyle Silver
#> 3 2004 BARDACH, Georgina Swimming 400M Individual Medley Bronze¿Cuáles son los tres países con más medallas de oro en total (juegos de invierno y verano)?
Pista 1: para combinar dos
tibblescon las mismas columnas pueden usar bind_rows().Pista 2: Para quedarse con los tres primeros valores pueden usar la función slice_head() con
n = 3.
# Solución
top_3_tbl <- winter_por_disciplina_tbl %>%
bind_rows(summer_por_disciplina_tbl) %>%
filter(Medal == "Gold") %>%
group_by(Country) %>%
count(name = "N") %>% # o summarise(N = n())
arrange(desc(N)) %>%
slice_head(n = 3)
head(top_3_tbl)
#> # A tibble: 6 × 2
#> # Groups: Country [6]
#> Country N
#> <chr> <int>
#> 1 ALG 5
#> 2 ANZ 3
#> 3 ARG 18
#> 4 ARM 1
#> 5 AUS 146
#> 6 AUT 79Aprovechemos los datos de
dictionary_tblpara pensar un poco en la cantidad de medallas por millón de habitantes. Armemos untibbleque contenga la cantidad de medallas per cápita por país. ¿Qué pasó con la Unión Soviética (URS)?Pista 1: Para juntar dos
tibblespueden usar la función inner_join()Pista 2: Para descartar las filas con valores
NApueden usar la función drop_na()
# Solución
medallas_per_million_tbl <- summer_por_disciplina_tbl %>%
rbind(winter_por_disciplina_tbl) %>%
group_by(Country) %>%
count(name = "Total_Medals") %>% # o summarise(Total_Medals = n()) %>%
rename("Code" = "Country") %>%
left_join(dictionary_tbl) %>%
drop_na() %>%
mutate(medals_per_million = Total_Medals/Population * 1e6) %>%
select(all_of(c("Country", "medals_per_million"))) %>%
arrange(desc(medals_per_million))
head(medallas_per_million_tbl)
#> # A tibble: 6 × 3
#> # Groups: Code [6]
#> Code Country medals_per_million
#> <chr> <chr> <dbl>
#> 1 NOR Norway 92.4
#> 2 FIN Finland 84.5
#> 3 SWE Sweden 63.9
#> 4 HUN Hungary 49.5
#> 5 SUI Switzerland 39.5
#> 6 AUT Austria 35.9¿Cuántos medallistas olímpicos de invierno que ganaron bronce tienen de nombre John?
Opción 1: La función
str_split()de {stringr} nos separa un string en base a un separador que les damos. Por ejemplostr_split("Juan Perez", pattern = " ")nos de la lista"Juan" "Perez", y de esta forma accedemos a su primer elementostr_split("Juan Perez", pattern = " ")[[1]][1].Opción 2: La función
str_detect()de {stringr} nos devuelve unTRUEsi encuentra un patrón en el texto y unFALSEsi no. Por ejemplo,str_detect("Juan Perez", "Juan", negate = FALSE)devuelveTRUEystr_detect("Pedro Perez", "Juan", negate = FALSE)devuelveFALSE.Recuerden también usar el verbo
mutate().
# Solución
juanes_tbl <- winter_tbl %>%
filter(Medal == "Bronze") %>%
mutate(is_jhon = str_detect(Athlete, "John", negate = FALSE)) %>%
filter(is_jhon)
head(juanes_tbl)
#> # A tibble: 6 × 10
#> Year City Sport Discipline Athlete Country Gender Event Medal is_jhon
#> <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <lgl>
#> 1 1928 St.Moritz Skat… Speed ska… FARREL… USA Men 500M Bron… TRUE
#> 2 1928 St.Moritz Skii… Nordic Co… SNERSR… NOR Men Indi… Bron… TRUE
#> 3 1932 Lake Placid Bobs… Bobsleigh HEATON… USA Men Two-… Bron… TRUE
#> 4 1936 Garmisch Pa… Ice … Ice Hockey GARRIS… USA Men Ice … Bron… TRUE
#> 5 1936 Garmisch Pa… Ice … Ice Hockey LAX, J… USA Men Ice … Bron… TRUE
#> 6 1936 Garmisch Pa… Ice … Ice Hockey SHAUGH… USA Men Ice … Bron… TRUE