Let’s load the packages that we need for this exercise.
library(tidyverse)
library(magrittr)
#install.packages("repurrrsive")
library(repurrrsive)
library(tibble)
I am going to use the data got_chars which contains information about the Game of Thrones characters. This data comes from the repurrrsive package, so make sure that you have that package loaded (and of course that this package has been installed).
#we can look at the data before we dive into using the data
#head(got_chars)
#we can see that this data set has a bunch of information about the GOT characters. We see that the first character in the data set is Theon Greyjoy. Looks like the data is in a list format, but we can check
got_chars %>% class
## [1] "list"
Now that we have stolen a glance at the data, let’s begin exploring the data using the map() function.
What if we want to know which GOT characters are in this list?
We can use map() to do this.
#let's rename the list
t1 <- got_chars
#if you want to make sure that this action above worked
#t1
#we can extract the first 5 character names
map(t1[1:5], "name")
## [[1]]
## [1] "Theon Greyjoy"
##
## [[2]]
## [1] "Tyrion Lannister"
##
## [[3]]
## [1] "Victarion Greyjoy"
##
## [[4]]
## [1] "Will"
##
## [[5]]
## [1] "Areo Hotah"
#or we could extract the first 10 character names
map(t1[1:10], "name")
## [[1]]
## [1] "Theon Greyjoy"
##
## [[2]]
## [1] "Tyrion Lannister"
##
## [[3]]
## [1] "Victarion Greyjoy"
##
## [[4]]
## [1] "Will"
##
## [[5]]
## [1] "Areo Hotah"
##
## [[6]]
## [1] "Chett"
##
## [[7]]
## [1] "Cressen"
##
## [[8]]
## [1] "Arianne Martell"
##
## [[9]]
## [1] "Daenerys Targaryen"
##
## [[10]]
## [1] "Davos Seaworth"
If we want to be more sophisticated and use the pipe (%>%) when we do this action, we can do the following:
t1 %>%
map("name")
## [[1]]
## [1] "Theon Greyjoy"
##
## [[2]]
## [1] "Tyrion Lannister"
##
## [[3]]
## [1] "Victarion Greyjoy"
##
## [[4]]
## [1] "Will"
##
## [[5]]
## [1] "Areo Hotah"
##
## [[6]]
## [1] "Chett"
##
## [[7]]
## [1] "Cressen"
##
## [[8]]
## [1] "Arianne Martell"
##
## [[9]]
## [1] "Daenerys Targaryen"
##
## [[10]]
## [1] "Davos Seaworth"
##
## [[11]]
## [1] "Arya Stark"
##
## [[12]]
## [1] "Arys Oakheart"
##
## [[13]]
## [1] "Asha Greyjoy"
##
## [[14]]
## [1] "Barristan Selmy"
##
## [[15]]
## [1] "Varamyr"
##
## [[16]]
## [1] "Brandon Stark"
##
## [[17]]
## [1] "Brienne of Tarth"
##
## [[18]]
## [1] "Catelyn Stark"
##
## [[19]]
## [1] "Cersei Lannister"
##
## [[20]]
## [1] "Eddard Stark"
##
## [[21]]
## [1] "Jaime Lannister"
##
## [[22]]
## [1] "Jon Connington"
##
## [[23]]
## [1] "Jon Snow"
##
## [[24]]
## [1] "Aeron Greyjoy"
##
## [[25]]
## [1] "Kevan Lannister"
##
## [[26]]
## [1] "Melisandre"
##
## [[27]]
## [1] "Merrett Frey"
##
## [[28]]
## [1] "Quentyn Martell"
##
## [[29]]
## [1] "Samwell Tarly"
##
## [[30]]
## [1] "Sansa Stark"
##names is the third item in the list so we can do the following
t1 %>%
map(3)
## [[1]]
## [1] "Theon Greyjoy"
##
## [[2]]
## [1] "Tyrion Lannister"
##
## [[3]]
## [1] "Victarion Greyjoy"
##
## [[4]]
## [1] "Will"
##
## [[5]]
## [1] "Areo Hotah"
##
## [[6]]
## [1] "Chett"
##
## [[7]]
## [1] "Cressen"
##
## [[8]]
## [1] "Arianne Martell"
##
## [[9]]
## [1] "Daenerys Targaryen"
##
## [[10]]
## [1] "Davos Seaworth"
##
## [[11]]
## [1] "Arya Stark"
##
## [[12]]
## [1] "Arys Oakheart"
##
## [[13]]
## [1] "Asha Greyjoy"
##
## [[14]]
## [1] "Barristan Selmy"
##
## [[15]]
## [1] "Varamyr"
##
## [[16]]
## [1] "Brandon Stark"
##
## [[17]]
## [1] "Brienne of Tarth"
##
## [[18]]
## [1] "Catelyn Stark"
##
## [[19]]
## [1] "Cersei Lannister"
##
## [[20]]
## [1] "Eddard Stark"
##
## [[21]]
## [1] "Jaime Lannister"
##
## [[22]]
## [1] "Jon Connington"
##
## [[23]]
## [1] "Jon Snow"
##
## [[24]]
## [1] "Aeron Greyjoy"
##
## [[25]]
## [1] "Kevan Lannister"
##
## [[26]]
## [1] "Melisandre"
##
## [[27]]
## [1] "Merrett Frey"
##
## [[28]]
## [1] "Quentyn Martell"
##
## [[29]]
## [1] "Samwell Tarly"
##
## [[30]]
## [1] "Sansa Stark"
Now time for the exercises!
#we can use the names() function to look at the names of the list of elements associated with each character in GOT
names(t1[[1]])
## [1] "url" "id" "name" "gender" "culture"
## [6] "born" "died" "alive" "titles" "aliases"
## [11] "father" "mother" "spouse" "allegiances" "books"
## [16] "povBooks" "tvSeries" "playedBy"
# we see that the following information is associated with each character
#now we need to figure out where "played by" is located in the list
which(names(t1[[1]]) == "playedBy")
## [1] 18
#"playedBy" is 18th in the list
#we can use map to pull out a list of all the "playedBy" elements
t1 %>%
map("playedBy")
## [[1]]
## [1] "Alfie Allen"
##
## [[2]]
## [1] "Peter Dinklage"
##
## [[3]]
## [1] ""
##
## [[4]]
## [1] "Bronson Webb"
##
## [[5]]
## [1] "DeObia Oparei"
##
## [[6]]
## [1] ""
##
## [[7]]
## [1] "Oliver Ford"
##
## [[8]]
## [1] ""
##
## [[9]]
## [1] "Emilia Clarke"
##
## [[10]]
## [1] "Liam Cunningham"
##
## [[11]]
## [1] "Maisie Williams"
##
## [[12]]
## [1] ""
##
## [[13]]
## [1] "Gemma Whelan"
##
## [[14]]
## [1] "Ian McElhinney"
##
## [[15]]
## [1] ""
##
## [[16]]
## [1] "Isaac Hempstead-Wright"
##
## [[17]]
## [1] "Gwendoline Christie"
##
## [[18]]
## [1] "Michelle Fairley"
##
## [[19]]
## [1] "Lena Headey"
##
## [[20]]
## [1] "Sean Bean" "Sebastian Croft" "Robert Aramayo"
##
## [[21]]
## [1] "Nikolaj Coster-Waldau"
##
## [[22]]
## [1] ""
##
## [[23]]
## [1] "Kit Harington"
##
## [[24]]
## [1] "Michael Feast"
##
## [[25]]
## [1] "Ian Gelder"
##
## [[26]]
## [1] "Carice van Houten"
##
## [[27]]
## [1] ""
##
## [[28]]
## [1] ""
##
## [[29]]
## [1] "John Bradley-West"
##
## [[30]]
## [1] "Sophie Turner"
t1 %>%
map_int("id")
## [1] 1022 1052 1074 1109 1166 1267 1295 130 1303 1319 148 149 150 168 2066
## [16] 208 216 232 238 339 529 576 583 60 605 743 751 844 954 957
So far, we have only extracted one value from the list. But what if we want to pull out multiple values. For example, what if we want to know a character’s name, and gender?
#let's start by doing this action for ONE character to see if we know what we're doing
#let's just pick the third character in the list
t1[[3]][c("name", "gender")]
## $name
## [1] "Victarion Greyjoy"
##
## $gender
## [1] "Male"
#we can replicate for the 8th person in the list with the following
t1[[8]][c("name", "gender")]
## $name
## [1] "Arianne Martell"
##
## $gender
## [1] "Female"
But this approach may be a bit too clunky, so we can use map to help us be more elegant.
Hint: map() is simply:
map(.x, .f, …)
l1 <- map(
t1,
extract,
c("name", "gender")
)
#did it work? we can run the following code and check
#l1
#we could even use the str() function to pull out specific information about characters by specifying where they fall in the list
str(l1[12])
## List of 1
## $ :List of 2
## ..$ name : chr "Arys Oakheart"
## ..$ gender: chr "Male"
l2 <- map(
t1,
extract,
c("name", "gender", "culture", "born", "died")
)
#l2
str(l2[20:22])
## List of 3
## $ :List of 5
## ..$ name : chr "Eddard Stark"
## ..$ gender : chr "Male"
## ..$ culture: chr "Northmen"
## ..$ born : chr "In 263 AC, at Winterfell"
## ..$ died : chr "In 299 AC, at Great Sept of Baelor in King's Landing"
## $ :List of 5
## ..$ name : chr "Jaime Lannister"
## ..$ gender : chr "Male"
## ..$ culture: chr "Westerlands"
## ..$ born : chr "In 266 AC, at Casterly Rock"
## ..$ died : chr ""
## $ :List of 5
## ..$ name : chr "Jon Connington"
## ..$ gender : chr "Male"
## ..$ culture: chr "Stormlands"
## ..$ born : chr "In or between 263 AC and 265 AC"
## ..$ died : chr ""
For the last part of this exercise, let us make a nice and neat data frame.
t1 %>%
map_dfr( ~ tibble(
id = .x[["id"]],
name = .x[["name"]],
gender = .x[["gender"]],
born = .x[["born"]],
culture = .x[["culture"]],
alive = .x[["alive"]]
)
)
## # A tibble: 30 × 6
## id name gender born culture alive
## <int> <chr> <chr> <chr> <chr> <lgl>
## 1 1022 Theon Greyjoy Male "In 278 AC or 279 AC, at Pyke" "Ironb… TRUE
## 2 1052 Tyrion Lannister Male "In 273 AC, at Casterly Rock" "" TRUE
## 3 1074 Victarion Greyjoy Male "In 268 AC or before, at Pyke" "Ironb… TRUE
## 4 1109 Will Male "" "" FALSE
## 5 1166 Areo Hotah Male "In 257 AC or before, at Norvo… "Norvo… TRUE
## 6 1267 Chett Male "At Hag's Mire" "" FALSE
## 7 1295 Cressen Male "In 219 AC or 220 AC" "" FALSE
## 8 130 Arianne Martell Female "In 276 AC, at Sunspear" "Dorni… TRUE
## 9 1303 Daenerys Targaryen Female "In 284 AC, at Dragonstone" "Valyr… TRUE
## 10 1319 Davos Seaworth Male "In 260 AC or before, at King'… "Weste… TRUE
## # ℹ 20 more rows