Skip to content

Instantly share code, notes, and snippets.

@jtrecenti
Created September 19, 2020 20:51
Show Gist options
  • Save jtrecenti/d896765d56a886ee2bb77f265def79d9 to your computer and use it in GitHub Desktop.
Save jtrecenti/d896765d56a886ee2bb77f265def79d9 to your computer and use it in GitHub Desktop.
#' Author: Julio Trecenti
#' Subject: Distâncias das capitais
library(tidyverse)
library(leaflet)
library(plotly)
# Import -----------------------------------------------------------------------
## Download a partir do site
r_capitals <- httr::GET(
"https://lab.lmnixon.org/4th/worldcapitals.html",
httr::user_agent("Mozilla/5.0 (X11; Linux x86_64)")
)
## Parse do resultado do site
da_countries_raw <- r_capitals %>%
xml2::read_html() %>%
xml2::xml_find_first("//table") %>%
rvest::html_table(header = TRUE) %>%
tibble::as_tibble() %>%
janitor::clean_names()
# Tidy -------------------------------------------------------------------------
da_countries_tidy <- da_countries_raw %>%
filter(country != "") %>%
# transforma (N,S) (E,W) em (1,-1), (1,-1)
mutate(
lat_num = str_detect(latitude, "N") * 2 - 1,
lng_num = str_detect(longitude, "E") * 2 - 1
) %>%
# transforma em numérico
mutate(
across(c(latitude, longitude), parse_number),
lat = latitude * lat_num,
lng = longitude * lng_num
) %>%
# arruma Israel
mutate(
lat = if_else(country == "Israel", 31.7683, lat),
lng = if_else(country == "Israel", 35.2137, lng)
) %>%
select(country, capital, lat, lng)
# Transform --------------------------------------------------------------------
da_countries <- da_countries_tidy %>%
# cria pontos com base em lat lng e sf::st_point()
# sf::st_sfc() serve para transformar a lista num objeto POINT do {sf}
# crs = 4326 serve para o {sf} saber que são coordenadas no planeta Terra.
mutate(pt = sf::st_sfc(
map2(lng, lat, ~sf::st_point(c(.x, .y, 1))),
crs = 4326
)) %>%
mutate(
across(c(lat, lng), list(br = ~.x[country == "Brazil"])),
pt_br = sf::st_sfc(
list(sf::st_point(c(lng_br[1], lat_br[1], 1))),
crs = 4326
)
) %>%
mutate(
dist_br = sf::st_distance(pt, pt_br, by_element = TRUE),
dist_br = as.numeric(dist_br / 1000)
) %>%
# ordena a base pelas distâncias
arrange(dist_br)
da_lines_sf <- da_countries %>%
mutate(geometry = sf::st_sfc(
purrr::map2(pt, pt_br, ~sf::st_linestring(c(.x, .y), dim = "XYZ"))
)) %>%
mutate(
geometry = sf::st_line_sample(geometry, n = 30),
geometry = sf::st_cast(geometry, "LINESTRING")
) %>%
select(-pt, -pt_br) %>%
arrange(desc(dist_br)) %>%
head(10) %>%
sf::st_as_sf()
# Visualize --------------------------------------------------------------------
## Tabelas
tab_perto <- da_countries %>%
arrange(dist_br) %>%
filter(country != "Brazil") %>%
select(country, capital, dist_br) %>%
head(10)
tab_longe <- da_countries %>%
arrange(-dist_br) %>%
filter(country != "Brazil") %>%
select(country, capital, dist_br) %>%
head(10)
## Grafico com {leaflet}
make_label <- function(pais, capital) {
txt <- stringr::str_glue("<b>País</b>: {pais}<br/><b>Capital</b>: {capital}")
htmltools::HTML(txt)
}
p_leaflet <- da_countries %>%
mutate(lab = map2(country, capital, make_label)) %>%
leaflet() %>%
addTiles() %>%
addMarkers(
clusterOptions = markerClusterOptions(),
lat = ~lat, lng = ~lng, popup = ~lab
)
library(plotly)
# mapa mundi
world <- sf::st_as_sf(maps::map("world", plot = FALSE, fill = TRUE)) %>%
sf::st_simplify(dTolerance = 0.1) %>%
filter(!sf::st_is_empty(geom)) %>%
mutate(geom = sf::st_cast(geom, "MULTIPOLYGON"))
# funções de transformação de coordenadas
deg2rad <- function(degree) degree * pi / 180
coord_x <- function(x, y) 1.001 * cos(deg2rad(x)) * cos(deg2rad(y))
coord_y <- function(x, y) 1.001 * sin(deg2rad(x)) * cos(deg2rad(y))
coord_z <- function(y) 1.001 * sin(deg2rad(y))
label_plotly <- function(pais, capital, dist) {
stringr::str_glue(
"<b>País</b>: {pais}<br>",
"<b>Capital</b>: {capital}<br>",
"<b>Distância</b>: {round(dist, 1)}km"
)
}
p_plotly <- plot_ly(height = 1000) %>%
# adiciona o mapa mundi
add_sf(
data = world,
x = ~coord_x(x, y),
y = ~coord_y(x, y),
z = ~coord_z(y),
color = I("gray80"),
size = I(2),
hoverinfo = "none"
) %>%
# adiciona as linhas
add_sf(
data = da_lines_sf,
name = "linhas",
x = ~coord_x(x, y),
y = ~coord_y(x, y),
z = ~coord_z(y),
color = ~dist_br,
size = I(3),
text = ~label_plotly(country, capital, dist_br),
hoverinfo = "text"
) %>%
layout(showlegend = FALSE)
# Model ------------------------------------------------------------------------
## Não tem modelagem :)
# Export -----------------------------------------------------------------------
htmlwidgets::saveWidget(p_leaflet, "~/Documents/drafts/data/p_leaflet_world.html")
htmlwidgets::saveWidget(p_plotly, "~/Documents/drafts/data/p_plotly_world.html")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment