background-image: url("img/logo_padded.001.jpeg") background-position: left background-size: 60% class: middle, center, .pull-right[ <br> ## .base_color[Iteration] <br> #### .navy[Kelly McConville] #### .navy[ Stat 108 | Week 9 | Spring 2023] ] --- ## Announcements * Project 1 -- Initial dashboard drafts due on by **noon on Th, Mar 30th**. + Peer feedback activity later this week. Will receive instructions in Wednesday's lecture. * P-Set 5 is due at 10pm on Wed. ************************ ## Week's Goals .pull-left[ **Mon Lecture** * Iteration via `for()` and `while()` loops * Functional Programming via `purrr` ] .pull-right[ **Wed Lecture** * Code smells * Refactoring code ] --- ### Functions Recap * Start with an MVP. * Then start generalizing. * For inputs: + Check their class. + Consider their order. + Determine whether or not to supply a default. * Remember that names are important for readability. * And don't forget to test your function thoroughly! --- ### RStudio Projects/GitHub Repos * At this point you now have **two** Stat 108 RStudio Projects (synced with a corresponding GitHub Repo): + `work-githubusername` + `project1-groupXXX` * When you go to work in RStudio, it is good practice to switch to the related RStudio Project. * When you want to commit & push changes, you must switch to the related RStudio Project. --- ### Reducing Code Duplication * Have already reduced code duplication by creating **functions**. ```r library(pdxTrees) get_pdxTrees_parks() %>% rename(ht = Tree_Height, pol = Pollution_Removal_oz) %>% summarize(DBH_cv = sd(DBH, na.rm = TRUE)/mean(DBH, na.rm = TRUE), ht_cv = sd(ht, na.rm = TRUE)/mean(ht, na.rm = TRUE), pol_cv = sd(pol, na.rm = TRUE)/mean(ht, na.rm = TRUE)) ``` ``` ## # A tibble: 1 × 3 ## DBH_cv ht_cv pol_cv ## <dbl> <dbl> <dbl> ## 1 0.650 0.613 0.243 ``` --- ### Reducing Code Duplication * Have already reduced code duplication by creating **functions**. ```r coef_of_var <- function(x, trim = 0, na.rm = FALSE){ stopifnot(is.numeric(x)) sd(x, na.rm = na.rm)/mean(x, na.rm = na.rm, trim = trim) } get_pdxTrees_parks() %>% rename(ht = Tree_Height, pol = Pollution_Removal_oz) %>% summarize(DBH_cv = coef_of_var(DBH, na.rm = TRUE), ht_cv = coef_of_var(ht, na.rm = TRUE), pol_cv = coef_of_var(pol, na.rm = TRUE)) ``` ``` ## # A tibble: 1 × 3 ## DBH_cv ht_cv pol_cv ## <dbl> <dbl> <dbl> ## 1 0.650 0.613 0.884 ``` * But we do still have some code duplication. --- ### Reducing Code Duplication * Can also reduce duplication through iteration. * **Iteration**: Do the same thing for multiple inputs. -- * `dplyr` style: ```r get_pdxTrees_parks() %>% rename(ht = Tree_Height, pol = Pollution_Removal_oz) %>% summarize(across(.cols = c(DBH, ht, pol), .fns = coef_of_var)) ``` ``` ## # A tibble: 1 × 3 ## DBH ht pol ## <dbl> <dbl> <dbl> ## 1 0.650 NA NA ``` * Why the `NA`s for `ht` and `pol`? --- ### Anonymous Function * Create a function on the fly to use as an argument of another function. + Don't store the anonymous function. * Also called lambda function/expression. ```r get_pdxTrees_parks() %>% rename(ht = Tree_Height, pol = Pollution_Removal_oz) %>% summarize(across(.cols = c(DBH, ht, pol), .fns = function(.x) { coef_of_var(.x, na.rm = TRUE) })) ``` ``` ## # A tibble: 1 × 3 ## DBH ht pol ## <dbl> <dbl> <dbl> ## 1 0.650 0.613 0.884 ``` --- ### Anonymous Function * Shorthand `~` ```r get_pdxTrees_parks() %>% rename(ht = Tree_Height, pol = Pollution_Removal_oz) %>% summarize(across(.cols = c(DBH, ht, pol), .fns = ~ coef_of_var(.x, na.rm = TRUE))) ``` ``` ## # A tibble: 1 × 3 ## DBH ht pol ## <dbl> <dbl> <dbl> ## 1 0.650 0.613 0.884 ``` --- ### Back to `dplyr` Iterating * `everything()` is useful if you want to apply the function to all columns of the `data.frame()`. ```r get_pdxTrees_parks() %>% rename(ht = Tree_Height, pol = Pollution_Removal_oz) %>% select(DBH, ht, pol) %>% summarize(across(everything(), .fns = ~ coef_of_var(.x, na.rm = TRUE))) ``` ``` ## # A tibble: 1 × 3 ## DBH ht pol ## <dbl> <dbl> <dbl> ## 1 0.650 0.613 0.884 ``` --- ### Back to `dplyr` Iterating * `where()` is useful for conditional application of the function. ```r get_pdxTrees_parks() %>% rename(ht = Tree_Height, pol = Pollution_Removal_oz) %>% select(DBH, ht, pol, Condition) %>% summarize(across(where(is.numeric), .fns = ~ coef_of_var(.x, na.rm = TRUE))) ``` ``` ## # A tibble: 1 × 3 ## DBH ht pol ## <dbl> <dbl> <dbl> ## 1 0.650 0.613 0.884 ``` --- ### Back to `dplyr` Iterating * You can provide more than one function via a `list()`. ```r get_pdxTrees_parks() %>% rename(ht = Tree_Height, pol = Pollution_Removal_oz) %>% select(DBH, ht, pol, Condition) %>% summarize(across(where(is.numeric), .fns = list( cv = ~ coef_of_var(.x, na.rm = TRUE), mean = ~ mean(.x, na.rm = TRUE)))) ``` ``` ## # A tibble: 1 × 6 ## DBH_cv DBH_mean ht_cv ht_mean pol_cv pol_mean ## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 0.650 20.6 0.613 65.7 0.884 18.1 ``` --- ### Back to `dplyr` Iterating * `across()` also works with `mutate()`. * I used it in the Week 4 live coding example: ```r library(readxl) url <- "https://www.bts.gov/sites/bts.dot.gov/files/table_01_33_102020.xlsx" destfile <- "table_01_33_102020.xlsx" curl::curl_download(url, destfile) Amtrak <- read_excel(destfile, range = 'A2:AI8') Amtrak %>% slice(2:3) %>% mutate(across(2:35, as.numeric)) ``` ``` ## # A tibble: 2 × 35 ## ...1 `1972` `1975` `1980` `1985` `1990` `1991` `1992` `1993` `1994` `1995` ## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 Percent… NA 87 83 93 84 86 83 84 85 88 ## 2 Average… 22.3 14.4 7.4 7 12 13 13 13.2 13.4 13.9 ## # … with 24 more variables: `1996` <dbl>, `1997` <dbl>, `1998` <dbl>, ## # `1999` <dbl>, `2000` <dbl>, `2001` <dbl>, `2002` <dbl>, `2003` <dbl>, ## # `2004` <dbl>, `2005` <dbl>, `2006` <dbl>, `2007` <dbl>, `2008` <dbl>, ## # `2009` <dbl>, `2010` <dbl>, `2011` <dbl>, `2012` <dbl>, `2013` <dbl>, ## # `2014` <dbl>, `2015` <dbl>, `2016` <dbl>, `2017` <dbl>, `2018` <dbl>, ## # `2019` <dbl> ``` --- class: middle, center ## Explicit Iterating: `for()` Loops --- ### Explicit Iterating: `for()` Loops * Language: + Iterating = Looping ```r # Data pdxTrees <- get_pdxTrees_parks() # Variables of interest vars <- c("DBH", "Tree_Height", "Pollution_Removal_oz") # Vector for storing output pdxTrees_coef_of_vars <- rep(NA, 3) # For loop for(i in 1:3){ pdxTrees_coef_of_vars[i] <- coef_of_var(pdxTrees[[vars[i]]], na.rm = TRUE) } # Examine output pdxTrees_coef_of_vars ``` ``` ## [1] 0.6496634 0.6129159 0.8835582 ``` --- ### `for()` Loop Components * **Output**: What you want to produce and store. + Good to specify size of output object. + Start with `NA`s so clear which have been replaced. + Determine if you want to store the output as a vector or data frame or something else. ```r # Output options pdxTrees_coef_of_vars <- vector("double", 3) pdxTrees_coef_of_vars ``` ``` ## [1] 0 0 0 ``` ```r pdxTrees_coef_of_vars <- vector() pdxTrees_coef_of_vars ``` ``` ## logical(0) ``` ```r pdxTrees_coef_of_vars <- rep(NA, 3) pdxTrees_coef_of_vars ``` ``` ## [1] NA NA NA ``` --- ### `for()` Loop Components * **Sequence**: The vector you want to iterate over ```r # Sequence Options 1:3 ``` ``` ## [1] 1 2 3 ``` ```r 1:length(pdxTrees_coef_of_vars) ``` ``` ## [1] 1 2 3 ``` ```r seq_along(pdxTrees_coef_of_vars) ``` ``` ## [1] 1 2 3 ``` --- ### `for()` Loop Components * Careful of unusual behavior! ```r pdxTrees_coef_of_vars2 <- NULL # Sequence Options 1:0 ``` ``` ## [1] 1 0 ``` ```r 1:length(pdxTrees_coef_of_vars2) ``` ``` ## [1] 1 0 ``` ```r seq_along(pdxTrees_coef_of_vars2) ``` ``` ## integer(0) ``` --- ### `for()` Loop Components * **Body**: The code that we iterate. ```r for(i in seq_along(pdxTrees_coef_of_vars)){ pdxTrees_coef_of_vars[i] <- coef_of_var(pdxTrees[[vars[i]]], na.rm = TRUE) } pdxTrees_coef_of_vars ``` ``` ## [1] 0.6496634 0.6129159 0.8835582 ``` --- ### Another example: Building Up a `for()` Loop I want to construct a bootstrap distribution for the mean `DBH` for our sample of Portland trees. * How is looping/iterating helpful here? -- * Let's start with a minimal viable product. ```r mean(sample(pdxTrees$DBH, replace = TRUE)) ``` ``` ## [1] 20.61302 ``` --- ### Another example: Building Up a `for()` Loop * What do I want to store? + What type of R object do I want? + What's the required size? -- ```r boot <- data.frame(avg = rep(NA, 1000)) ``` --- ### Another example: Building Up a `for()` Loop * How do I save this in `boot`? ```r mean(sample(pdxTrees$DBH, replace = TRUE)) ``` ``` ## [1] 20.56722 ``` -- ```r # Set i for now i <- 1 # Option 1 boot[i, ] <- mean(sample(pdxTrees$DBH, replace = TRUE)) boot[i, ] ``` ``` ## [1] 20.5901 ``` ```r # Option 2 boot$avg[i] <- mean(sample(pdxTrees$DBH, replace = TRUE)) boot$avg[i] ``` ``` ## [1] 20.56384 ``` --- ### Another example: Building Up a `for()` Loop ```r boot <- data.frame(avg = rep(NA, 1000)) for(i in seq_along(boot$avg)){ boot[i,] <- mean(sample(pdxTrees$DBH, replace = TRUE)) } ggplot(data = boot, mapping = aes(x = avg)) + geom_density() ``` <img src="stat108_wk09mon_files/figure-html/unnamed-chunk-19-1.png" width="432" style="display: block; margin: auto;" /> --- Can nest loops ```r boot <- data.frame(avg_n_20 = rep(NA, 1000), avg_n_50 = rep(NA, 1000), avg_n_100 = rep(NA, 1000)) sizes <- c(20, 50, 100) for(j in 1:ncol(boot)){ # Generate sample samp <- sample(pdxTrees$DBH, size = sizes[j]) for(i in 1:nrow(boot)){ boot[i,j] <- mean(sample(samp, replace = TRUE)) } } glimpse(boot) ``` ``` ## Rows: 1,000 ## Columns: 3 ## $ avg_n_20 <dbl> 13.395, 17.820, 24.460, 18.930, 18.510, 16.300, 12.840, 14.5… ## $ avg_n_50 <dbl> 20.178, 20.756, 19.414, 21.660, 20.734, 20.704, 23.176, 20.1… ## $ avg_n_100 <dbl> 22.362, 23.527, 22.118, 23.391, 24.760, 23.220, 23.986, 22.3… ``` --- ### Need an Unknown Number of Iterations * If you want to iterate `while` some condition is true, then you don't necessarily know how many iterations are required beforehand. * Will then use a `while()` loop instead of a `for()` loop. ```r for(i in 1:???){ # Do Something } while(condition) { # Do Something } ``` * Keeps iterating as long as the condition holds. --- ### `while()` Loop Example * Want 20 random draws from a normal that are positive numbers ```r norm_pos <- vector() i <- 0 while(length(norm_pos) < 20){ # Random draw draw <- rnorm(n = 1) # Only add positive draws if(draw > 0){ norm_pos <- c(norm_pos, draw) } } glimpse(norm_pos) ``` ``` ## num [1:20] 1.664 0.966 0.843 1.905 0.442 ... ``` --- ### Loops * `while()` loops aren't nearly as common as `for()` loops. * For those who go into statistics research, you will end up often using `for()` loops to run simulation studies. * The internet hates `for()` loops in R. + But they usually aren't as slow as people say. * Alternatives: + `apply()` functions + `purrr` functions ```r library(purrr) ``` --- class: middle, center ## Function Programming with `purrr` <img src="img/purrr.png" width="20%" style="display: block; margin: auto;" /> --- ### Function Programming **Functional Programming**: Functions that allow us to pass other functions as arguments ```r pdxTrees %>% select(DBH, Tree_Height, Pollution_Removal_oz) %>% map(.f = mean, na.rm = TRUE) ``` ``` ## $DBH ## [1] 20.61408 ## ## $Tree_Height ## [1] 65.73607 ## ## $Pollution_Removal_oz ## [1] 18.09618 ``` ```r pdxTrees %>% select(DBH, Tree_Height, Pollution_Removal_oz) %>% map_dbl(.f = mean, na.rm = TRUE) ``` ``` ## DBH Tree_Height Pollution_Removal_oz ## 20.61408 65.73607 18.09618 ``` --- ### Function Programming Problem? ```r pdxTrees %>% select(DBH, Condition, Pollution_Removal_oz) %>% map_dbl(mean, na.rm = TRUE) ``` ``` ## DBH Condition Pollution_Removal_oz ## 20.61408 NA 18.09618 ``` --- ### `map_XXX` Functions * Loop over an R object * Do something * Save results * Function for each type of output: + `map()` makes a list. + `map_lgl()` makes a logical vector. + `map_int()` makes an integer vector. + `map_dbl()` makes a double vector. + `map_chr()` makes a character vector. + `map_df()` makes a data frame. * General structure ```r map_XXX(.x, .f, ...) ``` --- ### `map_XXX` Functions * Input: vector + What did `map_XXX()` iterate over? ```r x <- c(1, 3, 6, 2) map_lgl(x, .f = ~(.x > 5 )) ``` ``` ## [1] FALSE FALSE TRUE FALSE ``` --- ### `map_XXX` Functions * Input: data frame + What did `map_XXX()` iterate over? ```r pdxTrees %>% select(DBH, Tree_Height, Pollution_Removal_oz) %>% map_dbl(.f = mean, na.rm = TRUE) ``` ``` ## DBH Tree_Height Pollution_Removal_oz ## 20.61408 65.73607 18.09618 ``` * Lists iterate over its elements. --- ### `map_XXX` Functions ```r pdxTrees %>% select(DBH, Condition, Pollution_Removal_oz) %>% map(class) ``` ``` ## $DBH ## [1] "numeric" ## ## $Condition ## [1] "character" ## ## $Pollution_Removal_oz ## [1] "numeric" ``` ```r pdxTrees %>% select(DBH, Condition, Pollution_Removal_oz) %>% map_chr(class) ``` ``` ## DBH Condition Pollution_Removal_oz ## "numeric" "character" "numeric" ``` --- ### `map_XXX` Functions ```r pdxTrees %>% select(Condition, Native) %>% map_int(n_distinct) ``` ``` ## Condition Native ## 4 3 ``` ```r map_lgl(c(1, 4, NA, 3), is.na) ``` ``` ## [1] FALSE FALSE TRUE FALSE ``` ```r pdxTrees %>% select(DBH, Condition, Native) %>% map_df(as.factor) %>% glimpse() ``` ``` ## Rows: 25,534 ## Columns: 3 ## $ DBH <fct> 37.4, 32.5, 9.7, 10.3, 33.2, 32.1, 28.4, 27.2, 35.2, 32.4, 3… ## $ Condition <fct> Fair, Fair, Fair, Poor, Fair, Fair, Fair, Fair, Fair, Fair, … ## $ Native <fct> Yes, Yes, No, No, Yes, Yes, Yes, Yes, Yes, Yes, Yes, No, Yes… ``` --- ### `map_XXX()` using `...` ```r pdxTrees %>% select(DBH, Tree_Height, Pollution_Removal_oz) %>% map_dbl(mean, na.rm = TRUE, trim = 0.1) ``` ``` ## DBH Tree_Height Pollution_Removal_oz ## 19.70520 62.95046 15.93507 ``` --- ### Anonymous Functions * As we saw, you can also supply anonymous functions to `map_XXX()`. ```r pdxTrees %>% select(DBH, Tree_Height, Pollution_Removal_oz) %>% map_dbl(.f = function(.x){ mean(.x, na.rm = TRUE) }) ``` ``` ## DBH Tree_Height Pollution_Removal_oz ## 20.61408 65.73607 18.09618 ``` --- ### Anonymous Functions ```r pdxTrees %>% select(Condition, Native, Tree_Height) %>% map_df(.f = function(.x) { data.frame(n_distinct = n_distinct(.x), class = class(.x)) }) ``` ``` ## n_distinct class ## 1 4 character ## 2 3 character ## 3 185 numeric ``` * What useful information did we lose? --- ### Anonymous Functions ```r pdxTrees %>% select(Condition, Native, Tree_Height) %>% map_df(.f = function(.x) { data.frame(n_distinct = n_distinct(.x), class = class(.x)) }, .id = "variable") ``` ``` ## variable n_distinct class ## 1 Condition 4 character ## 2 Native 3 character ## 3 Tree_Height 185 numeric ``` --- ### Returning to our Bootstrap Example ```r boot_mean <- function(x){ samp <- sample(x, replace = TRUE) mean(samp) } boot_mean(pdxTrees$DBH) ``` ``` ## [1] 20.55799 ``` ```r map_dbl(1:5, ~ boot_mean(pdxTrees$DBH)) ``` ``` ## [1] 20.62148 20.62270 20.59036 20.69682 20.62044 ``` --- ### Scary `list()` to Friendly `data.frame()` ```r # Examples of nested lists library(repurrrsive) ``` * `got_chars`: recursive list + Each element is a character in Game of Thrones * Want to put the `name`, `culture`, and `alive` into a `data.frame()`. ```r class(got_chars) ``` ``` ## [1] "list" ``` ```r got_chars ``` ``` ## [[1]] ## [[1]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1022" ## ## [[1]]$id ## [1] 1022 ## ## [[1]]$name ## [1] "Theon Greyjoy" ## ## [[1]]$gender ## [1] "Male" ## ## [[1]]$culture ## [1] "Ironborn" ## ## [[1]]$born ## [1] "In 278 AC or 279 AC, at Pyke" ## ## [[1]]$died ## [1] "" ## ## [[1]]$alive ## [1] TRUE ## ## [[1]]$titles ## [1] "Prince of Winterfell" ## [2] "Lord of the Iron Islands (by law of the green lands)" ## ## [[1]]$aliases ## [1] "Prince of Fools" "Theon Turncloak" "Reek" "Theon Kinslayer" ## ## [[1]]$father ## [1] "" ## ## [[1]]$mother ## [1] "" ## ## [[1]]$spouse ## [1] "" ## ## [[1]]$allegiances ## [1] "House Greyjoy of Pyke" ## ## [[1]]$books ## [1] "A Game of Thrones" "A Storm of Swords" "A Feast for Crows" ## ## [[1]]$povBooks ## [1] "A Clash of Kings" "A Dance with Dragons" ## ## [[1]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[1]]$playedBy ## [1] "Alfie Allen" ## ## ## [[2]] ## [[2]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1052" ## ## [[2]]$id ## [1] 1052 ## ## [[2]]$name ## [1] "Tyrion Lannister" ## ## [[2]]$gender ## [1] "Male" ## ## [[2]]$culture ## [1] "" ## ## [[2]]$born ## [1] "In 273 AC, at Casterly Rock" ## ## [[2]]$died ## [1] "" ## ## [[2]]$alive ## [1] TRUE ## ## [[2]]$titles ## [1] "Acting Hand of the King (former)" "Master of Coin (former)" ## ## [[2]]$aliases ## [1] "The Imp" "Halfman" "The boyman" ## [4] "Giant of Lannister" "Lord Tywin's Doom" "Lord Tywin's Bane" ## [7] "Yollo" "Hugor Hill" "No-Nose" ## [10] "Freak" "Dwarf" ## ## [[2]]$father ## [1] "" ## ## [[2]]$mother ## [1] "" ## ## [[2]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/2044" ## ## [[2]]$allegiances ## [1] "House Lannister of Casterly Rock" ## ## [[2]]$books ## [1] "A Feast for Crows" "The World of Ice and Fire" ## ## [[2]]$povBooks ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Dance with Dragons" ## ## [[2]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[2]]$playedBy ## [1] "Peter Dinklage" ## ## ## [[3]] ## [[3]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1074" ## ## [[3]]$id ## [1] 1074 ## ## [[3]]$name ## [1] "Victarion Greyjoy" ## ## [[3]]$gender ## [1] "Male" ## ## [[3]]$culture ## [1] "Ironborn" ## ## [[3]]$born ## [1] "In 268 AC or before, at Pyke" ## ## [[3]]$died ## [1] "" ## ## [[3]]$alive ## [1] TRUE ## ## [[3]]$titles ## [1] "Lord Captain of the Iron Fleet" "Master of the Iron Victory" ## ## [[3]]$aliases ## [1] "The Iron Captain" ## ## [[3]]$father ## [1] "" ## ## [[3]]$mother ## [1] "" ## ## [[3]]$spouse ## [1] "" ## ## [[3]]$allegiances ## [1] "House Greyjoy of Pyke" ## ## [[3]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## ## [[3]]$povBooks ## [1] "A Feast for Crows" "A Dance with Dragons" ## ## [[3]]$tvSeries ## [1] "" ## ## [[3]]$playedBy ## [1] "" ## ## ## [[4]] ## [[4]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1109" ## ## [[4]]$id ## [1] 1109 ## ## [[4]]$name ## [1] "Will" ## ## [[4]]$gender ## [1] "Male" ## ## [[4]]$culture ## [1] "" ## ## [[4]]$born ## [1] "" ## ## [[4]]$died ## [1] "In 297 AC, at Haunted Forest" ## ## [[4]]$alive ## [1] FALSE ## ## [[4]]$titles ## [1] "" ## ## [[4]]$aliases ## [1] "" ## ## [[4]]$father ## [1] "" ## ## [[4]]$mother ## [1] "" ## ## [[4]]$spouse ## [1] "" ## ## [[4]]$allegiances ## list() ## ## [[4]]$books ## [1] "A Clash of Kings" ## ## [[4]]$povBooks ## [1] "A Game of Thrones" ## ## [[4]]$tvSeries ## [1] "" ## ## [[4]]$playedBy ## [1] "Bronson Webb" ## ## ## [[5]] ## [[5]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1166" ## ## [[5]]$id ## [1] 1166 ## ## [[5]]$name ## [1] "Areo Hotah" ## ## [[5]]$gender ## [1] "Male" ## ## [[5]]$culture ## [1] "Norvoshi" ## ## [[5]]$born ## [1] "In 257 AC or before, at Norvos" ## ## [[5]]$died ## [1] "" ## ## [[5]]$alive ## [1] TRUE ## ## [[5]]$titles ## [1] "Captain of the Guard at Sunspear" ## ## [[5]]$aliases ## [1] "" ## ## [[5]]$father ## [1] "" ## ## [[5]]$mother ## [1] "" ## ## [[5]]$spouse ## [1] "" ## ## [[5]]$allegiances ## [1] "House Nymeros Martell of Sunspear" ## ## [[5]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## ## [[5]]$povBooks ## [1] "A Feast for Crows" "A Dance with Dragons" ## ## [[5]]$tvSeries ## [1] "Season 5" "Season 6" ## ## [[5]]$playedBy ## [1] "DeObia Oparei" ## ## ## [[6]] ## [[6]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1267" ## ## [[6]]$id ## [1] 1267 ## ## [[6]]$name ## [1] "Chett" ## ## [[6]]$gender ## [1] "Male" ## ## [[6]]$culture ## [1] "" ## ## [[6]]$born ## [1] "At Hag's Mire" ## ## [[6]]$died ## [1] "In 299 AC, at Fist of the First Men" ## ## [[6]]$alive ## [1] FALSE ## ## [[6]]$titles ## [1] "" ## ## [[6]]$aliases ## [1] "" ## ## [[6]]$father ## [1] "" ## ## [[6]]$mother ## [1] "" ## ## [[6]]$spouse ## [1] "" ## ## [[6]]$allegiances ## list() ## ## [[6]]$books ## [1] "A Game of Thrones" "A Clash of Kings" ## ## [[6]]$povBooks ## [1] "A Storm of Swords" ## ## [[6]]$tvSeries ## [1] "" ## ## [[6]]$playedBy ## [1] "" ## ## ## [[7]] ## [[7]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1295" ## ## [[7]]$id ## [1] 1295 ## ## [[7]]$name ## [1] "Cressen" ## ## [[7]]$gender ## [1] "Male" ## ## [[7]]$culture ## [1] "" ## ## [[7]]$born ## [1] "In 219 AC or 220 AC" ## ## [[7]]$died ## [1] "In 299 AC, at Dragonstone" ## ## [[7]]$alive ## [1] FALSE ## ## [[7]]$titles ## [1] "Maester" ## ## [[7]]$aliases ## [1] "" ## ## [[7]]$father ## [1] "" ## ## [[7]]$mother ## [1] "" ## ## [[7]]$spouse ## [1] "" ## ## [[7]]$allegiances ## list() ## ## [[7]]$books ## [1] "A Storm of Swords" "A Feast for Crows" ## ## [[7]]$povBooks ## [1] "A Clash of Kings" ## ## [[7]]$tvSeries ## [1] "Season 2" ## ## [[7]]$playedBy ## [1] "Oliver Ford" ## ## ## [[8]] ## [[8]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/130" ## ## [[8]]$id ## [1] 130 ## ## [[8]]$name ## [1] "Arianne Martell" ## ## [[8]]$gender ## [1] "Female" ## ## [[8]]$culture ## [1] "Dornish" ## ## [[8]]$born ## [1] "In 276 AC, at Sunspear" ## ## [[8]]$died ## [1] "" ## ## [[8]]$alive ## [1] TRUE ## ## [[8]]$titles ## [1] "Princess of Dorne" ## ## [[8]]$aliases ## [1] "" ## ## [[8]]$father ## [1] "" ## ## [[8]]$mother ## [1] "" ## ## [[8]]$spouse ## [1] "" ## ## [[8]]$allegiances ## [1] "House Nymeros Martell of Sunspear" ## ## [[8]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Dance with Dragons" ## ## [[8]]$povBooks ## [1] "A Feast for Crows" ## ## [[8]]$tvSeries ## [1] "" ## ## [[8]]$playedBy ## [1] "" ## ## ## [[9]] ## [[9]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1303" ## ## [[9]]$id ## [1] 1303 ## ## [[9]]$name ## [1] "Daenerys Targaryen" ## ## [[9]]$gender ## [1] "Female" ## ## [[9]]$culture ## [1] "Valyrian" ## ## [[9]]$born ## [1] "In 284 AC, at Dragonstone" ## ## [[9]]$died ## [1] "" ## ## [[9]]$alive ## [1] TRUE ## ## [[9]]$titles ## [1] "Queen of the Andals and the Rhoynar and the First Men, Lord of the Seven Kingdoms" ## [2] "Khaleesi of the Great Grass Sea" ## [3] "Breaker of Shackles/Chains" ## [4] "Queen of Meereen" ## [5] "Princess of Dragonstone" ## ## [[9]]$aliases ## [1] "Dany" "Daenerys Stormborn" ## [3] "The Unburnt" "Mother of Dragons" ## [5] "Mother" "Mhysa" ## [7] "The Silver Queen" "Silver Lady" ## [9] "Dragonmother" "The Dragon Queen" ## [11] "The Mad King's daughter" ## ## [[9]]$father ## [1] "" ## ## [[9]]$mother ## [1] "" ## ## [[9]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/1346" ## ## [[9]]$allegiances ## [1] "House Targaryen of King's Landing" ## ## [[9]]$books ## [1] "A Feast for Crows" ## ## [[9]]$povBooks ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Dance with Dragons" ## ## [[9]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[9]]$playedBy ## [1] "Emilia Clarke" ## ## ## [[10]] ## [[10]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/1319" ## ## [[10]]$id ## [1] 1319 ## ## [[10]]$name ## [1] "Davos Seaworth" ## ## [[10]]$gender ## [1] "Male" ## ## [[10]]$culture ## [1] "Westeros" ## ## [[10]]$born ## [1] "In 260 AC or before, at King's Landing" ## ## [[10]]$died ## [1] "" ## ## [[10]]$alive ## [1] TRUE ## ## [[10]]$titles ## [1] "Ser" "Lord of the Rainwood" ## [3] "Admiral of the Narrow Sea" "Hand of the King" ## ## [[10]]$aliases ## [1] "Onion Knight" "Davos Shorthand" "Ser Onions" "Onion Lord" ## [5] "Smuggler" ## ## [[10]]$father ## [1] "" ## ## [[10]]$mother ## [1] "" ## ## [[10]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/1676" ## ## [[10]]$allegiances ## [1] "House Baratheon of Dragonstone" "House Seaworth of Cape Wrath" ## ## [[10]]$books ## [1] "A Feast for Crows" ## ## [[10]]$povBooks ## [1] "A Clash of Kings" "A Storm of Swords" "A Dance with Dragons" ## ## [[10]]$tvSeries ## [1] "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[10]]$playedBy ## [1] "Liam Cunningham" ## ## ## [[11]] ## [[11]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/148" ## ## [[11]]$id ## [1] 148 ## ## [[11]]$name ## [1] "Arya Stark" ## ## [[11]]$gender ## [1] "Female" ## ## [[11]]$culture ## [1] "Northmen" ## ## [[11]]$born ## [1] "In 289 AC, at Winterfell" ## ## [[11]]$died ## [1] "" ## ## [[11]]$alive ## [1] TRUE ## ## [[11]]$titles ## [1] "Princess" ## ## [[11]]$aliases ## [1] "Arya Horseface" "Arya Underfoot" "Arry" ## [4] "Lumpyface" "Lumpyhead" "Stickboy" ## [7] "Weasel" "Nymeria" "Squan" ## [10] "Saltb" "Cat of the Canaly" "Bets" ## [13] "The Blind Girh" "The Ugly Little Girl" "Mercedenl" ## [16] "Mercye" ## ## [[11]]$father ## [1] "" ## ## [[11]]$mother ## [1] "" ## ## [[11]]$spouse ## [1] "" ## ## [[11]]$allegiances ## [1] "House Stark of Winterfell" ## ## [[11]]$books ## list() ## ## [[11]]$povBooks ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Feast for Crows" "A Dance with Dragons" ## ## [[11]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[11]]$playedBy ## [1] "Maisie Williams" ## ## ## [[12]] ## [[12]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/149" ## ## [[12]]$id ## [1] 149 ## ## [[12]]$name ## [1] "Arys Oakheart" ## ## [[12]]$gender ## [1] "Male" ## ## [[12]]$culture ## [1] "Reach" ## ## [[12]]$born ## [1] "At Old Oak" ## ## [[12]]$died ## [1] "In 300 AC, at the Greenblood" ## ## [[12]]$alive ## [1] FALSE ## ## [[12]]$titles ## [1] "Ser" ## ## [[12]]$aliases ## [1] "" ## ## [[12]]$father ## [1] "" ## ## [[12]]$mother ## [1] "" ## ## [[12]]$spouse ## [1] "" ## ## [[12]]$allegiances ## [1] "House Oakheart of Old Oak" ## ## [[12]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Dance with Dragons" ## ## [[12]]$povBooks ## [1] "A Feast for Crows" ## ## [[12]]$tvSeries ## [1] "" ## ## [[12]]$playedBy ## [1] "" ## ## ## [[13]] ## [[13]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/150" ## ## [[13]]$id ## [1] 150 ## ## [[13]]$name ## [1] "Asha Greyjoy" ## ## [[13]]$gender ## [1] "Female" ## ## [[13]]$culture ## [1] "Ironborn" ## ## [[13]]$born ## [1] "In 275 AC or 276 AC, at Pyke" ## ## [[13]]$died ## [1] "" ## ## [[13]]$alive ## [1] TRUE ## ## [[13]]$titles ## [1] "Princess" "Captain of the Black Wind" ## [3] "Conqueror of Deepwood Motte" ## ## [[13]]$aliases ## [1] "Esgred" "The Kraken's Daughter" ## ## [[13]]$father ## [1] "" ## ## [[13]]$mother ## [1] "" ## ## [[13]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/1372" ## ## [[13]]$allegiances ## [1] "House Greyjoy of Pyke" "House Ironmaker" ## ## [[13]]$books ## [1] "A Game of Thrones" "A Clash of Kings" ## ## [[13]]$povBooks ## [1] "A Feast for Crows" "A Dance with Dragons" ## ## [[13]]$tvSeries ## [1] "Season 2" "Season 3" "Season 4" ## ## [[13]]$playedBy ## [1] "Gemma Whelan" ## ## ## [[14]] ## [[14]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/168" ## ## [[14]]$id ## [1] 168 ## ## [[14]]$name ## [1] "Barristan Selmy" ## ## [[14]]$gender ## [1] "Male" ## ## [[14]]$culture ## [1] "Westeros" ## ## [[14]]$born ## [1] "In 237 AC" ## ## [[14]]$died ## [1] "" ## ## [[14]]$alive ## [1] TRUE ## ## [[14]]$titles ## [1] "Ser" "Hand of the Queen" ## ## [[14]]$aliases ## [1] "Barristan the Bold" "Arstan Whitebeard" "Ser Grandfather" ## [4] "Barristan the Old" "Old Ser" ## ## [[14]]$father ## [1] "" ## ## [[14]]$mother ## [1] "" ## ## [[14]]$spouse ## [1] "" ## ## [[14]]$allegiances ## [1] "House Selmy of Harvest Hall" "House Targaryen of King's Landing" ## ## [[14]]$books ## [1] "A Game of Thrones" "A Clash of Kings" ## [3] "A Storm of Swords" "A Feast for Crows" ## [5] "The World of Ice and Fire" ## ## [[14]]$povBooks ## [1] "A Dance with Dragons" ## ## [[14]]$tvSeries ## [1] "Season 1" "Season 3" "Season 4" "Season 5" ## ## [[14]]$playedBy ## [1] "Ian McElhinney" ## ## ## [[15]] ## [[15]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/2066" ## ## [[15]]$id ## [1] 2066 ## ## [[15]]$name ## [1] "Varamyr" ## ## [[15]]$gender ## [1] "Male" ## ## [[15]]$culture ## [1] "Free Folk" ## ## [[15]]$born ## [1] "At a village Beyond the Wall" ## ## [[15]]$died ## [1] "In 300 AC, at a village Beyond the Wall" ## ## [[15]]$alive ## [1] FALSE ## ## [[15]]$titles ## [1] "" ## ## [[15]]$aliases ## [1] "Varamyr Sixskins" "Haggon" "Lump" ## ## [[15]]$father ## [1] "" ## ## [[15]]$mother ## [1] "" ## ## [[15]]$spouse ## [1] "" ## ## [[15]]$allegiances ## list() ## ## [[15]]$books ## [1] "A Storm of Swords" ## ## [[15]]$povBooks ## [1] "A Dance with Dragons" ## ## [[15]]$tvSeries ## [1] "" ## ## [[15]]$playedBy ## [1] "" ## ## ## [[16]] ## [[16]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/208" ## ## [[16]]$id ## [1] 208 ## ## [[16]]$name ## [1] "Brandon Stark" ## ## [[16]]$gender ## [1] "Male" ## ## [[16]]$culture ## [1] "Northmen" ## ## [[16]]$born ## [1] "In 290 AC, at Winterfell" ## ## [[16]]$died ## [1] "" ## ## [[16]]$alive ## [1] TRUE ## ## [[16]]$titles ## [1] "Prince of Winterfell" ## ## [[16]]$aliases ## [1] "Bran" "Bran the Broken" "The Winged Wolf" ## ## [[16]]$father ## [1] "" ## ## [[16]]$mother ## [1] "" ## ## [[16]]$spouse ## [1] "" ## ## [[16]]$allegiances ## [1] "House Stark of Winterfell" ## ## [[16]]$books ## [1] "A Feast for Crows" ## ## [[16]]$povBooks ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Dance with Dragons" ## ## [[16]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 6" ## ## [[16]]$playedBy ## [1] "Isaac Hempstead-Wright" ## ## ## [[17]] ## [[17]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/216" ## ## [[17]]$id ## [1] 216 ## ## [[17]]$name ## [1] "Brienne of Tarth" ## ## [[17]]$gender ## [1] "Female" ## ## [[17]]$culture ## [1] "" ## ## [[17]]$born ## [1] "In 280 AC" ## ## [[17]]$died ## [1] "" ## ## [[17]]$alive ## [1] TRUE ## ## [[17]]$titles ## [1] "" ## ## [[17]]$aliases ## [1] "The Maid of Tarth" "Brienne the Beauty" "Brienne the Blue" ## ## [[17]]$father ## [1] "" ## ## [[17]]$mother ## [1] "" ## ## [[17]]$spouse ## [1] "" ## ## [[17]]$allegiances ## [1] "House Baratheon of Storm's End" "House Stark of Winterfell" ## [3] "House Tarth of Evenfall Hall" ## ## [[17]]$books ## [1] "A Clash of Kings" "A Storm of Swords" "A Dance with Dragons" ## ## [[17]]$povBooks ## [1] "A Feast for Crows" ## ## [[17]]$tvSeries ## [1] "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[17]]$playedBy ## [1] "Gwendoline Christie" ## ## ## [[18]] ## [[18]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/232" ## ## [[18]]$id ## [1] 232 ## ## [[18]]$name ## [1] "Catelyn Stark" ## ## [[18]]$gender ## [1] "Female" ## ## [[18]]$culture ## [1] "Rivermen" ## ## [[18]]$born ## [1] "In 264 AC, at Riverrun" ## ## [[18]]$died ## [1] "In 299 AC, at the Twins" ## ## [[18]]$alive ## [1] FALSE ## ## [[18]]$titles ## [1] "Lady of Winterfell" ## ## [[18]]$aliases ## [1] "Catelyn Tully" "Lady Stoneheart" "The Silent Sistet" ## [4] "Mother Mercilesr" "The Hangwomans" ## ## [[18]]$father ## [1] "" ## ## [[18]]$mother ## [1] "" ## ## [[18]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/339" ## ## [[18]]$allegiances ## [1] "House Stark of Winterfell" "House Tully of Riverrun" ## ## [[18]]$books ## [1] "A Feast for Crows" "A Dance with Dragons" ## ## [[18]]$povBooks ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## ## [[18]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" ## ## [[18]]$playedBy ## [1] "Michelle Fairley" ## ## ## [[19]] ## [[19]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/238" ## ## [[19]]$id ## [1] 238 ## ## [[19]]$name ## [1] "Cersei Lannister" ## ## [[19]]$gender ## [1] "Female" ## ## [[19]]$culture ## [1] "Westerman" ## ## [[19]]$born ## [1] "In 266 AC, at Casterly Rock" ## ## [[19]]$died ## [1] "" ## ## [[19]]$alive ## [1] TRUE ## ## [[19]]$titles ## [1] "Light of the West" "Queen Dowager" "Protector of the Realm" ## [4] "Lady of Casterly Rock" "Queen Regent" ## ## [[19]]$aliases ## [1] "" ## ## [[19]]$father ## [1] "" ## ## [[19]]$mother ## [1] "" ## ## [[19]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/901" ## ## [[19]]$allegiances ## [1] "House Lannister of Casterly Rock" ## ## [[19]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## ## [[19]]$povBooks ## [1] "A Feast for Crows" "A Dance with Dragons" ## ## [[19]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[19]]$playedBy ## [1] "Lena Headey" ## ## ## [[20]] ## [[20]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/339" ## ## [[20]]$id ## [1] 339 ## ## [[20]]$name ## [1] "Eddard Stark" ## ## [[20]]$gender ## [1] "Male" ## ## [[20]]$culture ## [1] "Northmen" ## ## [[20]]$born ## [1] "In 263 AC, at Winterfell" ## ## [[20]]$died ## [1] "In 299 AC, at Great Sept of Baelor in King's Landing" ## ## [[20]]$alive ## [1] FALSE ## ## [[20]]$titles ## [1] "Lord of Winterfell" "Warden of the North" "Hand of the King" ## [4] "Protector of the Realm" "Regent" ## ## [[20]]$aliases ## [1] "Ned" "The Ned" "The Quiet Wolf" ## ## [[20]]$father ## [1] "" ## ## [[20]]$mother ## [1] "" ## ## [[20]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/232" ## ## [[20]]$allegiances ## [1] "House Stark of Winterfell" ## ## [[20]]$books ## [1] "A Clash of Kings" "A Storm of Swords" ## [3] "A Feast for Crows" "A Dance with Dragons" ## [5] "The World of Ice and Fire" ## ## [[20]]$povBooks ## [1] "A Game of Thrones" ## ## [[20]]$tvSeries ## [1] "Season 1" "Season 6" ## ## [[20]]$playedBy ## [1] "Sean Bean" "Sebastian Croft" "Robert Aramayo" ## ## ## [[21]] ## [[21]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/529" ## ## [[21]]$id ## [1] 529 ## ## [[21]]$name ## [1] "Jaime Lannister" ## ## [[21]]$gender ## [1] "Male" ## ## [[21]]$culture ## [1] "Westerlands" ## ## [[21]]$born ## [1] "In 266 AC, at Casterly Rock" ## ## [[21]]$died ## [1] "" ## ## [[21]]$alive ## [1] TRUE ## ## [[21]]$titles ## [1] "Ser" "Lord Commander of the Kingsguard" ## [3] "Warden of the East (formerly)" ## ## [[21]]$aliases ## [1] "The Kingslayer" "The Lion of Lannister" "The Young Lion" ## [4] "Cripple" ## ## [[21]]$father ## [1] "" ## ## [[21]]$mother ## [1] "" ## ## [[21]]$spouse ## [1] "" ## ## [[21]]$allegiances ## [1] "House Lannister of Casterly Rock" ## ## [[21]]$books ## [1] "A Game of Thrones" "A Clash of Kings" ## ## [[21]]$povBooks ## [1] "A Storm of Swords" "A Feast for Crows" "A Dance with Dragons" ## ## [[21]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" ## ## [[21]]$playedBy ## [1] "Nikolaj Coster-Waldau" ## ## ## [[22]] ## [[22]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/576" ## ## [[22]]$id ## [1] 576 ## ## [[22]]$name ## [1] "Jon Connington" ## ## [[22]]$gender ## [1] "Male" ## ## [[22]]$culture ## [1] "Stormlands" ## ## [[22]]$born ## [1] "In or between 263 AC and 265 AC" ## ## [[22]]$died ## [1] "" ## ## [[22]]$alive ## [1] TRUE ## ## [[22]]$titles ## [1] "Lord of Griffin's Roost" "Hand of the King" ## [3] "Hand of the True King" ## ## [[22]]$aliases ## [1] "Griffthe Mad King's Hand" ## ## [[22]]$father ## [1] "" ## ## [[22]]$mother ## [1] "" ## ## [[22]]$spouse ## [1] "" ## ## [[22]]$allegiances ## [1] "House Connington of Griffin's Roost" "House Targaryen of King's Landing" ## ## [[22]]$books ## [1] "A Storm of Swords" "A Feast for Crows" ## [3] "The World of Ice and Fire" ## ## [[22]]$povBooks ## [1] "A Dance with Dragons" ## ## [[22]]$tvSeries ## [1] "" ## ## [[22]]$playedBy ## [1] "" ## ## ## [[23]] ## [[23]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/583" ## ## [[23]]$id ## [1] 583 ## ## [[23]]$name ## [1] "Jon Snow" ## ## [[23]]$gender ## [1] "Male" ## ## [[23]]$culture ## [1] "Northmen" ## ## [[23]]$born ## [1] "In 283 AC" ## ## [[23]]$died ## [1] "" ## ## [[23]]$alive ## [1] TRUE ## ## [[23]]$titles ## [1] "Lord Commander of the Night's Watch" ## ## [[23]]$aliases ## [1] "Lord Snow" ## [2] "Ned Stark's Bastard" ## [3] "The Snow of Winterfell" ## [4] "The Crow-Come-Over" ## [5] "The 998th Lord Commander of the Night's Watch" ## [6] "The Bastard of Winterfell" ## [7] "The Black Bastard of the Wall" ## [8] "Lord Crow" ## ## [[23]]$father ## [1] "" ## ## [[23]]$mother ## [1] "" ## ## [[23]]$spouse ## [1] "" ## ## [[23]]$allegiances ## [1] "House Stark of Winterfell" ## ## [[23]]$books ## [1] "A Feast for Crows" ## ## [[23]]$povBooks ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Dance with Dragons" ## ## [[23]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[23]]$playedBy ## [1] "Kit Harington" ## ## ## [[24]] ## [[24]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/60" ## ## [[24]]$id ## [1] 60 ## ## [[24]]$name ## [1] "Aeron Greyjoy" ## ## [[24]]$gender ## [1] "Male" ## ## [[24]]$culture ## [1] "Ironborn" ## ## [[24]]$born ## [1] "In or between 269 AC and 273 AC, at Pyke" ## ## [[24]]$died ## [1] "" ## ## [[24]]$alive ## [1] TRUE ## ## [[24]]$titles ## [1] "Priest of the Drowned God" ## [2] "Captain of the Golden Storm (formerly)" ## ## [[24]]$aliases ## [1] "The Damphair" "Aeron Damphair" ## ## [[24]]$father ## [1] "" ## ## [[24]]$mother ## [1] "" ## ## [[24]]$spouse ## [1] "" ## ## [[24]]$allegiances ## [1] "House Greyjoy of Pyke" ## ## [[24]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Dance with Dragons" ## ## [[24]]$povBooks ## [1] "A Feast for Crows" ## ## [[24]]$tvSeries ## [1] "Season 6" ## ## [[24]]$playedBy ## [1] "Michael Feast" ## ## ## [[25]] ## [[25]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/605" ## ## [[25]]$id ## [1] 605 ## ## [[25]]$name ## [1] "Kevan Lannister" ## ## [[25]]$gender ## [1] "Male" ## ## [[25]]$culture ## [1] "" ## ## [[25]]$born ## [1] "In 244 AC" ## ## [[25]]$died ## [1] "In 300 AC, at King's Landing" ## ## [[25]]$alive ## [1] FALSE ## ## [[25]]$titles ## [1] "Ser" "Master of laws" "Lord Regent" ## [4] "Protector of the Realm" ## ## [[25]]$aliases ## [1] "" ## ## [[25]]$father ## [1] "" ## ## [[25]]$mother ## [1] "" ## ## [[25]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/327" ## ## [[25]]$allegiances ## [1] "House Lannister of Casterly Rock" ## ## [[25]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Feast for Crows" ## ## [[25]]$povBooks ## [1] "A Dance with Dragons" ## ## [[25]]$tvSeries ## [1] "Season 1" "Season 2" "Season 5" "Season 6" ## ## [[25]]$playedBy ## [1] "Ian Gelder" ## ## ## [[26]] ## [[26]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/743" ## ## [[26]]$id ## [1] 743 ## ## [[26]]$name ## [1] "Melisandre" ## ## [[26]]$gender ## [1] "Female" ## ## [[26]]$culture ## [1] "Asshai" ## ## [[26]]$born ## [1] "At Unknown" ## ## [[26]]$died ## [1] "" ## ## [[26]]$alive ## [1] TRUE ## ## [[26]]$titles ## [1] "" ## ## [[26]]$aliases ## [1] "The Red Priestess" "The Red Woman" "The King's Red Shadow" ## [4] "Lady Red" "Lot Seven" ## ## [[26]]$father ## [1] "" ## ## [[26]]$mother ## [1] "" ## ## [[26]]$spouse ## [1] "" ## ## [[26]]$allegiances ## list() ## ## [[26]]$books ## [1] "A Clash of Kings" "A Storm of Swords" "A Feast for Crows" ## ## [[26]]$povBooks ## [1] "A Dance with Dragons" ## ## [[26]]$tvSeries ## [1] "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[26]]$playedBy ## [1] "Carice van Houten" ## ## ## [[27]] ## [[27]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/751" ## ## [[27]]$id ## [1] 751 ## ## [[27]]$name ## [1] "Merrett Frey" ## ## [[27]]$gender ## [1] "Male" ## ## [[27]]$culture ## [1] "Rivermen" ## ## [[27]]$born ## [1] "In 262 AC" ## ## [[27]]$died ## [1] "In 300 AC, at Near Oldstones" ## ## [[27]]$alive ## [1] FALSE ## ## [[27]]$titles ## [1] "" ## ## [[27]]$aliases ## [1] "Merrett Muttonhead" ## ## [[27]]$father ## [1] "" ## ## [[27]]$mother ## [1] "" ## ## [[27]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/712" ## ## [[27]]$allegiances ## [1] "House Frey of the Crossing" ## ## [[27]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Feast for Crows" ## [4] "A Dance with Dragons" ## ## [[27]]$povBooks ## [1] "A Storm of Swords" ## ## [[27]]$tvSeries ## [1] "" ## ## [[27]]$playedBy ## [1] "" ## ## ## [[28]] ## [[28]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/844" ## ## [[28]]$id ## [1] 844 ## ## [[28]]$name ## [1] "Quentyn Martell" ## ## [[28]]$gender ## [1] "Male" ## ## [[28]]$culture ## [1] "Dornish" ## ## [[28]]$born ## [1] "In 281 AC, at Sunspear, Dorne" ## ## [[28]]$died ## [1] "In 300 AC, at Meereen" ## ## [[28]]$alive ## [1] FALSE ## ## [[28]]$titles ## [1] "Prince" ## ## [[28]]$aliases ## [1] "Frog" "Prince Frog" ## [3] "The prince who came too late" "The Dragonrider" ## ## [[28]]$father ## [1] "" ## ## [[28]]$mother ## [1] "" ## ## [[28]]$spouse ## [1] "" ## ## [[28]]$allegiances ## [1] "House Nymeros Martell of Sunspear" ## ## [[28]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Feast for Crows" ## ## [[28]]$povBooks ## [1] "A Dance with Dragons" ## ## [[28]]$tvSeries ## [1] "" ## ## [[28]]$playedBy ## [1] "" ## ## ## [[29]] ## [[29]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/954" ## ## [[29]]$id ## [1] 954 ## ## [[29]]$name ## [1] "Samwell Tarly" ## ## [[29]]$gender ## [1] "Male" ## ## [[29]]$culture ## [1] "Andal" ## ## [[29]]$born ## [1] "In 283 AC, at Horn Hill" ## ## [[29]]$died ## [1] "" ## ## [[29]]$alive ## [1] TRUE ## ## [[29]]$titles ## [1] "" ## ## [[29]]$aliases ## [1] "Sam" "Ser Piggy" "Prince Pork-chop" "Lady Piggy" ## [5] "Sam the Slayer" "Black Sam" "Lord of Ham" ## ## [[29]]$father ## [1] "" ## ## [[29]]$mother ## [1] "" ## ## [[29]]$spouse ## [1] "" ## ## [[29]]$allegiances ## [1] "House Tarly of Horn Hill" ## ## [[29]]$books ## [1] "A Game of Thrones" "A Clash of Kings" "A Dance with Dragons" ## ## [[29]]$povBooks ## [1] "A Storm of Swords" "A Feast for Crows" ## ## [[29]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[29]]$playedBy ## [1] "John Bradley-West" ## ## ## [[30]] ## [[30]]$url ## [1] "https://www.anapioficeandfire.com/api/characters/957" ## ## [[30]]$id ## [1] 957 ## ## [[30]]$name ## [1] "Sansa Stark" ## ## [[30]]$gender ## [1] "Female" ## ## [[30]]$culture ## [1] "Northmen" ## ## [[30]]$born ## [1] "In 286 AC, at Winterfell" ## ## [[30]]$died ## [1] "" ## ## [[30]]$alive ## [1] TRUE ## ## [[30]]$titles ## [1] "Princess" ## ## [[30]]$aliases ## [1] "Little bird" "Alayne Stone" "Jonquil" ## ## [[30]]$father ## [1] "" ## ## [[30]]$mother ## [1] "" ## ## [[30]]$spouse ## [1] "https://www.anapioficeandfire.com/api/characters/1052" ## ## [[30]]$allegiances ## [1] "House Baelish of Harrenhal" "House Stark of Winterfell" ## ## [[30]]$books ## [1] "A Dance with Dragons" ## ## [[30]]$povBooks ## [1] "A Game of Thrones" "A Clash of Kings" "A Storm of Swords" ## [4] "A Feast for Crows" ## ## [[30]]$tvSeries ## [1] "Season 1" "Season 2" "Season 3" "Season 4" "Season 5" "Season 6" ## ## [[30]]$playedBy ## [1] "Sophie Turner" ``` --- ### Scary `list()` to Friendly `data.frame()` ```r class(got_chars[[1]]) ``` ``` ## [1] "list" ``` ```r names(got_chars[[1]]) ``` ``` ## [1] "url" "id" "name" "gender" "culture" ## [6] "born" "died" "alive" "titles" "aliases" ## [11] "father" "mother" "spouse" "allegiances" "books" ## [16] "povBooks" "tvSeries" "playedBy" ``` --- ### Scary `list()` to Friendly `data.frame()` Explain what the following code does. ```r got_chars[[1]]["name"] ``` ``` ## $name ## [1] "Theon Greyjoy" ``` ```r got_chars[[1]][3] ``` ``` ## $name ## [1] "Theon Greyjoy" ``` How should we generalize this to extract the `name`, `culture`, and `alive` for the first character? --- ### Scary `list()` to Friendly `data.frame()` How should we generalize this to extract the `name`, `culture`, and `alive` for the first character? ```r got_chars[[1]][c("name", "culture", "alive")] ``` ``` ## $name ## [1] "Theon Greyjoy" ## ## $culture ## [1] "Ironborn" ## ## $alive ## [1] TRUE ``` --- ### Scary `list()` to Friendly `data.frame()` ```r names(got_chars[[1]]) ``` ``` ## [1] "url" "id" "name" "gender" "culture" ## [6] "born" "died" "alive" "titles" "aliases" ## [11] "father" "mother" "spouse" "allegiances" "books" ## [16] "povBooks" "tvSeries" "playedBy" ``` ```r got_chars[[1]][c(3, 5, 8)] ``` ``` ## $name ## [1] "Theon Greyjoy" ## ## $culture ## [1] "Ironborn" ## ## $alive ## [1] TRUE ``` * What do I want to store? + What type of R object do I want? + What's the required size? --- ### Scary `list()` to Friendly `data.frame()` ```r got_chars_df <- data.frame(name = rep(NA, 30), culture = rep(NA, 30), alive = rep(NA, 30)) dim(got_chars_df) ``` ``` ## [1] 30 3 ``` How should I save the information in `got_chars_df`? --- ### `for()` Loop Version ```r # Set i and j to test i <- 1 j <- 2 # Variable locations locations <- c(3, 5, 8) # Grab the jth variable of the ith person got_chars[[i]][locations[j]] ``` ``` ## $culture ## [1] "Ironborn" ``` ```r # Another option k <- locations[j] got_chars[[i]][k] ``` ``` ## $culture ## [1] "Ironborn" ``` ```r # Store got_chars_df[i, j] <- got_chars[[i]][k] ``` --- ### Scary `list()` to Friendly `data.frame()` ```r got_chars_df <- data.frame(name = rep(NA, 30), culture = rep(NA, 30), alive = rep(NA, 30)) locations <- c(3, 5, 8) for(j in 1:ncol(got_chars_df)){ for(i in 1:nrow(got_chars_df)){ k <- locations[j] got_chars_df[i, j] <- got_chars[[i]][k] } } ``` --- ### Scary `list()` to Friendly `data.frame()` * We did it! ```r got_chars_df ``` ``` ## name culture alive ## 1 Theon Greyjoy Ironborn TRUE ## 2 Tyrion Lannister TRUE ## 3 Victarion Greyjoy Ironborn TRUE ## 4 Will FALSE ## 5 Areo Hotah Norvoshi TRUE ## 6 Chett FALSE ## 7 Cressen FALSE ## 8 Arianne Martell Dornish TRUE ## 9 Daenerys Targaryen Valyrian TRUE ## 10 Davos Seaworth Westeros TRUE ## 11 Arya Stark Northmen TRUE ## 12 Arys Oakheart Reach FALSE ## 13 Asha Greyjoy Ironborn TRUE ## 14 Barristan Selmy Westeros TRUE ## 15 Varamyr Free Folk FALSE ## 16 Brandon Stark Northmen TRUE ## 17 Brienne of Tarth TRUE ## 18 Catelyn Stark Rivermen FALSE ## 19 Cersei Lannister Westerman TRUE ## 20 Eddard Stark Northmen FALSE ## 21 Jaime Lannister Westerlands TRUE ## 22 Jon Connington Stormlands TRUE ## 23 Jon Snow Northmen TRUE ## 24 Aeron Greyjoy Ironborn TRUE ## 25 Kevan Lannister FALSE ## 26 Melisandre Asshai TRUE ## 27 Merrett Frey Rivermen FALSE ## 28 Quentyn Martell Dornish FALSE ## 29 Samwell Tarly Andal TRUE ## 30 Sansa Stark Northmen TRUE ``` --- class: middle, center ## Now how can we use `purrr` to convert the scary `list()` to friendly `data.frame()`? --- ### Scary `list()` to Friendly `data.frame()` * Let's start with `name`. * Translate into words what the following anonymous function is doing. ```r map(got_chars, ~ .x[[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" ``` --- ### Scary `list()` to Friendly `data.frame()` * Shortcut ```r map(got_chars, 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" ``` --- ### Scary `list()` to Friendly `data.frame()` * Another shortcut * How do we change this to a **vector()** output instead of a **list()** output? ```r map(got_chars, "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" ``` --- ### Scary `list()` to Friendly `data.frame()` * How do we change this to a **vector()** output instead of a **list()** output? ```r map_chr(got_chars, "name") ``` ``` ## [1] "Theon Greyjoy" "Tyrion Lannister" "Victarion Greyjoy" ## [4] "Will" "Areo Hotah" "Chett" ## [7] "Cressen" "Arianne Martell" "Daenerys Targaryen" ## [10] "Davos Seaworth" "Arya Stark" "Arys Oakheart" ## [13] "Asha Greyjoy" "Barristan Selmy" "Varamyr" ## [16] "Brandon Stark" "Brienne of Tarth" "Catelyn Stark" ## [19] "Cersei Lannister" "Eddard Stark" "Jaime Lannister" ## [22] "Jon Connington" "Jon Snow" "Aeron Greyjoy" ## [25] "Kevan Lannister" "Melisandre" "Merrett Frey" ## [28] "Quentyn Martell" "Samwell Tarly" "Sansa Stark" ``` --- ### Scary `list()` to Friendly `data.frame()` Let's go back to the code that grabs the `name`, `culture`, and `alive` for the first character. ```r got_chars[[1]][c("name", "culture", "alive")] ``` ``` ## $name ## [1] "Theon Greyjoy" ## ## $culture ## [1] "Ironborn" ## ## $alive ## [1] TRUE ``` --- ### Scary `list()` to Friendly `data.frame()` * For all characters, we will use the `[` function ```r map(got_chars, `[`, c("name", "culture", "alive")) ``` ``` ## [[1]] ## [[1]]$name ## [1] "Theon Greyjoy" ## ## [[1]]$culture ## [1] "Ironborn" ## ## [[1]]$alive ## [1] TRUE ## ## ## [[2]] ## [[2]]$name ## [1] "Tyrion Lannister" ## ## [[2]]$culture ## [1] "" ## ## [[2]]$alive ## [1] TRUE ## ## ## [[3]] ## [[3]]$name ## [1] "Victarion Greyjoy" ## ## [[3]]$culture ## [1] "Ironborn" ## ## [[3]]$alive ## [1] TRUE ## ## ## [[4]] ## [[4]]$name ## [1] "Will" ## ## [[4]]$culture ## [1] "" ## ## [[4]]$alive ## [1] FALSE ## ## ## [[5]] ## [[5]]$name ## [1] "Areo Hotah" ## ## [[5]]$culture ## [1] "Norvoshi" ## ## [[5]]$alive ## [1] TRUE ## ## ## [[6]] ## [[6]]$name ## [1] "Chett" ## ## [[6]]$culture ## [1] "" ## ## [[6]]$alive ## [1] FALSE ## ## ## [[7]] ## [[7]]$name ## [1] "Cressen" ## ## [[7]]$culture ## [1] "" ## ## [[7]]$alive ## [1] FALSE ## ## ## [[8]] ## [[8]]$name ## [1] "Arianne Martell" ## ## [[8]]$culture ## [1] "Dornish" ## ## [[8]]$alive ## [1] TRUE ## ## ## [[9]] ## [[9]]$name ## [1] "Daenerys Targaryen" ## ## [[9]]$culture ## [1] "Valyrian" ## ## [[9]]$alive ## [1] TRUE ## ## ## [[10]] ## [[10]]$name ## [1] "Davos Seaworth" ## ## [[10]]$culture ## [1] "Westeros" ## ## [[10]]$alive ## [1] TRUE ## ## ## [[11]] ## [[11]]$name ## [1] "Arya Stark" ## ## [[11]]$culture ## [1] "Northmen" ## ## [[11]]$alive ## [1] TRUE ## ## ## [[12]] ## [[12]]$name ## [1] "Arys Oakheart" ## ## [[12]]$culture ## [1] "Reach" ## ## [[12]]$alive ## [1] FALSE ## ## ## [[13]] ## [[13]]$name ## [1] "Asha Greyjoy" ## ## [[13]]$culture ## [1] "Ironborn" ## ## [[13]]$alive ## [1] TRUE ## ## ## [[14]] ## [[14]]$name ## [1] "Barristan Selmy" ## ## [[14]]$culture ## [1] "Westeros" ## ## [[14]]$alive ## [1] TRUE ## ## ## [[15]] ## [[15]]$name ## [1] "Varamyr" ## ## [[15]]$culture ## [1] "Free Folk" ## ## [[15]]$alive ## [1] FALSE ## ## ## [[16]] ## [[16]]$name ## [1] "Brandon Stark" ## ## [[16]]$culture ## [1] "Northmen" ## ## [[16]]$alive ## [1] TRUE ## ## ## [[17]] ## [[17]]$name ## [1] "Brienne of Tarth" ## ## [[17]]$culture ## [1] "" ## ## [[17]]$alive ## [1] TRUE ## ## ## [[18]] ## [[18]]$name ## [1] "Catelyn Stark" ## ## [[18]]$culture ## [1] "Rivermen" ## ## [[18]]$alive ## [1] FALSE ## ## ## [[19]] ## [[19]]$name ## [1] "Cersei Lannister" ## ## [[19]]$culture ## [1] "Westerman" ## ## [[19]]$alive ## [1] TRUE ## ## ## [[20]] ## [[20]]$name ## [1] "Eddard Stark" ## ## [[20]]$culture ## [1] "Northmen" ## ## [[20]]$alive ## [1] FALSE ## ## ## [[21]] ## [[21]]$name ## [1] "Jaime Lannister" ## ## [[21]]$culture ## [1] "Westerlands" ## ## [[21]]$alive ## [1] TRUE ## ## ## [[22]] ## [[22]]$name ## [1] "Jon Connington" ## ## [[22]]$culture ## [1] "Stormlands" ## ## [[22]]$alive ## [1] TRUE ## ## ## [[23]] ## [[23]]$name ## [1] "Jon Snow" ## ## [[23]]$culture ## [1] "Northmen" ## ## [[23]]$alive ## [1] TRUE ## ## ## [[24]] ## [[24]]$name ## [1] "Aeron Greyjoy" ## ## [[24]]$culture ## [1] "Ironborn" ## ## [[24]]$alive ## [1] TRUE ## ## ## [[25]] ## [[25]]$name ## [1] "Kevan Lannister" ## ## [[25]]$culture ## [1] "" ## ## [[25]]$alive ## [1] FALSE ## ## ## [[26]] ## [[26]]$name ## [1] "Melisandre" ## ## [[26]]$culture ## [1] "Asshai" ## ## [[26]]$alive ## [1] TRUE ## ## ## [[27]] ## [[27]]$name ## [1] "Merrett Frey" ## ## [[27]]$culture ## [1] "Rivermen" ## ## [[27]]$alive ## [1] FALSE ## ## ## [[28]] ## [[28]]$name ## [1] "Quentyn Martell" ## ## [[28]]$culture ## [1] "Dornish" ## ## [[28]]$alive ## [1] FALSE ## ## ## [[29]] ## [[29]]$name ## [1] "Samwell Tarly" ## ## [[29]]$culture ## [1] "Andal" ## ## [[29]]$alive ## [1] TRUE ## ## ## [[30]] ## [[30]]$name ## [1] "Sansa Stark" ## ## [[30]]$culture ## [1] "Northmen" ## ## [[30]]$alive ## [1] TRUE ``` --- ### Scary `list()` to Friendly `data.frame()` **Finally**: Let's make it into a data frame. * `dfr`: `r` stands for row binding. ```r map_dfr(got_chars, `[`, c("name", "culture", "alive")) ``` ``` ## # A tibble: 30 × 3 ## name culture alive ## <chr> <chr> <lgl> ## 1 Theon Greyjoy "Ironborn" TRUE ## 2 Tyrion Lannister "" TRUE ## 3 Victarion Greyjoy "Ironborn" TRUE ## 4 Will "" FALSE ## 5 Areo Hotah "Norvoshi" TRUE ## 6 Chett "" FALSE ## 7 Cressen "" FALSE ## 8 Arianne Martell "Dornish" TRUE ## 9 Daenerys Targaryen "Valyrian" TRUE ## 10 Davos Seaworth "Westeros" TRUE ## # … with 20 more rows ``` --- ### Two Routes to the Same End ```r map_dfr(got_chars, `[`, c("name", "culture", "alive")) ``` **Versus** ```r got_chars_df <- data.frame(name = rep(NA, 30), culture = rep(NA, 30), alive = rep(NA, 30)) locations <- c(3, 5, 8) for(j in 1:ncol(got_chars_df)){ for(i in 1:nrow(got_chars_df)){ k <- locations[j] got_chars_df[i, j] <- got_chars[[i]][k] } } ``` **Pros/Cons?** --- ```r system.time({ got_chars_df <- map_dfr(got_chars, `[`, c("name", "culture", "alive")) }) ``` ``` ## user system elapsed ## 0.006 0.000 0.006 ``` ```r system.time({ got_chars_df <- data.frame(name = rep(NA, 30), culture = rep(NA, 30), alive = rep(NA, 30)) locations <- c(3, 5, 8) for(j in 1:ncol(got_chars_df)){ for(i in 1:nrow(got_chars_df)){ k <- locations[j] got_chars_df[i, j] <- got_chars[[i]][k] } } }) ``` ``` ## user system elapsed ## 0.011 0.000 0.012 ``` --- ### Closing Sage Thoughts > "But you should never feel bad about using a for loop instead of a map function. The map functions are a step up a tower of abstraction, and it can take a long time to get your head around how they work. The important thing is that you solve the problem that you’re working on, not write the most concise and elegant code (although that’s definitely something you want to strive towards!)." -- Hadley Wickham & Garrett Grolemund * Both of my current thesis students did large simulation studies that used `for()` loops!