Matriz Mágica
P>Inicialmente estava a pensar chamar a este post “Voltar à Base”, uma vez que estou a sair do arrumado e a entrar no mundo das matrizes, mas não há realmente nada de básico nisto. Vamos percorrê-lo passo a passo.
P>Primeiro, vamos pegar na nossa mesa e fazer dela uma matriz. Não podemos simplesmente fazer as.matrix()
directamente, pois fará da coluna de Ataque a primeira coluna, enquanto nós queremos que isso sejam os nomes das rochas, por isso vamos fazê-lo em dois passos.
m <- as.matrix(type_comparisons)rownames(m) <- type_comparisons$Attacking
Next, porque só nos interessa se a entrada é 2 ou não, vamos alterar cada entrada que é 2 para ser 1 e cada entrada que não é 0 (a 1L *
faz com que seja 1 ou 0 em vez de VERDADEIRO ou FALSO).
super_effective_m <- (m == 2) * 1L
super_effective_m
## Normal Fire Water Electric Grass Ice Fighting Poison Ground Flying## Normal 0 0 0 0 0 0 0 0 0 0## Fire 0 0 0 0 1 1 0 0 0 0## Water 0 1 0 0 0 0 0 0 1 0## Electric 0 0 1 0 0 0 0 0 0 1## Grass 0 0 1 0 0 0 0 0 1 0## Ice 0 0 0 0 1 0 0 0 1 1## Fighting 1 0 0 0 0 1 0 0 0 0## Poison 0 0 0 0 1 0 0 0 0 0## Ground 0 1 0 1 0 0 0 1 0 0## Flying 0 0 0 0 1 0 1 0 0 0## Psychic 0 0 0 0 0 0 1 1 0 0## Bug 0 0 0 0 1 0 0 0 0 0## Rock 0 1 0 0 0 1 0 0 0 1## Ghost 0 0 0 0 0 0 0 0 0 0## Dragon 0 0 0 0 0 0 0 0 0 0## Dark 0 0 0 0 0 0 0 0 0 0## Steel 0 0 0 0 0 1 0 0 0 0## Fairy 0 0 0 0 0 0 1 0 0 0## Psychic Bug Rock Ghost Dragon Dark Steel Fairy## Normal 0 0 0 0 0 0 0 0## Fire 0 1 0 0 0 0 1 0## Water 0 0 1 0 0 0 0 0## Electric 0 0 0 0 0 0 0 0## Grass 0 0 1 0 0 0 0 0## Ice 0 0 0 0 1 0 0 0## Fighting 0 0 1 0 0 1 1 0## Poison 0 0 0 0 0 0 0 1## Ground 0 0 1 0 0 0 1 0## Flying 0 1 0 0 0 0 0 0## Psychic 0 0 0 0 0 0 0 0## Bug 1 0 0 0 0 1 0 0## Rock 0 1 0 0 0 0 0 0## Ghost 1 0 0 1 0 0 0 0## Dragon 0 0 0 0 1 0 0 0## Dark 1 0 0 1 0 0 0 0## Steel 0 0 1 0 0 0 0 1## Fairy 0 0 0 0 1 1 0 0
O all_combinations
matriz que criámos anteriormente é essencialmente um conjunto de índices para a matriz super_effective_m
. Por exemplo, a coluna 1 de all_combinations
são os números de 1 a 6, o que significa que queremos obter as linhas 1 a 6 de super_effective_m
. Lembre-se, cada linha de super_effective_m
é um tipo de ataque na nossa equipa, e cada coluna é um tipo de defesa. Queremos então obter a soma de cada coluna e saber quantas colunas têm uma soma de mais de 0, o que significa que pelo menos um dos nossos tipos atacantes foi super eficaz contra ele. Vamos fazer uma função, super_effective_nb
:
super_effective_nb <- function(indices) { sum(colSums(super_effective_m) > 0)}
Agora podemos usar apply()
para obter um vector, para todas as equipas de 18k+, de quantos tipos são super eficazes contra ele. Se não estiver familiarizado com apply()
, o primeiro argumento é a que estamos a aplicar a nossa função, o segundo é se deve aplicar-se às linhas ou colunas (escolhemos 2 para coluna, uma vez que cada coluna é a equipa), e o terceiro é a função.
super_effective_results <- apply(all_combinations, 2, super_effective_nb)
Quais são as combinações que são super eficazes contra o número máximo de tipos possíveis?
which(super_effective_results == max(super_effective_results))
## 14323 14325 15610 15612 16454 16459 16852 16854 16989 16994
Vemos que existem 10 combinações possíveis de seis tipos. Vejamo-los obtendo essas colunas de all_combinations
.
## ## 4 4 5 5 5 5 6 6 6 6## 6 6 6 6 8 8 7 7 7 7## 7 7 7 7 9 9 8 8 9 9## 9 9 9 9 13 13 9 9 10 10## 10 10 10 10 14 16 10 10 14 16## 14 16 14 16 18 18 14 16 17 17
Temos agora uma matriz, best_combo
, onde cada coluna é uma equipa. Por exemplo, vemos uma equipa de tipos 4, 6, 7, 9, 10, e 14 cobrir o número máximo de tipos defensores. Mas o que é o tipo 4? Para responder a isso, tomamos os nomes das linhas de super_effective_m
e indexamo-los por best_combos
.
rownames(super_effective_m)
## "Electric" "Ice" "Fighting" "Ground" "Flying" "Ghost" ## "Electric" "Ice" "Fighting" "Ground" "Flying" "Dark" ## "Grass" "Ice" "Fighting" "Ground" "Flying" "Ghost" ## "Grass" "Ice" "Fighting" "Ground" "Flying" "Dark" ## "Grass" "Poison" "Ground" "Rock" "Ghost" "Fairy" ## "Grass" "Poison" "Ground" "Rock" "Dark" "Fairy" ## "Ice" "Fighting" "Poison" "Ground" "Flying" "Ghost" ## "Ice" "Fighting" "Poison" "Ground" "Flying" "Dark" ## "Ice" "Fighting" "Ground" "Flying" "Ghost" "Steel" ## "Ice" "Fighting" "Ground" "Flying" "Dark" "Steel"
Isto dá-nos um vector de caracteres. Está em ordem, por isso sabemos que os seis primeiros são a equipa 1, os seis segundos a equipa 2, etc., mas não é muito bem apresentado. Podemos usar matrix
para transformar isto numa matriz, especificando que queremos 6 filas.
strongest_teams <- matrix(rownames(super_effective_m), nrow = 6)
strongest_teams
## ## "Electric" "Electric" "Grass" "Grass" "Grass" "Grass" "Ice" ## "Ice" "Ice" "Ice" "Ice" "Poison" "Poison" "Fighting"## "Fighting" "Fighting" "Fighting" "Fighting" "Ground" "Ground" "Poison" ## "Ground" "Ground" "Ground" "Ground" "Rock" "Rock" "Ground" ## "Flying" "Flying" "Flying" "Flying" "Ghost" "Dark" "Flying" ## "Ghost" "Dark" "Ghost" "Dark" "Fairy" "Fairy" "Ghost" ## ## "Ice" "Ice" "Ice" ## "Fighting" "Fighting" "Fighting"## "Poison" "Ground" "Ground" ## "Ground" "Flying" "Flying" ## "Flying" "Ghost" "Dark" ## "Dark" "Steel" "Steel"
Para o nosso passo final, vamos de facto fazer disto um tibble, para que eu possa ver quais os tipos que aparecem com mais frequência nas diferentes possibilidades da equipa.
strongest_teams %>% as_tibble() %>% gather(team, type) %>% count(type, sort = TRUE) %>% knitr::kable()
type | n |
---|---|
Ground | 10 |
8 | |
Flying | |
Ice | |
5 | |
Ghost | 5 |
Grass | 4 |
Poison | 4 |
Electric | 2 |
Fairy | 2 |
Rock | 2 |
Steel | 2 |
Vemos que todas as 10 equipas precisam de um tipo de solo, onde 8 têm um tipo de Combate, Voar, ou Gelo. Por outro lado, Elétrico, Fada, Pedra e Aço são usados apenas por duas equipas.