Caio Lente

Globo interativo em R

· Caio Lente

Eu sou viciado em visualizações geográficas; eu acho que ela realmente colocam os dados em perspectiva, como se cada ponto tivesse seu lugar. Neste tutorial vou te ensinar a criar um globo 3D interativo bastante interessante com o pacote threejs.

Introdução

Nosso objetivo é visualizar o comércio do Japão com arcos em uma animação tridimensional da Terra. A base de dados que utilizaremos (Japan Trade Statistics, por Tadashi Nagao) é um ótimo exemplo do que encontramos no dia-a-dia: os dados têm informação apenas sobre os países (seus nomes registrados de forma desordenada) e têm não tem absolutamente nenhum dado sobre suas coordenadas.

Criaremos a visualização em 3 passos: pegar as coordenadas da capital de cada país, converter os nomes dos países para um formado padrão e criar o globo em si.

Pegando as coordenadas

Nossa primeira tarefa é importar os dados.

Eu carreguei os dados com informação do comércio japonês, carreguei a tabela com a relação país/código e então juntei as duas em um data frame. Eu também converti os nomes das colunas para caixa baixa e agrupei a tabela por país (somando os valores de todo o comércio com cada país). Nada disso é mostrado aqui por ser muito pouco geral, mas este foi o resultado:

country_name country value
Afghanistan 130 8764947
Albania 229 1473130
Algeria 503 59532804
American_Oceania 622 4914
American_Samoa 621 276510
Andorra 212 29382

Depois desse setup inicial, podemos seguir em frente e pegar as coordenadas da capital de cada país com o pacote maps (vamos usar as coordenadas das capitais como os “pontos de aterrissagem” dos arcos no globo 3D). Aqui vou carregar a tabela world.cities e selecionar os nomes dos países, suas capitais e suas coordenadas.

# Pegar as coordenadas de cada capital
capitals <- world.cities %>%
  filter(capital == 1) %>%
  transmute(
    country_name = country.etc,
    lat = lat,
    long = long
  ) %>%
  rbind(c("Hong Kong", 22.39, 114.1))

Obs.: Não nos deixemos levar pela geopolítica, mas eu adicionei Hong Kong manualmente porque aparentemente ela é/não é parte da China, então ela não está na tabela world.cities

Essa é a cara da tabela capitals:

country_name lat long
Jordan 31.95 35.93
United Arab Emirates 24.48 54.37
Nigeria 9.18 7.17
Ghana 5.56 -0.2
Pitcairn -25.05 -130.1
Ethiopia 9.03 38.74

Convertendo os nomes dos países

Preste atenção em como “American Samoa” e “United Arab Emirates” estão escritos nas duas tabelas acima (esse é o principal motivo pelo qual eu as incluí). Eles não estão formatados da mesma maneira.

Eu vou te poupar dos detalhes, mas esta é a parte mais difícil de trabalhar com dados geográficos: os nomes são um saco. As duas tabelas com as quais temos que trabalhar têm os nomes formatados de maneiras muito diferentes, então temos que padronizá-los.

Vamos fazer isso com o pacote countrycodes, mais especificamente com a base countrycode_data. Ela têm uma coluna com comandos regex que conseguem encontrar o nome de cada país quase independentemente da forma que ele estiver escrito. Primeiramente eu faço uma pequena limpeza em trades\$country_name, mas depois é simples assim:

# Pegar o regex de cada país
regex <- countrycode::countrycode_data$country.name.en.regex
# Pegar a correspondência entre os países de 'totals' e
# 'capitals'
trades_capitals <- as_tibble(cbind(
  regex,
  trades_countries = match_country(regex, trades$country_name),
  capitals_countries = match_country(regex, capitals$country_name)
))

No código acima estou omitindo a função match_country, que simplesmente associa cada entrada em regex com uma entrada do segundo argumento, mas o código em si é bem simples! E agora temos a tabela que conecta os nomes em trades com os nomes em capitals, que pode ser usada para juntas as duas em uma nova tabela chamada geo_trades.

Criando o globo

Para criar os arcos no globo precisamos de uma tabela com um formato bastante especial. Ela precisa conter 4 colunas: origin_lat, origin_long, dest_lat, e dest_long que serão os pontos iniciais e finais para cada arco no globo.

Eu vou usar geo_trades para criar uma nova tabela chamada arcs (nossa tabela também terá o valor da comércio entre as duas pontas, mas vamos excluir essa coluna quando passarmos a tabela para a função que gerará o globo). É assim que eu criei arcs:

# Criar origem e destino dos arcos (origem é sempre Tóquio)
arcs <- geo_trades %>%
  cbind(
    origin_lat = 35.68,
    origin_long = 139.69
  ) %>%
  select(-country_name) %>%
  transmute(
    origin_lat = origin_lat,
    origin_long = origin_long,
    dest_lat = lat,
    dest_long = long,
    value = value
  )

E agora o grand finale: essa é a função que usamos para gerar o globo 😁 Se você olhar com cuidado para a imagem abaixo, é possível ver que a grossura de cada linha representa o volume monetário total das trocas comerciais entre o Japão e cada país.

# Pegar a imagem do globo
earth <- system.file("images/world.jpg",  package = "threejs")
# Criar globo
globejs(
  img = earth, lat = arcs$dest_lat, long = arcs$dest_long,
  arcs = arcs[, 1:4], arcsOpacity = 0.6, arcsHeight = 0.8,
  arcsLwd = arcs$value, arcsColor = "green", atmosphere = TRUE,
  height = 800, width = 800, bg = "white", value = 4
)

E se você quiser interagir com o globo, por favor vá para o meu Kaggle kernel onde o HTML funciona melhor.

#r #viz #ds

Responda a este post por email ↪