#install.packages("pokemon")

Load relevant libraries

library(dplyr) 
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr) 
library(ggplot2)
library(gt)
## Warning: package 'gt' was built under R version 4.5.2

Import pokemon dataset and name the data frame allpokemon

allpokemon <- pokemon::pokemon

A quick glance at the dataframe

?pokemon
## starting httpd help server ... done
head(allpokemon)
## # A tibble: 6 × 22
##      id pokemon    species_id height weight base_experience type_1 type_2    hp
##   <dbl> <chr>           <dbl>  <dbl>  <dbl>           <dbl> <chr>  <chr>  <dbl>
## 1     1 bulbasaur           1    0.7    6.9              64 grass  poison    45
## 2     2 ivysaur             2    1     13               142 grass  poison    60
## 3     3 venusaur            3    2    100               236 grass  poison    80
## 4     4 charmander          4    0.6    8.5              62 fire   <NA>      39
## 5     5 charmeleon          5    1.1   19               142 fire   <NA>      58
## 6     6 charizard           6    1.7   90.5             240 fire   flying    78
## # ℹ 13 more variables: attack <dbl>, defense <dbl>, special_attack <dbl>,
## #   special_defense <dbl>, speed <dbl>, color_1 <chr>, color_2 <chr>,
## #   color_f <chr>, egg_group_1 <chr>, egg_group_2 <chr>, url_icon <chr>,
## #   generation_id <dbl>, url_image <chr>
tail(allpokemon)
## # A tibble: 6 × 22
##      id pokemon     species_id height weight base_experience type_1 type_2    hp
##   <dbl> <chr>            <dbl>  <dbl>  <dbl>           <dbl> <chr>  <chr>  <dbl>
## 1 10142 minior-vio…        774    0.3    0.3             175 rock   flying    60
## 2 10143 mimikyu-bu…        778    0.2    0.7             167 ghost  fairy     55
## 3 10144 mimikyu-to…        778    0.4    2.8             167 ghost  fairy     55
## 4 10145 mimikyu-to…        778    0.4    2.8             167 ghost  fairy     55
## 5 10146 kommo-o-to…        784    2.4  208.              270 dragon fight…    75
## 6 10147 magearna-o…        801    1     80.5             120 steel  fairy     80
## # ℹ 13 more variables: attack <dbl>, defense <dbl>, special_attack <dbl>,
## #   special_defense <dbl>, speed <dbl>, color_1 <chr>, color_2 <chr>,
## #   color_f <chr>, egg_group_1 <chr>, egg_group_2 <chr>, url_icon <chr>,
## #   generation_id <dbl>, url_image <chr>
summary(allpokemon)
##        id          pokemon            species_id        height      
##  Min.   :    1   Length:949         Min.   :  1.0   Min.   : 0.100  
##  1st Qu.:  238   Class :character   1st Qu.:191.0   1st Qu.: 0.500  
##  Median :  475   Mode  :character   Median :395.0   Median : 1.000  
##  Mean   : 1900                      Mean   :400.1   Mean   : 1.228  
##  3rd Qu.:  712                      3rd Qu.:615.0   3rd Qu.: 1.500  
##  Max.   :10147                      Max.   :802.0   Max.   :14.500  
##                                                                     
##      weight       base_experience    type_1             type_2         
##  Min.   :  0.10   Min.   : 36.0   Length:949         Length:949        
##  1st Qu.:  8.50   1st Qu.: 68.0   Class :character   Class :character  
##  Median : 28.80   Median :157.0   Mode  :character   Mode  :character  
##  Mean   : 66.21   Mean   :150.5                                        
##  3rd Qu.: 66.60   3rd Qu.:184.0                                        
##  Max.   :999.90   Max.   :608.0                                        
##                                                                        
##        hp             attack          defense       special_attack  
##  Min.   :  1.00   Min.   :  5.00   Min.   :  5.00   Min.   : 10.00  
##  1st Qu.: 50.00   1st Qu.: 55.00   1st Qu.: 50.00   1st Qu.: 50.00  
##  Median : 65.00   Median : 75.00   Median : 70.00   Median : 65.00  
##  Mean   : 68.95   Mean   : 79.47   Mean   : 74.07   Mean   : 72.81  
##  3rd Qu.: 80.00   3rd Qu.:100.00   3rd Qu.: 90.00   3rd Qu.: 95.00  
##  Max.   :255.00   Max.   :190.00   Max.   :230.00   Max.   :194.00  
##                                                                     
##  special_defense      speed          color_1            color_2         
##  Min.   : 20.00   Min.   :  5.00   Length:949         Length:949        
##  1st Qu.: 50.00   1st Qu.: 45.00   Class :character   Class :character  
##  Median : 70.00   Median : 65.00   Mode  :character   Mode  :character  
##  Mean   : 72.22   Mean   : 69.02                                        
##  3rd Qu.: 90.00   3rd Qu.: 90.00                                        
##  Max.   :230.00   Max.   :180.00                                        
##                                                                         
##    color_f          egg_group_1        egg_group_2          url_icon        
##  Length:949         Length:949         Length:949         Length:949        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##  generation_id    url_image        
##  Min.   :1.000   Length:949        
##  1st Qu.:2.000   Class :character  
##  Median :4.000   Mode  :character  
##  Mean   :3.695                     
##  3rd Qu.:5.000                     
##  Max.   :7.000                     
##  NA's   :147

After running the above code I noticed a few things:

- 147 pokemon with NA for generation_id (upon viewing the dataframe noted that they were special pokemon that I didn't want in my results)
- There was no total stat points column for each pokemon which I was really interested in (This is what I was going to test to determine each pokemon types overall strength)
- type_1 was primary typing and type_2 was secondary type if it had one (since I want to plot total stats based on typing I will need to count some pokemon for both types)

Therefore I used dplyr filter to remove pokemon which had NA for generation_id Then I used dplyr mutate to create the total stat points for each pokemon

filteredpokemon <- allpokemon |> filter(!is.na(generation_id))
pokemonwtotal <- filteredpokemon |>
  mutate(total_stats = (hp + attack + defense + special_attack + special_defense
+ speed) )

Here I took some advice from week 2 lab and used pivot_longer to essentially add the type_1 and type_2 values. This results in some of the pokemon being listed twice but that’s ok for my purposes as I’m most interested in the relationship between typing (type) and overall strength (total_stats).

pokemoncombinedtypes <- pokemonwtotal |> 
  pivot_longer(
    cols = c(type_1, type_2),
    names_to = "primary/secondary",
    values_to = "type") |> 
  filter(!is.na(type))

Next I tried a selection of graph types but settled on the boxplot which looks the neatest in my opinion (Especially since I wanted to display a comparison of the general strength of each type of pokemon someone would encounter in the wild). I also added colour coding, labels, and manually added a scale I thought would be most helpful (inputting the custom scale was a surprise for me and took longer than expected as I thought it was something I could add in theme(), but ggplot2 documentation was really helpful: https://ggplot2-book.org/)

ggplot(pokemoncombinedtypes, aes(y = type, x = total_stats, col = type)) + 
  geom_boxplot() +
  scale_x_continuous(breaks = c(200, 300, 400, 500, 600, 700)) +
  theme_bw() + 
  labs(x = "Total Stat Points", y = "Type", title = "The Strength of Different Pokemon Types") + 
  theme(plot.title = element_text(face = "bold", hjust= 0.5, size = 16), 
        axis.title.y = element_text(face = "bold", size = 12), 
        axis.title.x = element_text(face = "bold", size = 12), 
        legend.position = "none")

Next I used dplyr to pull out the 6 strongest pokemon of each type (the most you can have in a party).

top6bytype <- pokemoncombinedtypes |> 
  group_by(type) |> 
  slice_max(order_by = total_stats, n = 6, with_ties = FALSE)

Then I created a data frame for party stats, summing the stats of all 6 pokemon of each type to get the total party strength. (This step was more challenging than I thought it would be as I had sep = “,” instead of collapse = “,” and couldn’t work out where I went wrong for a while)

party_stats <- top6bytype |>
  group_by(type) |>
  summarise(party_total_stats = sum(total_stats, na.rm = TRUE),
    Party_Members = paste(pokemon, collapse = ", ")) |>
  arrange(desc(party_total_stats))

Finally, I took the party stats data frame and converted it into a table with gt and played around with the table style, especially different colours, before settling with an easier to read alternating grey and the default white scheme

party_stats |> 
  gt(auto_align = FALSE) |> 
  tab_header(
    title = "Best Parties Attainable for Each Type",
    subtitle = "(The Ultimate Guide for Gym Leaders)"
  ) |>
  tab_style(
    style = cell_fill(color = "grey90"),
    locations = cells_body(
      rows = seq(1, nrow(party_stats), 2)
    )
  ) 
Best Parties Attainable for Each Type
(The Ultimate Guide for Gym Leaders)
type party_total_stats Party_Members
dragon 4080 rayquaza, dialga, palkia, giratina-altered, reshiram, zekrom
flying 3920 lugia, ho-oh, rayquaza, yveltal, dragonite, salamence
psychic 3920 mewtwo, lugia, solgaleo, lunala, mew, celebi
normal 3770 arceus, slaking, regigigas, meloetta-aria, silvally, snorlax
steel 3760 dialga, solgaleo, metagross, jirachi, heatran, genesect
fire 3740 ho-oh, reshiram, heatran, victini, volcanion, moltres
water 3710 palkia, kyogre, manaphy, volcanion, suicune, keldeo-ordinary
ghost 3615 giratina-altered, lunala, hoopa, marshadow, decidueye, dusknoir
fairy 3590 xerneas, diancie, magearna, tapu-koko, tapu-lele, tapu-bulu
dark 3580 yveltal, tyranitar, darkrai, hydreigon, guzzlord, greninja
electric 3560 zekrom, zapdos, raikou, thundurus-incarnate, tapu-koko, xurkitree
ground 3540 groudon, garchomp, landorus-incarnate, zygarde, swampert, rhyperior
fighting 3520 kommo-o, marshadow, cobalion, terrakion, virizion, keldeo-ordinary
rock 3497 tyranitar, diancie, regirock, terrakion, nihilego, archeops
grass 3455 celebi, shaymin-land, virizion, tapu-bulu, kartana, tangrowth
ice 3420 kyurem, articuno, regice, lapras, vanilluxe, walrein
bug 3335 genesect, buzzwole, pheromosa, volcarona, golisopod, yanmega
poison 3165 nihilego, crobat, venusaur, tentacruel, roserade, nidoqueen