Análise de Magic the gathering com R - Prof. Thiago Marques

Carregando bibliotecas

Dados de cards brancos, pretos, artefatos e terrenos

dados_cartas = scry_cards("c:w or c:b or t:artifact or t:land")

filtrando as cartas desejadas

dados_cartas_filtradas = dados_cartas %>%  filter(name %in% c(#brancas
                                                    "Orah, Skyclave Hierophant",
                                                    
                                                    "Bishop of Binding",
                                                    "Soul Warden",
                                                    "Speaker of the Heavens",
                                                    "High Priest of Penance",
                                                    "Ayli, Eternal Pilgrim",
                                                    "Cruel Celebrant",
                                                    "Cleric of Life's Bond",
                                                    "Battlefield Medic",
                                                    "Suture Priest",
                                                    "Bygone Bishop",
                                                    "Edgewalker",
                                                    "Sin Collector",
                                                    "Hammers of Moradin",
                                                    "Priest of the Blessed Graf",
                                                    "Righteous Valkyrie",
                                                    "Soulbinders",
                                                    "Heliod, God of the Sun",
                                                    "Minthara, Merciless Soul",
                                                    "Doubtless One",
                                                    "Glorious Protector",
                                                    "Firja, Judge of Valor",
                                                    "Shieldmage Elder",
                                                    "Astarion, the Decadent",
                                                    "Sun Titan",
                                                    "Fight as One",
                                                    "Pride of Conquerors",
                                                    "Dire Tactics",
                                                    "Akroma's Blessing",
                                                    "Mortify",
                                                    "Closing Statement",
                                                    "Austere Command",
                                                    "Akroma's Vengeance",
                                                    "Cleric Class",
                                                    "Rally the Ranks",
                                                    "Etchings of the Chosen",
                                                    "Ghostly Prison",
                                                    "Soul Link",
                                                    "Sigil of the New Dawn",
                                                    "Custodi Soulbinders",
                                                    #pretas
                                        "Doomed Necromancer",
                                               "Boneknitter",
                                               "Rotlung Reanimator",
                                               "Marauding Blight-Priest",
                                               "Taborax, Hope's Demise",
                                               "Vengeful Reaper",
                                               "Vile Deacon",
                                               "Jarl of the Forsaken",
                                               "Shadowheart, Dark Justiciar",
                                               "Gangrenous Goliath",
                                               "Pontiff of Blight",
                                               "Misery Charm",
                                               "Cut of the Profits",
                                               "Profane Prayers",
                                               "Patriarch's Bidding",
                                               "Gruesome Menagerie",
                                               "Greed",
                                               "Cabal Archon",
                                               #artefatos
                                               "Zuran Orb",
                                               "Charcoal Diamond",
                                               "Marble Diamond",
                                               "Pyre of Heroes",
                                               "Talisman of Hierarchy",
                                               "Neurok Stealthsuit",
                                               "Herald's Horn",
                                               "Relic Vial",
                                               "Bontu's Monument",
                                               "Gangrenous Goliath",
                                               "Orzhov Signet",
                                               "Angel's Feather",
                                               #terrenos
                                               "Base Camp",
                                               "Vault of the Archangel",
                                               "Path of Ancestry",
                                               "Silverquill Campus",
                                               "Desert of the True",
                                               "Radiant Fountain",
                                               "Secluded Courtyard",
                                               "Swamp",
                                               "Plains",
                                               "Great Hall of Starnheim",
                                               "Starlit Sanctum",
                                               "Temple of Silence",
                                               "Evolving Wilds",
                                               "Command Tower")|
                                        str_detect(name,"Chaplain of Alms") | 
                                        str_detect(name,"Selfless Glyphweaver")|
                                        str_detect(name,"Arguel's")|
                                        str_detect(name,"Revival // Revenge")
                                                )

Filtrando as variáveis desejadas

dados_cartas_filtradas_var_selec = dados_cartas_filtradas %>% select( id, name, color_identity,
                                            mana_cost,
                                            oracle_text,
                                            power,
                                            toughness,
                                            type_line,keywords,scryfall_uri,
                                            collector_number, prices, rarity,cmc)

Totalizando quantidade de cartas

dim(dados_cartas_filtradas)[1]
## [1] 86

Populando os swamps e plains para formar 100 cartas

dados_consolidado_deck_clerigo = dados_cartas_filtradas %>% add_row(dados_cartas_filtradas[79,]) %>% 
add_row(dados_cartas_filtradas[79,]) %>% 
add_row(dados_cartas_filtradas[79,]) %>% 
add_row(dados_cartas_filtradas[79,]) %>% 
add_row(dados_cartas_filtradas[79,]) %>% 
add_row(dados_cartas_filtradas[54,]) %>% 
add_row(dados_cartas_filtradas[54,]) %>% 
add_row(dados_cartas_filtradas[54,]) %>% 
add_row(dados_cartas_filtradas[54,]) %>% 
add_row(dados_cartas_filtradas[54,]) %>% 
add_row(dados_cartas_filtradas[54,]) %>% 
add_row(dados_cartas_filtradas[54,]) %>% 
add_row(dados_cartas_filtradas[54,]) %>% 
add_row(dados_cartas_filtradas[54,]) 

Contabilizando os tipos de mana usados por cada carta

table(dados_consolidado_deck_clerigo$mana_cost)
## 
##                                             {0}                  {1}{B} 
##                      28                       1                       1 
##                  {1}{W}               {1}{W}{B}                     {2} 
##                       4                       5                       7 
##                  {2}{B}               {2}{B}{B}                  {2}{W} 
##                       5                       2                       6 
##               {2}{W}{B}            {2}{W}{B}{B}               {2}{W}{W} 
##                       2                       1                       1 
##                     {3}                  {3}{B}               {3}{B}{B} 
##                       3                       4                       3 
##                  {3}{W}               {3}{W}{B}               {4}{B}{B} 
##                       5                       1                       1 
##               {4}{W}{B}               {4}{W}{W}                  {5}{W} 
##                       1                       3                       1 
##                     {B} {W/B}{W/B} // {4}{W}{B}                     {W} 
##                       1                       1                       4 
##                  {W}{B}               {X}{B}{B} 
##                       5                       1

Contabilizando o total de manas das cartas

table(dados_consolidado_deck_clerigo$cmc)
## 
##  0  1  2  3  4  5  6  8 
## 29  6 19 20 14  5  6  1

Filtrando só as cartas de uma mana branca

dados_consolidado_deck_clerigo_brancos = dados_consolidado_deck_clerigo %>% filter(mana_cost=="{W}")

Filtrando as cartas de 3 manas

dados_consolidado_deck_clerigo %>% filter(cmc == 3)
## # A tibble: 20 x 74
##    id     name   set   lang  colors color_identity mana_cost   cmc oracle_text  
##    <chr>  <chr>  <chr> <chr> <list> <list>         <chr>     <dbl> <chr>        
##  1 be43f~ Akrom~ vma   en    <chr ~ <chr [1]>      {2}{W}        3 "Choose a co~
##  2 171a9~ Bontu~ dmc   en    <NULL> <NULL>         {3}           3 "Black creat~
##  3 cf879~ Bygon~ clb   en    <chr ~ <chr [1]>      {2}{W}        3 "Flying\nWhe~
##  4 4bdf6~ Cabal~ ons   en    <chr ~ <chr [1]>      {2}{B}        3 "{B}, Sacrif~
##  5 2d322~ Doome~ afc   en    <chr ~ <chr [1]>      {2}{B}        3 "{B}, {T}, S~
##  6 c8b47~ Edgew~ scg   en    <chr ~ <chr [2]>      {1}{W}{B}     3 "Cleric spel~
##  7 7036a~ Etchi~ mh1   en    <chr ~ <chr [2]>      {1}{W}{B}     3 "As Etchings~
##  8 8169d~ Ghost~ voc   en    <chr ~ <chr [1]>      {2}{W}        3 "Creatures c~
##  9 e7429~ Hamme~ clb   en    <chr ~ <chr [1]>      {2}{W}        3 "Myriad (Whe~
## 10 e7ac5~ Heral~ 40k   en    <NULL> <NULL>         {3}           3 "As Herald's~
## 11 730dd~ Marau~ znr   en    <chr ~ <chr [1]>      {2}{B}        3 "Whenever yo~
## 12 02040~ Morti~ 40k   en    <chr ~ <chr [2]>      {1}{W}{B}     3 "Destroy tar~
## 13 5b394~ Pries~ voc   en    <chr ~ <chr [1]>      {2}{W}        3 "At the begi~
## 14 4b9ae~ Relic~ znr   en    <NULL> <NULL>         {3}           3 "{2}, {T}, S~
## 15 02fb5~ Right~ khm   en    <chr ~ <chr [1]>      {2}{W}        3 "Flying\nWhe~
## 16 87b29~ Rotlu~ ons   en    <chr ~ <chr [1]>      {2}{B}        3 "Whenever Ro~
## 17 8982f~ Selfl~ stx   en    <NULL> <chr [2]>      <NA>          3  <NA>        
## 18 8cad9~ Sin C~ mm3   en    <chr ~ <chr [2]>      {1}{W}{B}     3 "When Sin Co~
## 19 425e0~ Soul ~ apc   en    <chr ~ <chr [2]>      {1}{W}{B}     3 "Enchant cre~
## 20 331bf~ Tabor~ znr   en    <chr ~ <chr [1]>      {2}{B}        3 "Flying\nTab~
## # ... with 65 more variables: type_line <chr>, edhrec_rank <int>,
## #   keywords <list>, layout <chr>, legalities <list>, oversized <lgl>,
## #   reserved <lgl>, oracle_id <chr>, arena_id <int>, mtgo_id <int>,
## #   multiverse_ids <list>, tcgplayer_id <int>, cardmarket_id <int>, uri <chr>,
## #   scryfall_uri <chr>, rulings_uri <chr>, prints_search_uri <chr>,
## #   artist <chr>, artist_ids <list>, booster <lgl>, border_color <chr>,
## #   card_back_id <chr>, collector_number <chr>, digital <lgl>, foil <lgl>, ...

Consertando as manas dos que estão sem mana

dados_consolidado_deck_clerigo_NA = dados_consolidado_deck_clerigo %>% filter(is.na(mana_cost)==T)

Imputando o correto nas cartas: Arguel’s Blood Fast, Selfless Glyphweaver e Chaplain of Alms

dados_consolidado_deck_clerigo$mana_cost[dados_consolidado_deck_clerigo$id=="c4ac7570-e74e-4081-ac53-cf41e695b7eb"] = "{1}{B}"

dados_consolidado_deck_clerigo$mana_cost[dados_consolidado_deck_clerigo$id=="8982ff88-8595-4363-8cde-6e87fb57a2d8"] = "{2}{W}"

dados_consolidado_deck_clerigo$mana_cost[dados_consolidado_deck_clerigo$id=="20e94e17-2e4c-41cd-8cc5-39ab41037287"] = "{W}"

Transformando a var colors para contar

dados_consolidado_deck_clerigo = dados_consolidado_deck_clerigo %>% mutate(
  colors_novo = case_when(
    colors == "W" ~ "Branca",
    colors == "B" ~ "Preta",
    colors == c("B","W") ~ "Branca e Preta",
    colors == "NULL" & type_line == "Artifact" | type_line == "Artifact — Equipment" | type_line == "Legendary Artifact" ~ "Incolor/Artefatos",
    colors == "NULL" & type_line == "Basic Land — Plains" | type_line == "Basic Land — Swamp" |  type_line == "Land" | type_line == "Land — Desert" ~ "Terrenos" 
  )
)

dados_consolidado_deck_clerigo = dados_consolidado_deck_clerigo %>% mutate(colors_novo = replace_na(colors_novo,"Branca e Preta"))

Gráfico de pizza da quantidade de cores do deck

df_pizza_tab=table(dados_consolidado_deck_clerigo$colors_novo)
df_pizza <<- data.frame(df_pizza_tab)
df_pizza %>% kbl %>% kable_material_dark(full_width = F)
Var1 Freq
Branca 24
Branca e Preta 19
Incolor/Artefatos 11
Preta 18
Terrenos 28
colors <- c("#FFFFFF", "#ffd700", "#c0c0c0","#000000","#f5f5dc")

grafico_pizza_iterativo = plot_ly(df_pizza, 
                            labels = ~Var1, 
                            values = ~Freq, 
                            type = 'pie',
                            marker = list(colors = colors,
                            line = list(color = '#FFFFFF', width = 1))
                            )%>%
                            layout(title = 'Frequência relativa das cores do deck (%) '
                                    )

grafico_pizza_iterativo

Filtrando as cartas Brancas

dados_consolidado_deck_clerigo %>% filter(colors_novo == "Branca")
## # A tibble: 24 x 75
##    id      name  set   lang  colors color_identity mana_cost   cmc oracle_text  
##    <chr>   <chr> <chr> <chr> <list> <list>         <chr>     <dbl> <chr>        
##  1 be43fd~ Akro~ vma   en    <chr ~ <chr [1]>      {2}{W}        3 "Choose a co~
##  2 e45b4c~ Akro~ c20   en    <chr ~ <chr [1]>      {4}{W}{W}     6 "Destroy all~
##  3 3d2403~ Aust~ clb   en    <chr ~ <chr [1]>      {4}{W}{W}     6 "Choose two ~
##  4 9c4445~ Batt~ ons   en    <chr ~ <chr [1]>      {1}{W}        2 "{T}: Preven~
##  5 aaadce~ Bish~ rix   en    <chr ~ <chr [1]>      {3}{W}        4 "When Bishop~
##  6 cf879f~ Bygo~ clb   en    <chr ~ <chr [1]>      {2}{W}        3 "Flying\nWhe~
##  7 47ce8b~ Cler~ afr   en    <chr ~ <chr [1]>      {W}           1 "(Gain the n~
##  8 6a0dd7~ Cust~ voc   en    <chr ~ <chr [1]>      {3}{W}        4 "Custodi Sou~
##  9 0dedef~ Doub~ ons   en    <chr ~ <chr [1]>      {3}{W}        4 "Doubtless O~
## 10 5c62ea~ Figh~ iko   en    <chr ~ <chr [1]>      {W}           1 "Choose one ~
## # ... with 14 more rows, and 66 more variables: type_line <chr>,
## #   edhrec_rank <int>, keywords <list>, layout <chr>, legalities <list>,
## #   oversized <lgl>, reserved <lgl>, oracle_id <chr>, arena_id <int>,
## #   mtgo_id <int>, multiverse_ids <list>, tcgplayer_id <int>,
## #   cardmarket_id <int>, uri <chr>, scryfall_uri <chr>, rulings_uri <chr>,
## #   prints_search_uri <chr>, artist <chr>, artist_ids <list>, booster <lgl>,
## #   border_color <chr>, card_back_id <chr>, collector_number <chr>, ...

Imputando as cores corretas nas cartas Selfless Glyphweaver , Arguel’s Blood Fast e Chaplain of Alms

dados_consolidado_deck_clerigo$colors_novo[dados_consolidado_deck_clerigo$id=="8982ff88-8595-4363-8cde-6e87fb57a2d8"] = "Branca"

dados_consolidado_deck_clerigo$colors_novo[dados_consolidado_deck_clerigo$id=="c4ac7570-e74e-4081-ac53-cf41e695b7eb"] = "Preta"

dados_consolidado_deck_clerigo$colors_novo[dados_consolidado_deck_clerigo$id=="20e94e17-2e4c-41cd-8cc5-39ab41037287"] = "Branca"

Análise gráfica das cores do deck

df_pizza_tab=table(dados_consolidado_deck_clerigo$colors_novo)
df_pizza <<- data.frame(df_pizza_tab)
df_pizza %>% kbl %>% kable_material_dark(full_width = F)
Var1 Freq
Branca 26
Branca e Preta 16
Incolor/Artefatos 11
Preta 19
Terrenos 28
colors <- c("#FFFFFF", "#ffd700", "#c0c0c0","#000000","#f5f5dc")

grafico_pizza_iterativo = plot_ly(df_pizza, 
                            labels = ~Var1, 
                            values = ~Freq, 
                            type = 'pie',
                            marker = list(colors = colors,
                            line = list(color = '#FFFFFF', width = 1))
                            )%>%
                            layout(title = 'Frequência relativa das cores do deck (%) '
                                    )

grafico_pizza_iterativo

Gráfico de barras empilhado

grafico_coluna_empilhada=ggplot(dados_consolidado_deck_clerigo,aes(x=cmc,fill=colors_novo)) + 
  geom_bar(position = 'fill',show.legend = FALSE) +
  ggtitle("Número de carta por cor e quantidade de mana")+
  scale_y_continuous(labels=percent) +
  scale_x_continuous(breaks=seq(0,8,by=1))+
  xlab("Quantidade de mana") +
  ylab("Proporção de cartas % (Frequência Relativa)")+
  scale_fill_manual(values = c("#FFFFFF", "#ffd700", "#c0c0c0","#000000","#f5f5dc"))


ggplotly(grafico_coluna_empilhada)

Gráfico de barras empilhado absoluto

grafico_coluna_empilhada=ggplot(dados_consolidado_deck_clerigo,aes(x=cmc,fill=colors_novo)) + 
  geom_bar(position = 'stack',show.legend = FALSE) +
  ggtitle("Número de carta por cor e quantidade de mana")+
  #scale_y_continuous(labels=percent) +
  scale_x_continuous(breaks=seq(0,8,by=1))+
  xlab("Quantidade de mana") +
  ylab("Proporção de cartas % (Frequência Relativa)")+
  scale_fill_manual(values = c("#FFFFFF", "#ffd700", "#c0c0c0","#000000","#f5f5dc"))


ggplotly(grafico_coluna_empilhada)

Transformando a var tipo para contar

dados_consolidado_deck_clerigo = dados_consolidado_deck_clerigo %>% mutate(
  type_line_novo = case_when(
    type_line == "Sorcery" |  type_line == "Sorcery // Sorcery" | type_line == "Instant" ~ "Magia",
    type_line == "Basic Land — Plains" | type_line == "Basic Land — Swamp" |  type_line == "Land" | type_line == "Land — Desert" ~ "Terrenos",
    type_line == "Artifact" | type_line == "Artifact — Equipment" | type_line == "Legendary Artifact" ~ "Incolor/Artefatos",
    type_line == "Enchantment" | type_line == "Enchantment — Aura" | type_line == "Enchantment — Class" | type_line == "Legendary Enchantment // Legendary Land" ~ "Encantamentos",
    str_detect(type_line, pattern = "Creature") ~ "Criatura")
  )

Análise gráfica do deck por tipo

df_pizza_tab=table(dados_consolidado_deck_clerigo$type_line_novo)
df_pizza <<- data.frame(df_pizza_tab)
df_pizza %>% kbl %>% kable_material_dark(full_width = F)
Var1 Freq
Criatura 39
Encantamentos 8
Incolor/Artefatos 11
Magia 14
Terrenos 28
colors <- c("#FFFFFF", "#ffd700", "#c0c0c0","#000000","#f5f5dc")

grafico_pizza_iterativo = plot_ly(df_pizza, 
                            labels = ~Var1, 
                            values = ~Freq, 
                            type = 'pie',
                            marker = list(colors = colors,
                            line = list(color = '#FFFFFF', width = 1))
                            )%>%
                            layout(title = 'Frequência relativa das cores do deck (%) '
                                    )

grafico_pizza_iterativo

Gráfico de barras empilhado absoluto por tipo

grafico_coluna_empilhada=ggplot(dados_consolidado_deck_clerigo,aes(x=cmc,fill=type_line_novo)) + 
  geom_bar(position = 'stack',show.legend = FALSE) +
  ggtitle("Número de carta por cor e quantidade de mana")+
  #scale_y_continuous(labels=percent) +
  scale_x_continuous(breaks=seq(0,8,by=1))+
  xlab("Quantidade de mana") +
  ylab("Proporção de cartas % (Frequência Relativa)")+
  scale_fill_manual(values = c("#FFFFFF", "#ffd700", "#c0c0c0","#000000","#f5f5dc"))


ggplotly(grafico_coluna_empilhada)

Imputando o correto nas cartas doubtlessone

dados_consolidado_deck_clerigo$keywords_teste[dados_consolidado_deck_clerigo$id=="0dedef8a-5527-40dc-9ad9-bcee4cf30a76"] = "Lifelink"
## Warning: Unknown or uninitialised column: `keywords_teste`.

Tratando

dados_consolidado_deck_clerigo = dados_consolidado_deck_clerigo %>% mutate(
  keywords_teste = case_when(
    keywords == "NULL" ~ "Sem habilidade especial", 
    TRUE ~ as.character(keywords)
  )
)

Grafo das cartas por tipo de habilidade

colors <- c(rep("#FFFFFF",50), rep("#ffd700",50), rep("#c0c0c0",50),rep("#000000",40),rep("#f5f5dc",6))

adj_autor_temas=table(dados_consolidado_deck_clerigo$name,dados_consolidado_deck_clerigo$keywords_teste)
net_autores_temas <- graph_from_incidence_matrix(adj_autor_temas)
net2=asNetwork(net_autores_temas)

df2=data.frame(table(dados_consolidado_deck_clerigo$keywords_teste))
df3=data.frame(dados_consolidado_deck_clerigo$name)

net2 %v% "Series" = dados_consolidado_deck_clerigo$name

n<-ggnetwork(net2)

df3=data.frame(table(cbind(dados_consolidado_deck_clerigo$keywords_teste,dados_consolidado_deck_clerigo$name)))

n_merge=merge(n,df3, by.x=names(n)[5],by.y=names(df3)[1])

ggplotly(
  ggplot(n_merge, aes(x = x, y = y, xend = xend, yend = yend)) +
    geom_edges(color = "grey50") +
    geom_nodes(aes(color = vertex.names, size=Freq)) +
    geom_nodetext(aes(color =colors, label = vertex.names),
                  fontface = "bold",size=3) +
    theme_blank()
)