invisible(Sys.setlocale("LC_CTYPE", "pt_BR.UTF-8"))
invisible(Sys.setlocale("LC_ALL","pt_BR.UTF-8"))
options(warn=-1)
suppressMessages(library(knitr, warn.conflicts=FALSE))
suppressMessages(library(kableExtra, warn.conflicts=FALSE))
suppressMessages(library(foreign, warn.conflicts=FALSE))
suppressMessages(library(geobr, warn.conflicts=FALSE))
suppressMessages(library(ggplot2, warn.conflicts=FALSE))
suppressMessages(library(miniCRAN, warn.conflicts=FALSE))
suppressMessages(library(readxl, warn.conflicts=FALSE))
# suppressMessages(library(rgdal, warn.conflicts=FALSE))
suppressMessages(library(rnaturalearth, warn.conflicts=FALSE))
# se nao estiver disponivel para sua versão de R:
# remotes::install_github("ropensci/rnaturalearthhires")
# devtools::install_github("ropensci/rnaturalearthhires")
suppressMessages(library(rnaturalearthhires, warn.conflicts=FALSE))
suppressMessages(library(sf, warn.conflicts=FALSE))
suppressMessages(library(sp, warn.conflicts=FALSE))
suppressMessages(library(dplyr, warn.conflicts=FALSE))
suppressMessages(library(openxlsx, warn.conflicts=FALSE))
suppressMessages(library(KernSmooth, warn.conflicts=FALSE))
suppressMessages(library(foreign, warn.conflicts=FALSE))
source("eiras.viridis.hot.R")
source("eiras.friendlycolor.R")
options(warn=0)
scripts
files
RPubs
|
|
|
Mapas podem modelar a elevação do terreno, como neste link e neste link.
Este vídeo tem um exemplo de construção com raster, usando ggplot, para mostrar a distribuição da chuva ao longo do ano: o código R é exposto à medida que cada comando vai sendo utilizado. Também é possível criar modelos de terrenos, como este mapa da Tanzânia — tem código fonte usando GMT, mas há componentes adicionais que precisam ser encontrados para sua execução. Detalhes em:
Lemenkova, Polina. 2022. Tanzania Craton, Serengeti Plain and Eastern Rift Valley: Mapping of Geospatial Data by Scripting Techniques. Estonian Journal of Earth Sciences 71 (2)..
GMT (Generic Mapping Tools) é uma coleção de ferramentas de linha de comando usada para criar mapas e realizar análises de dados geoespaciais, amplamente utilizado em geociências, geofísica, oceanografia e outras áreas que envolvem a manipulação e visualização de dados geográficos. GMT é um software open-source e pode ser utilizado em Linux, macOS e Windows. Um script básico do GMT geralmente segue esta estrutura:
Por exemplo, costa.gmt:
gera
|
É possível monitorar o regime de ventos, exibindo em tempo real, como neste site — mas não verifiquei se tem código fonte disponível (este exemplo é mencionado em r-bloggers.com mas o link que poderia ensinar como criar os mapas vetoriais está quebrado.
Para quem tem interesse, possíveis formas estão em r-graphics.org ou milospopovic.net/ (eu não tentei implementar estas rotinas).
\[~\]
Uma versão antiga, que fizemos no início da pandemia COVID_cases_UF.mp4, plotava os casos de acordo com a localização dos municípios, o que também é interessante ver.
Observe como foi feita a formatação do eixo das abscissas, exibindo as datas em um formato humanamente mais legível. Os dados continuam sendo atualizados pelo Governo Federal em https://covid.saude.gov.br/. Procurando algo similar sobre Dengue, encontrei o Plano de Dados Abertos do Ministério da Saúde. Encontrei o “Conjunto de dados” (um arquivo csv) onde há uma lista do que está disponível. |
Destacamos alguns momentos da pandemia:
15 de abril de 2020:
27 de maio de 2020:
27 de julho de 2020:
22 de março de 2021:
A sobreposição dos mapas com a localização de aeroportos, rodovias, ferrovias e hidrovias mostra o seguinte:
Aeroportos
Rodovias
Ferrovias
Hidrovias
Há uma grande quantidade de pacotes com funções interrelacionadas
para a manipulação de mapas e sua associação com procedimentos
estatísticos. Os mais integradores são sp
para desenhar objetos de classes
espaciais (Pebesma & Bivand, 2018) e spatstat
(Baddeley, 2021; Kopczewska,
2021). O pacote sp
, que cuida dos mapas (Mas et al., 2019),
trabalhava com dependência de:
rgdal
para ler e gravar objetos vetoriais (OGR), que
foi removido do CRANraster
(GDAL) (Bivand et al., 2017a) para ler e
escrever dadosrgeos
(Bivand & Rundel, 2017) para
operacionalização espacial, removido do CRANmaptools
(Becker & Wilks, 2018) que lidava com
conversões, removido do CRANPBSmapping
(Schnute et al., 2003) para manipular os
objetos espaciais e permitir a conversão para uso em outros pacotes
(ainda existe). Conexões dos pacotes
com base em sp
e spatstat
(baseado em
Kopczewska, 2021).
Existe, ainda, o pacote sf
(Pebesma, 2017), que promete
simplificar, mantendo compatibilidade, as diversas operações de análise
espacial, por exemplo integrando a exibição de resultados com leitura e
gravação dos dados[1]. Algumas de suas operações mais simples são
mostradas adiante.
Conexões entre pacotes
com base em sf
.
demo_miniCRAN.R
.
Estas duas figuras mostram os principais pacotes utilizados em análise espacial.
A análise espacial em R começou com grande profusão e confusão de função. Foi o trabalho de Roger Bivand que integrou pacotes, organizando classes de objetos e permitindo a conversão dos respectivos formatos quando necessário passar dos recursos de um para outro[3].
O objetivo deste texto é auxiliar nos passos iniciais. Neste texto
mostraremos como iniciar com os pacotes sp
e
sf
; instale-os para replicar os exemplos.
Funções:
sf::st_point()
: cria ponto (objeto sfg, de geometria)
com 2 a 4 dimensõessf::st_multipoint()
: cria vários pontos (pode receber
as coordenadas em matriz)sf::st_linestring()
: cria linha a partir das
coordenadassf::st_multilinestring()
: cria objeto com várias
linhassf::st_polygon()
: cria polígono a partir das
coordenadassf::st_multilinestring()
: cria objeto com várias
linhassf::st_sfc()
: cria objeto sfc, contendo uma coleção de
geometriassf::st_sf()
: adiciona atributos a uma geometria
criadasf::st_geometry()
: retorna somente a geometria de um
objeto sfcsf::st_coordinate()
: retorna as coordenadas de um
objeto sfcsf::st_read()
: lê um shapefileDados existem em muitas fontes. Para dados oficiais do Brasil, por
exemplo, existe o pacote geobr
, que contém:
suppressMessages(library(geobr, warn.conflicts=FALSE))
suppressMessages(library(knitr, warn.conflicts=FALSE))
suppressMessages(library(kableExtra, warn.conflicts=FALSE))
dt_br <- geobr::list_geobr()
# dt_br %>%
# knitr::kable("html") %>%
# kableExtra::kable_styling("striped", full_width = FALSE) %>%
# kableExtra::scroll_box(width = "100%", height = "400px")
table_html <- knitr::kable(dt_br, format = "html")
styled_table <- kableExtra::kable_styling(table_html,
bootstrap_options = "striped",
full_width = FALSE)
final_output <- kableExtra::scroll_box(styled_table, width = "100%", height = "400px")
print(final_output)
function | geography | years | source |
---|---|---|---|
read_country
|
Country | 1872, 1900, 1911, 1920, 1933, 1940, 1950, 1960, 1970, 1980, 1991, 2000, 2001, 2010, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 | IBGE |
read_region
|
Region | 2000, 2001, 2010, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 | IBGE |
read_state
|
States | 1872, 1900, 1911, 1920, 1933, 1940, 1950, 1960, 1970, 1980, 1991, 2000, 2001, 2010, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 | IBGE |
read_meso_region
|
Meso region | 2000, 2001, 2010, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 | IBGE |
read_micro_region
|
Micro region | 2000, 2001, 2010, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 | IBGE |
read_intermediate_region
|
Intermediate region | 2017, 2019, 2020 | IBGE |
read_immediate_region
|
Immediate region | 2017, 2019, 2020 | IBGE |
read_municipality
|
Municipality | 1872, 1900, 1911, 1920, 1933, 1940, 1950, 1960, 1970, 1980, 1991, 2000, 2001, 2005, 2007, 2010, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 | IBGE |
read_municipal_seat
|
Municipality seats (sedes municipais) | 1872, 1900, 1911, 1920, 1933, 1940, 1950, 1960, 1970, 1980, 1991, 2010 | IBGE |
read_weighting_area
|
Census weighting area (área de ponderação) | 2010 | IBGE |
read_census_tract
|
Census tract (setor censitário) | 2000, 2010, 2017, 2019, 2020 | IBGE |
read_statistical_grid
|
Statistical Grid of 200 x 200 meters | 2010 | IBGE |
read_metro_area
|
Metropolitan areas | 1970, 2001, 2002, 2003, 2005, 2010, 2013, 2014, 2015, 2016, 2017, 2018 | IBGE |
read_urban_area
|
Urban footprints | 2005, 2015 | IBGE |
read_amazon
|
Brazil’s Legal Amazon | 2012 | MMA |
read_biomes
|
Biomes | 2004, 2019 | IBGE |
read_conservation_units
|
Environmental Conservation Units | 201909 | MMA |
read_disaster_risk_area
|
Disaster risk areas | 2010 | CEMADEN and IBGE |
read_indigenous_land
|
Indigenous lands | 201907, 202103 | FUNAI |
read_semiarid
|
Semi Arid region | 2005, 2017, 2021, 2022 | IBGE |
read_health_facilities
|
Health facilities | 201505, 202303 | CNES, DataSUS |
read_health_region
|
Health regions and macro regions | 1991, 1994, 1997, 2001, 2005, 2013 | DataSUS |
read_neighborhood
|
Neighborhood limits | 2010 | IBGE |
read_schools
|
Schools | 2020, 2023 | INEP |
read_comparable_areas
|
Historically comparable municipalities, aka Áreas mínimas comparáveis (AMCs) | 1872, 1900, 1911, 1920, 1933, 1940, 1950, 1960, 1970, 1980, 1991, 2000, 2010 | IBGE |
read_urban_concentrations
|
Urban concentration areas (concentrações urbanas) | 2015 | IBGE |
read_pop_arrangements
|
Population arrangements (arranjos populacionais) | 2015 | IBGE |
Muitos dos mapas disponíveis usam o modelo geométrico de recursos simples (simple feature, em inglês), um padrão estabelecido pelo Open Geospatial Consortium (OGC), o qual utilizamos com os procedimentos em R que veremos adiante. Pela Web é possível encontrar muitos mapas de diversos locais do mundo pronto para seu uso.
ggplot2::ggplot
: função básica de gráfico do pacote
ggplot2
ggplot2::geom_sf
: exibição de shapefileggplot2::geom_point
: pontos em mapa com longitude e
latitude.ggplot2::aes
: controle de atributos dos elementos de
ggplot()
ggplot2::labs
: rótulos em eixos ou legendasggplot2::ylim
: cortes de segmentos dos mapas em
latitudesggplot2::xlim
: cortes de segmentos dos mapas em
longitudesggplot2::theme_XXX & ggplot2::theme(parameters)
:
para controlar a aparência dos mapas com temas (XXX indica que há vários
a escolher)ggplot2::element_blank
,
ggplot2::element_line
, ggplot2::element_rect
:
usadas com os parâmetros dos temas.Podem ser tomados em três situações[3] quando:
Um dos formatos mais difundidos para análise espacial são mapas distribuídos em simple feature[1]. Este tipo de objeto hierárquico permite que várias formas geográficas sejam armazenadas conjuntamente.
O pacote sf
tem funções para criar e armazenar estas
formas geográficas ou manipular objetos sf
já
existentes.
Além das formas vetoriais (pontos, linhas e polígonos) de expressar localização espacial, há pacotes que dividem a área em pequenas unidades discretas, formando um grid que pode receber cores ou intensidades de preto e branco, conhecido como formato raster. Como este formato preenche áreas com um padrão, é frequentemente sobreposto aos mapas vetoriais.
Usando sf
construiremos, passo-a-passo, um objeto no
formato simple feature. Embora o mapa resultante seja muito
elementar, facilitará o entendimento da estrutura dos mapas que
encontramos prontos para baixar pela Internet.
Os pontos podem ter de 2 a 4 dimensões em suas coordenadas. As duas primeiras coordenadas servem para posicionar o ponto no plano (x,y). A terceira é utilizada para representar altura, em mapas com informação sobre relevo. A quarta pode servir para algum outro parâmetro que se deseje estudar (densidade, temperatura, etc.).
Embora não pareça em nada diferente de um gráfico comum, criar os
pontos com o pacote sf
permitirá, adiante, integrar os
pontos em objetos geográficos. Veja o resultado de demo_ponto2d.R
:
cat("\nPonto, duas coordenadas:\n")
pto <- sf::st_point(c(3,5)) # 2 dimensões (XY)
print(pto)
cat("\nclass:\n")
print(class(pto))
cat("\nstr:\n")
print(str(pto))
# mapa
plot(pto, axes = TRUE)
Gerando o seguinte:
Ponto, duas coordenadas:
POINT (3 5)
class:
[1] "XY" "POINT" "sfg"
str:
'XY' num [1:2] 3 5
NULL
A função sf::st_point()
cria um ponto, que é um objeto
de geometria (ou, para simplificar a linguagem, uma geometria).
Note que usamos as funções nativas do R, class()
,
str()
e plot()
. As duas primeiras mostram que
o objeto criado não é um ponto qualquer, pois já está preparado para uso
em mapa. Observe, também, o uso de sf::
antes da função
st_point
. Indicar o pacote é um hábito, explicitando a qual
pacote a função pertence e evitando ambiguidades entre funções de mesmo
nome; é útil especialmente quando o R Script for longo e
revisitado muito tempo depois.
Usando plot()
, neste exemplo fizemos com que os eixos
fossem exibidos, o que costuma ser inconveniente para mapas.
Interessantemente, a função plot()
exibe os eixos por
default, mas com objetos deste tipo não o faz. Com demo_ponto2d_2.R
:
pto <- sf::st_point(c(3,5)) # 2 dimensões (XY)
plot(pto)
obtém-se:
Com pontos de duas coordenadas, mapas são bidimensionais. No entanto,
outras dimensões podem ser armazenadas em um ponto, por exemplo, Com demo_ponto4d.R
monta um ponto com 4 coordenadas:
cat("\nPonto, quatro coordenadas:\n")
pto <- sf::st_point(c(3,5,18,25)) # 4 dimensões (XYZM)
print(pto)
cat("\nclass:\n")
print(class(pto))
cat("\nstr:\n")
print(str(pto))
# mapa
plot(pto)
que contém, como podemos verificar:
Ponto, quatro coordenadas:
POINT ZM (3 5 18 25)
class:
[1] "XYZM" "POINT" "sfg"
str:
'XYZM' num [1:4] 3 5 18 25
NULL
O ponto tem quatro valores. Embora não haja efeito visível nesta imagem,
observe que as duas coordenadas adicionais foram incorporadas ao ponto
(observe o que
class()
informa), para uso em outras
situações. A terceira coordenada pode ser usada para indicar
profundidade; a quarta pode conter algum outro dado de interesse.
Vários pontos podem ser armazenados em uma geometria. Com demo_multiponto.R
x <- c(10,1,6,4)
y <- c(6,6,4,11)
z <- c(12,15,11,8)
pontos <- cbind(x,y,z) # cria matriz com tres colunas
cat("\nmatrix com os pontos:\n")
print(pontos)
cat("\nobjeto multipoint:\n")
mtpto <- sf::st_multipoint(pontos)
print(mtpto)
cat("\nclass:\n")
print(class(mtpto))
cat("\nstr:\n")
print(str(mtpto))
# mapa
plot(mtpto)
obtém-se:
matrix com os pontos:
x y z
[1,] 10 6 12
[2,] 1 6 15
[3,] 6 4 11
[4,] 4 11 8
objeto multipoint:
MULTIPOINT Z ((10 6 12), (1 6 15), (6 4 11), (4 11 8))
class:
[1] "XYZ" "MULTIPOINT" "sfg"
str:
'XYZ' num [1:4, 1:3] 10 1 6 4 6 6 4 11 12 15 ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:3] "x" "y" "z"
NULL
Note que class()
, agora, informa que há três dimensões e
que o objeto é MULTIPOINT
.
Os objetos definidos acima podem ser agrupados em uma simple
feature collection (sfc) usando a função st_sfc()
,
como em demo_geometria.R
.
x <- 3
y <- 5
pto <- sf::st_point(c(x,y))
x <- c(10,1,6,4)
y <- c(6,6,4,11)
z <- c(12,15,11,8)
ptos <- cbind(x,y,z) # cria matriz com tres colunas
mtpto <- sf::st_multipoint(ptos)
# objeto composto
cat("\nobjeto sfc (colecao de geometrias):\n")
geometria <- sf::st_sfc(pto,mtpto)
print(geometria)
cat("\nclass:\n")
print(class(geometria))
cat("\nstr:\n")
print(str(geometria))
# mapa
plot(geometria)
que gera:
objeto sfc (colecao de geometrias):
Geometry set for 2 features
Geometry type: GEOMETRY
Dimension: XY, XYZ
Bounding box: xmin: 1 ymin: 4 xmax: 10 ymax: 11
z_range: zmin: 8 zmax: 15
CRS: NA
POINT (3 5)
MULTIPOINT Z ((10 6 12), (1 6 15), (6 4 11), (4...
class:
[1] "sfc_GEOMETRY" "sfc"
str:
sfc_GEOMETRY of length 2; first list element: 'XY' num [1:2] 3 5
NULL
Observe a saída, que informa ser “Geometry set for 2 features”. Os dois componentes são POINT e MULTIPOINT. Podemos verificar como foram armazenados na geometria que acabamos de criar.
print(class(geometria[1]))
print(geometria[1])
[1] "sfc_POINT" "sfc"
Geometry set for 1 feature
Geometry type: POINT
Dimension: XY
Bounding box: xmin: 3 ymin: 5 xmax: 3 ymax: 5
CRS: NA
POINT (3 5)
print(class(geometria[2]))
print(geometria[2])
[1] "sfc_MULTIPOINT" "sfc"
Geometry set for 1 feature
Geometry type: MULTIPOINT
Dimension: XYZ
Bounding box: xmin: 1 ymin: 4 xmax: 10 ymax: 11
z_range: zmin: 8 zmax: 15
CRS: NA
MULTIPOINT Z ((10 6 12), (1 6 15), (6 4 11), (4...
demo_geometria_a.R
e demo_geometria_b.R
As duas geometrias que incorporamos com sf::st_sfc()
preservam, respectivamente, suas classes como sfc_POINT e
sfc_MULTIPOINT. O ponto isolado tem duas e os quatro multipontos têm
três dimensões cada um.
Esta geometria pode ser sofisticada, incluindo atributos para cada
ponto. Suponha que o primeiro ponto seja uma unidade de tratamento de
água, e que os multipontos definidos sejam poços artesianos,
executando-se demo_geometria2.R
.
# cria objeto sfc
x <- c(3,10,1,6,4)
y <- c(5,6,6,4,11)
z <- c(20,12,15,11,8)
coords <- cbind(x,y,z) # cria matriz com tres colunas
ptos <- c(NA,rep(nrow(coords)))
for (i in 1:nrow(coords))
{
ptos[i] <- list(sf::st_point(coords[i,]))
}
geometria2 <- sf::st_sfc(ptos)
# cria atributos para os pontos
id <- 1:length(geometria2)
tipo <- c("Unidade de tratamento",rep("Poço",4))
dt <- data.frame(id,tipo)
# monta novo objeto com os pontos
geometria2 <- sf::st_sf(dt,geometry=geometria2)
# exibe o resultado
cat("\nobjeto:\n")
print(class(geometria2))
print(geometria2)
cat("\nmapas:\n")
plot(geometria2)
objeto:
[1] "sf" "data.frame"
Simple feature collection with 5 features and 2 fields
Geometry type: POINT
Dimension: XYZ
Bounding box: xmin: 1 ymin: 4 xmax: 10 ymax: 11
z_range: zmin: 8 zmax: 20
CRS: NA
id tipo geometry
1 1 Unidade de tratamento POINT Z (3 5 20)
2 2 Poço POINT Z (10 6 12)
3 3 Poço POINT Z (1 6 15)
4 4 Poço POINT Z (6 4 11)
5 5 Poço POINT Z (4 11 8)
mapas:
A função sf::st_sf()
criou uma simple feature
de classe híbrida, contendo um sf e um data frame. Do
dataframe reconhecem-se dois atributos, que são id
(o número de identificação) e o tipo
(unidade de tratamento
ou poço).
O comportamento da função plot()
mudou, exibindo um mapa
para cada atributo (e usando uma cor diferente para cada um): no
primeiro mapa há 5 números de identificação diferentes (com cinco
cores); no segundo mapa representa apenas dois tipos (com duas
cores).
Quando se deseja exibir somente a geometria usa-se:
Para recuperar a informação do dataframe:
id tipo geometry
1 1 Unidade de tratamento POINT Z (3 5 20)
2 2 Poço POINT Z (10 6 12)
3 3 Poço POINT Z (1 6 15)
4 4 Poço POINT Z (6 4 11)
5 5 Poço POINT Z (4 11 8)
Para criar um objeto que é um subconjunto de outro objeto, por exemplo separando-se os pontos que representam poços:
[1] "sf" "data.frame"
Simple feature collection with 4 features and 2 fields
Geometry type: POINT
Dimension: XYZ
Bounding box: xmin: 1 ymin: 4 xmax: 10 ymax: 11
z_range: zmin: 8 zmax: 15
CRS: NA
id tipo geometry
2 2 Poço POINT Z (10 6 12)
3 3 Poço POINT Z (1 6 15)
4 4 Poço POINT Z (6 4 11)
5 5 Poço POINT Z (4 11 8)
Uma linha pode ser definida por um ou mais segmentos de reta
posicionados pelas coordenadas (x,y) de suas extremidades. Suponha que
os poços estejam ligados à unidade de tratamento de água por tubulações,
representadas por linhas. Da mesma forma que foi feito com pontos,
pode-se criar objetos com coleções de linhas. Por exemplo, executando-se
demo_linhas.R
(depende de rodar o exemplo anterior para criar a unidade de tratamento
e os poços antes):
# recupera as coordenadas dos pontos
# tubulacoes comecam nos pocos
pocos <- geometria2[tipo=="Poço",]
coord_pocos <- sf::st_coordinates(pocos$geometry)
# tubulacoes terminam na unidade de tratamento
tubos <- geometria2[tipo=="Unidade de tratamento",]
coord_trata <- sf::st_coordinates(tubos$geometry)
# maxmin y
ymin <- min(coord_pocos[,2],coord_trata[,2])
ymax <- max(coord_pocos[,2],coord_trata[,2])
# criando uma linha de cada poco ate a un. de tratamento
x <- c(coord_pocos[1,1], 6.3, coord_trata[1,1])
y <- c(coord_pocos[1,2], 6.1, coord_trata[1,2])
xy <- cbind(x,y)
l1 <- sf::st_linestring(xy)
x <- c(coord_pocos[2,1],2.2, 2.7, coord_trata[1,1])
y <- c(coord_pocos[2,2],6.6, 4.8, coord_trata[1,2])
xy <- cbind(x,y)
l2 <- sf::st_linestring(xy)
x <- c(coord_pocos[3,1],5.3, 3.8, coord_trata[1,1])
y <- c(coord_pocos[3,2],4.1, 4.6, coord_trata[1,2])
xy <- cbind(x,y)
l3 <- sf::st_linestring(xy)
x <- c(coord_pocos[4,1],3.3, 3.8, coord_trata[1,1])
y <- c(coord_pocos[4,2],10.2, 8.1, coord_trata[1,2])
xy <- cbind(x,y)
l4 <- sf::st_linestring(xy)
# junta as linhas
adutoras <- sf::st_multilinestring(list(l1,l2,l3,l4))
# mapa
plot(adutoras,lwd=2,col="blue", xlim=c(0,12), ylim=c(0,12))
plot(pocos$geometry,pch=21,bg="lightblue",add=TRUE)
plot(tubos$geometry,pch=21,bg="green",cex=1.5,add=TRUE)
temos:
Polígonos fechados também podem ser representados em objetos. O
cuidado é fornecer as coordenadas \((x,y)\) de forma que o último par de
coordenadas coincida com o primeiro para fechar o polígono. Por exemplo,
demo_poligonos.R
:
library("sf")
## P1 Polígono rio
## Polygon
# Cria uma cadeia de coordenadas em X
x <- c(0,6,10,12,12,11,5,0,0)
y <- c(0,0,1,3,6,5,3,3,0)
c <- cbind(x,y)
# Cria um objeto polygon (forma simples fechada)
rio = sf::st_polygon(list(c))
# Lencol freatico
x <- c(0,5,11,12,12,10,6,3,2,1,0,0)
y <- c(5,3,5,6,7,10,12,12,10,9,7,5)
c <- cbind(x,y)
# cria um buraco, area seca
x <- c(2,3,4,6,5,3,3,2)
y <- c(5,4,4,7,9,9,7,5)
c2 <- cbind(x,y)
lencol = sf::st_polygon(list(c,c2))
# floresta alta
x <- c(0,5,11,12,12,0,0)
y <- c(3,3,5,6,12,12,3)
c <- cbind(x,y)
floresta1 = sf::st_polygon(list(c))
# floresta baixa
x <- c(6,12,12,10,6)
y <- c(0,0,3,1,0)
c <- cbind(x,y)
floresta2 = sf::st_polygon(list(c))
# Junta várias geometrias com sfc (coleção de simple features)
geometria.all = sf::st_sfc(rio, lencol, floresta1, floresta2)
# Tabela de atributos
ID <- c(1,2,3,4)
code <- c("A","L","F","F")
tipo <- c("Agua","Lencol freatico", "Floresta", "Floresta")
tabela <- data.frame(cbind(ID,code,tipo))
# sf object
sfc_all = sf::st_sf(tabela, geometry = geometria.all)
plot(sfc_all$geometry)
plot(st_geometry(sfc_all[tipo=="Agua",]),col="#00ffff",add=TRUE)
plot(st_geometry(sfc_all[tipo=="Floresta",]),col="#00880050",add=TRUE)
plot(st_geometry(sfc_all[tipo=="Lencol freatico",]),col="#ffff00",add=TRUE)
mostra:
Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE
Podemos exibir conjuntamente as duas coleções de geometrias que construímos. A primeira coleção contém os poços (em azul claro) e tubulações (em azul escuro) que levam água à unidade de tratamento (verde); a segunda monta um ambiente com um rio (em azul claro), lençol freático (em amarelo) e a mata (em verde, parcialmente transparente, sobrepondo o lençol freático subterrâneo).
plot(sfc_all$geometry, xlim=c(0,12), ylim=c(0,12))
plot(sf::st_geometry(sfc_all[tipo=="Agua",]),col="#00ffff",add=TRUE)
plot(sf::st_geometry(sfc_all[tipo=="Lencol freatico",]),col="#ffff00",add=TRUE)
plot(sf::st_geometry(sfc_all[tipo=="Floresta",]),col="#00880050",add=TRUE)
plot(adutoras,lwd=2,col="blue",add=TRUE)
plot(pocos$geometry,pch=21,bg="lightblue",add=TRUE)
plot(tubos$geometry,pch=21,bg="green",cex=1.5,add=TRUE)
Este é o princípo de vários mapas disponíveis na Web, como por exemplo:
Os arquivos com este tipo de objeto, contendo geometrias e atributos, são oferecidos em shapefiles, conjuntos formados, no mínimo, por arquivos:
.shp
(com as geometrias),.shx
(um índice) e.dbf
(com os atributos).Este padrão foi estabelecido pela ESRI e amplamente utilizado para a troca de informações geográficas. A ESRI (Environmental Systems Research Institute) tem sede mundial em Redlands na Califórnia, Estados Unidos, produzindo soluções para o uso de informações geográficas. Dependendo do distribuidor, há arquivos com dados adicionais.
Há vários sites que distribuem mapas gratuitos. Busque “shapefiles” e o tipo de mapa que quer na Web.
Por exemplo, o arquivo
disponível no site Natural Earth tem, ao descompactar, os dados de
geometria em arquivo .shp
, trazendo os polígonos de cada
país. Este site oferece muitos mapas diferentes, com três níveis de
detalhamento (o número 50 que aparece no nome do arquivo é o
detalhamento moderado - veja Natural Earth,
Features{target”blank”}).
Descompactando o arquivo em uma pasta chamada
NaturalEarth
, executa-se, no estilo sf
:
sf_countries <- sf::st_read("NaturalEarth/ne_50m_admin_0_countries.shp")
plot(sf::st_geometry(sf_countries))
Reading layer `ne_50m_admin_0_countries' from data source
`D:\Usuarios\Jose\Documents\FMUSP\Pos-graduacao\MDR5730\Geoprocessamento\NaturalEarth\ne_50m_admin_0_countries.shp'
using driver `ESRI Shapefile'
Simple feature collection with 241 features and 94 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -180 ymin: -89.99893 xmax: 180 ymax: 83.59961
Geodetic CRS: WGS 84
demo_sf_worldmap1.R
.
Equivalentemente, para o modo sp
mais tradicional:
sp_countries <- rgdal::readOGR(dsn="NaturalEarth",layer="ne_50m_admin_0_countries")
plot(sp_countries)
demo_sp_worldmap1.R
.
Embora o resultado visual seja o mesmo, uma diferença importante
entre os dois métodos é que rgdal::readOGR
separa o caminho
(dns=
) e o nome de base do objeto espacial
sem a extensão .shp (layer=
).
Os objetos sf_countries
e sp_countries
também são diferentes:
cat("\nsf_countries:\n")
print(paste0(class(sf_countries)))
# cat("\nsp_countries:\n")
# print(class(sp_countries))
sf_countries:
[1] "sf" "data.frame"
Caso os verifique com str()
ou print()
verá
que os dados estão internamente organizados de forma diversa.
Note, ainda, que as funções sf::st_read
e
rgdal::readOGR
ecoam informações sobre o mapa que leram, o
que pode não ser conveniente em sua aplicação. Na documentação das
funções encontram-se os parâmetros que as silenciam,
respectivamente:
quiet=TRUE
para o pacote sf
:sfc_countries <- sf::st_read("NaturalEarth/ne_50m_admin_0_countries.shp", quiet=TRUE)
plot(sf::st_geometry(sfc_countries))
demo_sf_worldmap1d1.R
.
verbose=FALSE
para o pacote sp
:sp_countries <- rgdal::readOGR(dsn="NaturalEarth",layer="ne_50m_admin_0_countries", verbose=FALSE)
plot(sp_countries)
demo_sp_worldmap1d1.R
.
Como são mapas feitos com polígonos, podem ser preenchidos com cores,
usando os valores prontos em R ou qualquer cor que deseje em RGB, com a
importante diferença de que a função sf::st_geometry()
é
necessária para o primeiro estilo. Por exemplo,
plot(sf::st_geometry(sf_countries),col="lightgreen")
demo_sf_worldmap1b.R
.
ou
plot(sp_countries,col="lightgreen")
demo_sp_worldmap1b.R
.
Embora os dois objetos tenham organizações internas diferentes, o acesso aos dados é similar. Além dos polígonos, para descobrir o que existe em seu data frame, use
[1] "featurecla" "scalerank" "LABELRANK" "SOVEREIGNT" "SOV_A3"
[6] "ADM0_DIF" "LEVEL" "TYPE" "ADMIN" "ADM0_A3"
[11] "GEOU_DIF" "GEOUNIT" "GU_A3" "SU_DIF" "SUBUNIT"
[16] "SU_A3" "BRK_DIFF" "NAME" "NAME_LONG" "BRK_A3"
[21] "BRK_NAME" "BRK_GROUP" "ABBREV" "POSTAL" "FORMAL_EN"
[26] "FORMAL_FR" "NAME_CIAWF" "NOTE_ADM0" "NOTE_BRK" "NAME_SORT"
[31] "NAME_ALT" "MAPCOLOR7" "MAPCOLOR8" "MAPCOLOR9" "MAPCOLOR13"
[36] "POP_EST" "POP_RANK" "GDP_MD_EST" "POP_YEAR" "LASTCENSUS"
[41] "GDP_YEAR" "ECONOMY" "INCOME_GRP" "WIKIPEDIA" "FIPS_10_"
[46] "ISO_A2" "ISO_A3" "ISO_A3_EH" "ISO_N3" "UN_A3"
[51] "WB_A2" "WB_A3" "WOE_ID" "WOE_ID_EH" "WOE_NOTE"
[56] "ADM0_A3_IS" "ADM0_A3_US" "ADM0_A3_UN" "ADM0_A3_WB" "CONTINENT"
[61] "REGION_UN" "SUBREGION" "REGION_WB" "NAME_LEN" "LONG_LEN"
[66] "ABBREV_LEN" "TINY" "HOMEPART" "MIN_ZOOM" "MIN_LABEL"
[71] "MAX_LABEL" "NE_ID" "WIKIDATAID" "NAME_AR" "NAME_BN"
[76] "NAME_DE" "NAME_EN" "NAME_ES" "NAME_FR" "NAME_EL"
[81] "NAME_HI" "NAME_HU" "NAME_ID" "NAME_IT" "NAME_JA"
[86] "NAME_KO" "NAME_NL" "NAME_PL" "NAME_PT" "NAME_RU"
[91] "NAME_SV" "NAME_TR" "NAME_VI" "NAME_ZH" "geometry"
ou
Repare que as.data.frame()
funciona da mesma maneira
para ambos.
Como este arquivo foi bem construído, os nomes das colunas são sugestivos de seu conteúdo. Que tal tentar a coluna NAME_PT para verificar?
# as.data.frame(sp_countries) fornece com o mesmo resultado
dt_countries <- as.data.frame(sf_countries)
cat("\nTotal de ",nrow(dt_countries)," países disponíveis:\n",sep="")
print(dt_countries$NAME_PT)
Total de 241 países disponíveis:
[1] "Zimbábue"
[2] "Zâmbia"
[3] "Iémen"
[4] "Vietname"
[5] "Venezuela"
[6] "Vaticano"
[7] "Vanuatu"
[8] "Usbequistão"
[9] "Uruguai"
[10] "Micronésia"
[11] "Ilhas Marshall"
[12] "Marianas Setentrionais"
[13] "Ilhas Virgens Americanas"
[14] "Guam"
[15] "Samoa Americana"
[16] "Porto Rico"
[17] "Estados Unidos"
[18] "Ilhas Geórgia do Sul e Sandwich do Sul"
[19] "Território Britânico do Oceano Índico"
[20] "Santa Helena"
[21] "Ilhas Pitcairn"
[22] "Anguilla"
[23] "Ilhas Malvinas"
[24] "Ilhas Cayman"
[25] "Bermudas"
[26] "Ilhas Virgens Britânicas"
[27] "Turks e Caicos"
[28] "Montserrat"
[29] "Jersey"
[30] "Guernsey"
[31] "Ilha de Man"
[32] "Reino Unido"
[33] "Emirados Árabes Unidos"
[34] "Ucrânia"
[35] "Uganda"
[36] "Turquemenistão"
[37] "Turquia"
[38] "Tunísia"
[39] "Trinidad e Tobago"
[40] "Tonga"
[41] "Togo"
[42] "Timor-Leste"
[43] "Tailândia"
[44] "Tanzânia"
[45] "Tajiquistão"
[46] "Taiwan"
[47] "Síria"
[48] "Suíça"
[49] "Suécia"
[50] "eSwatini"
[51] "Suriname"
[52] "Sudão do Sul"
[53] "Sudão"
[54] "Sri Lanka"
[55] "Espanha"
[56] "Coreia do Sul"
[57] "África do Sul"
[58] "Somália"
[59] "Somalilândia"
[60] "Ilhas Salomão"
[61] "Eslováquia"
[62] "Eslovénia"
[63] "Singapura"
[64] "Serra Leoa"
[65] "Seychelles"
[66] "Sérvia"
[67] "Senegal"
[68] "Arábia Saudita"
[69] "São Tomé e Príncipe"
[70] "San Marino"
[71] "Samoa"
[72] "São Vicente e Granadinas"
[73] "Santa Lúcia"
[74] "São Cristóvão e Nevis"
[75] "Ruanda"
[76] "Rússia"
[77] "Roménia"
[78] "Catar"
[79] "Portugal"
[80] "Polónia"
[81] "Filipinas"
[82] "Peru"
[83] "Paraguai"
[84] "Papua-Nova Guiné"
[85] "Panamá"
[86] "Palau"
[87] "Paquistão"
[88] "Omã"
[89] "Noruega"
[90] "Coreia do Norte"
[91] "Nigéria"
[92] "Níger"
[93] "Nicarágua"
[94] "Nova Zelândia"
[95] "Niue"
[96] "Ilhas Cook"
[97] "Países Baixos"
[98] "Aruba"
[99] "Curaçao"
[100] "Nepal"
[101] "Nauru"
[102] "Namíbia"
[103] "Moçambique"
[104] "Marrocos"
[105] "Saara Ocidental"
[106] "Montenegro"
[107] "Mongólia"
[108] "Moldávia"
[109] "Mónaco"
[110] "México"
[111] "Maurícia"
[112] "Mauritânia"
[113] "Malta"
[114] "Mali"
[115] "Maldivas"
[116] "Malásia"
[117] "Malawi"
[118] "Madagáscar"
[119] "República da Macedónia"
[120] "Luxemburgo"
[121] "Lituânia"
[122] "Liechtenstein"
[123] "Líbia"
[124] "Libéria"
[125] "Lesoto"
[126] "Líbano"
[127] "Letónia"
[128] "Laos"
[129] "Quirguistão"
[130] "Kuwait"
[131] "Kosovo"
[132] "Kiribati"
[133] "Quénia"
[134] "Cazaquistão"
[135] "Jordânia"
[136] "Japão"
[137] "Jamaica"
[138] "Itália"
[139] "Israel"
[140] "Palestina"
[141] "República da Irlanda"
[142] "Iraque"
[143] "Irão"
[144] "Indonésia"
[145] "Índia"
[146] "Islândia"
[147] "Hungria"
[148] "Honduras"
[149] "Haiti"
[150] "Guiana"
[151] "Guiné-Bissau"
[152] "Guiné"
[153] "Guatemala"
[154] "Granada"
[155] "Grécia"
[156] "Gana"
[157] "Alemanha"
[158] "Geórgia"
[159] "Gâmbia"
[160] "Gabão"
[161] "França"
[162] "Saint-Pierre e Miquelon"
[163] "Wallis e Futuna"
[164] "São Martinho"
[165] "Coletividade de São Bartolomeu"
[166] "Polinésia Francesa"
[167] "Nova Caledónia"
[168] "Terras Austrais e Antárticas Francesas"
[169] "Åland"
[170] "Finlândia"
[171] "Fiji"
[172] "Etiópia"
[173] "Estónia"
[174] "Eritreia"
[175] "Guiné Equatorial"
[176] "El Salvador"
[177] "Egito"
[178] "Equador"
[179] "República Dominicana"
[180] "Dominica"
[181] "Djibouti"
[182] "Gronelândia"
[183] "Ilhas Feroe"
[184] "Dinamarca"
[185] "República Checa"
[186] "República Turca de Chipre do Norte"
[187] "Chipre"
[188] "Cuba"
[189] "Croácia"
[190] "Costa do Marfim"
[191] "Costa Rica"
[192] "República Democrática do Congo"
[193] "Congo"
[194] "Comores"
[195] "Colômbia"
[196] "China"
[197] "Macau"
[198] "Hong Kong"
[199] "Chile"
[200] "Chade"
[201] "República Centro-Africana"
[202] "Cabo Verde"
[203] "Canadá"
[204] "Camarões"
[205] "Camboja"
[206] "Mianmar"
[207] "Burundi"
[208] "Burkina Faso"
[209] "Bulgária"
[210] "Brunei"
[211] "Brasil"
[212] "Botsuana"
[213] "Bósnia e Herzegovina"
[214] "Bolívia"
[215] "Butão"
[216] "Benim"
[217] "Belize"
[218] "Bélgica"
[219] "Bielorrússia"
[220] "Barbados"
[221] "Bangladesh"
[222] "Bahrein"
[223] "Bahamas"
[224] "Azerbaijão"
[225] "Áustria"
[226] "Austrália"
[227] "Territórios australianos do Oceano Índico"
[228] "Ilha Heard e Ilhas McDonald"
[229] "Ilha Norfolk"
[230] "Ilhas Ashmore e Cartier"
[231] "Arménia"
[232] "Argentina"
[233] "Antígua e Barbuda"
[234] "Angola"
[235] "Andorra"
[236] "Argélia"
[237] "Albânia"
[238] "Afeganistão"
[239] "Glaciar de Siachen"
[240] "Antártida"
[241] "São Martinho"
demo_worldmap1b1.R
.
Para evitar redundâncias, alguns dos exemplos abaixo são feitos
apenas em estilo É fácil, caso deseje, adaptar o código para o outro estilo. |
Podemos separar o polígono que contém o Brasil e exibi-lo em outra cor (amarelo, neste exemplo):
sf_countries <- sf::st_read("NaturalEarth/ne_50m_admin_0_countries.shp", quiet=TRUE)
plot(st_geometry(sf_countries$geometry),col="lightgray")
dt_countries <- as.data.frame(sf_countries)
linha <- which(dt_countries$NAME_PT=="Brasil")
plot(sf_countries$geometry[linha],col="yellow",add=TRUE)
demo_worldmap1c.R
.
Obviamente, também é possível exibir apenas um polígono. Embora isto não seja muito interessante por enquanto, mostra que o uso destas geometrias é muito flexível:
sp_countries <- rgdal::readOGR(dsn="NaturalEarth",layer="ne_50m_admin_0_countries", verbose=FALSE)
dt_countries <- as.data.frame(sfc_countries)
linha <- which(dt_countries$NAME_PT=="Brasil")
plot(sp_countries[linha,],col="yellow")
demo_worldmap1d.R
.
Observe as duas formas, nos dois estilos, para isolar um único polígono. Em objetos lidos por de
Para objetos lidos por
(observe a vírgula após |
Ainda do mesmo site há arquivos com outras possibilidades:
Estes dois arquivos fornecem as as fronteiras dos países e as linhas costeiras. Propositalmente exibimos aqui, primeiro, apenas as fronteiras:
sfc_borders <- sf::st_read("NaturalEarth/ne_50m_admin_0_boundary_lines_land.shp", quiet=TRUE)
plot(sf::st_geometry(sfc_borders$geometry))
demo_worldmap1e.R
.
… exatamente o que promete o arquivo: são linhas, e não polígonos como no caso anterior.
Para ter a aparência do mapa mundial, combine os dois (para clareza, exibimos com duas cores diferentes: preto para os contornos costeiros e cinza para as fronteiras entre os países):
sfc_coastline <- sf::st_read("NaturalEarth/ne_50m_coastline.shp", quiet=TRUE)
sfc_borders <- sf::st_read("NaturalEarth/ne_50m_admin_0_boundary_lines_land.shp", quiet=TRUE)
plot(sf::st_geometry(sfc_coastline$geometry),col="black")
plot(sf::st_geometry(sfc_borders$geometry),col="darkgray",add=TRUE)
demo_worldmap1e1.R
.
Note o uso de add=TRUE
para sobrepor as duas
geometrias.
Interessantemente, mapas podem ser combinados. Neste exemplo, como
usaremos o polígono que representa o Brasil, note que o parâmetro
col
indica a cor do preenchimento e border
é a
cor da linha; para os exemplos anteriores, que as geometrias eram
linhas, col
era a cor da linha. Além disto, como estamos
usando a função nativa plot()
, podemos aproveitar
lwd
para definir a espessura da linha de contorno do
polígono (lwd, do inglês, line width).
Executa-se este exemplo, que destaca o Brasil e a Groenlândia:
sfc_coastline <- sf::st_read("NaturalEarth/ne_50m_coastline.shp", quiet=TRUE)
sfc_borders <- sf::st_read("NaturalEarth/ne_50m_admin_0_boundary_lines_land.shp", quiet=TRUE)
sfc_countries <- sf::st_read("NaturalEarth/ne_50m_admin_0_countries.shp", quiet=TRUE)
plot(sf::st_geometry(sfc_coastline$geometry),col="black")
plot(sf::st_geometry(sfc_borders$geometry),col="darkgray",add=TRUE)
# Brasil em destaque
dt_countries <- as.data.frame(sfc_countries)
linha <- which(dt_countries$NAME_PT=="Brasil")
plot(sf::st_geometry(sfc_countries$geometry[linha]),
col="yellow",border="darkgreen",
lwd=2, add=TRUE)
# Groenlandia em destaque
# por erro, aparece como "Gronelândia" no mapa
dt_countries <- as.data.frame(sfc_countries)
linha <- which(dt_countries$NAME_PT=="Gronelândia")
plot(sf::st_geometry(sfc_countries$geometry[linha]),
col="#a6da9a",border="black",
add=TRUE)
demo_worldmap1e2.R
.
Este mapa, pela aparência, usa uma projeção equiretangular (https://en.wikipedia.org/wiki/Equirectangular_projection), um tipo de projeção cilíndrica, das quais a mais famosa é a projeção de Mercator (https://en.wikipedia.org/wiki/Mercator_projection). O problema a ser resolvido pelas projeções é representar em um plano a superfície esférica. Nas projeções cilíndricas, o principal defeito é distorcer as áreas dos países, ampliando o que está mais próximo dos polos. Por isso a Europa parece maior do que é, a Groenlândia, muito próxima ao polo norte, tem tamanho próximo ao Brasil (quando na verdade é cerca de 4 vezes menor), e a Antártida, no polo sul, é exibida com um tamanho tremendamente exagerado. Uma animação disponível em https://commons.wikimedia.org/wiki/File:Worlds_animate.gif ilustra bem a distorção das áreas: Cada projeção tem vantagens e desvantagens. Veja https://en.wikipedia.org/wiki/Map_projection para mais informações. Existem formas de usar outros tipos de projeção na análise espacial em R. Por exemplo, podemos exibir o mapa mundial com projeção de (Mollweide)[https://en.wikipedia.org/wiki/Mollweide_projection], a qual preserva a proporção entre as áreas, com
Implementado com
demo_Mollweide.R .
CRS (Coordinate Reference Systems) é o que governa as projeções. Uma documentação que pode ajudar está em (Overview of Coordinate Reference Systems (CRS) in R)[https://www.nceas.ucsb.edu/sites/default/files/2020-04/OverviewCoordinateReferenceSystems.pdf]. |
Outra coisa interessante é que, sendo o formato padronizado, mapas de diferentes fontes podem ser combinados. Por exemplo, podemos pegar do website Nereus(USP) o arquivo Brasil.zip, que foi descompactado na pasta BrasilUSP, para exibir o contorno das unidades da federação:
sfc_coastline <- sf::st_read("NaturalEarth/ne_50m_coastline.shp", quiet=TRUE)
sfc_borders <- sf::st_read("NaturalEarth/ne_50m_admin_0_boundary_lines_land.shp", quiet=TRUE)
sfc_countries <- sf::st_read("NaturalEarth/ne_50m_admin_0_countries.shp", quiet=TRUE)
plot(sf::st_geometry(sfc_coastline$geometry),col="black")
plot(sf::st_geometry(sfc_borders$geometry),col="gray",add=TRUE)
# Brasil em destaque
dt_countries <- as.data.frame(sfc_countries)
linha <- which(dt_countries$NAME_PT=="Brasil")
plot(sf::st_geometry(sfc_countries$geometry[linha]),
col="yellow",border="darkgreen",
lwd=1, add=TRUE)
# Mapa dos estados
sfc_br <- sf::st_read("BrasilUSP/UFEBRASIL.shp",quiet=TRUE)
plot(sfc_br$geometry,add=TRUE,lwd=0.6)
demo_worldmap1e3.R
.
… ou, pegando o arquivo South_America.rar
(disponível em
Efrain Maps) que descompactamos na subpasta
EfrainMaps
, exibir somente a América do Sul em lugar do
mundo inteiro:
# Paises do Mundo
sfc_countries <- sf::st_read("NaturalEarth/ne_50m_admin_0_countries.shp")
# America do Sul
sfc_americasul <- sf::st_read("EfrainMaps/South_America.shp", quiet=TRUE)
plot(sf::st_geometry(sfc_americasul))
# Brasil em destaque
dt_countries <- as.data.frame(sfc_countries)
linha <- which(dt_countries$NAME_PT=="Brasil")
plot(sf::st_geometry(sfc_countries$geometry[linha]),
col="yellow",border="darkgreen",
lwd=1, add=TRUE)
# Mapa dos estados
sfc_br <- sf::st_read("BrasilUSP/UFEBRASIL.shp",quiet=TRUE)
plot(sfc_br$geometry,add=TRUE,lwd=0.6)
Reading layer `ne_50m_admin_0_countries' from data source
`D:\Usuarios\Jose\Documents\FMUSP\Pos-graduacao\MDR5730\Geoprocessamento\NaturalEarth\ne_50m_admin_0_countries.shp'
using driver `ESRI Shapefile'
Simple feature collection with 241 features and 94 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -180 ymin: -89.99893 xmax: 180 ymax: 83.59961
Geodetic CRS: WGS 84
demo_americasul1.R
.
Podemos adicionar quantas camadas desejarmos, como por exemplo exibindo as hidrovias brasileiras (https://www.gov.br/infraestrutura/pt-br/assuntos/dados-de-transportes/bit/bitmodosmapas). Neste exemplo alteramos cores e espessura de linhas para dar destaque aos elementos de maior interesse:
library(sf)
# Paises do Mundo
sfc_countries <- sf::st_read("NaturalEarth/ne_50m_admin_0_countries.shp", quiet=TRUE)
# Paises da America do Sul
sfc_americasul <- sf::st_read("EfrainMaps/South_America.shp", quiet=TRUE)
plot(sf::st_geometry(sfc_americasul), border="gray")
# Brasil em destaque
dt_countries <- as.data.frame(sfc_countries)
linha <- which(dt_countries$NAME_PT=="Brasil")
plot(sf::st_geometry(sfc_countries$geometry[linha]),
col="gray",border="black", lwd=1, add=TRUE)
# Mapa dos estados
sfc_br <- sf::st_read("BrasilUSP/UFEBRASIL.shp",quiet=TRUE)
plot(sfc_br$geometry,border="black",add=TRUE,lwd=0.3)
# Hidrovias
sfc_hidro <- sf::st_read("BrasilGov/Hidrovias.shp",quiet=TRUE)
plot(sfc_hidro$geometry,add=TRUE,col="darkcyan",lwd=1.5)
demo_americasul2.R
.
O mesmo mapa pode adicionar informações do data frame associado, por exemplo extraindo-se os nomes dos países da América do Sul e escrevendo-os perto dos centróides dos respectivos polígonos:
# Nomes dos países
paises <- as.data.frame(sfc_americasul)$COUNTRY
for (p in 1:length(paises))
{
centroide <- sf::st_centroid(sfc_americasul$geometry[[p]])
text(centroide[1],centroide[2],paises[p],col="brown",cex=0.8)
}
demo_americasul2nome.R
.
(algum refinamento poderia ser feito, acertando a posição das Guianas e encurtando o nome das ilhas oceânicas ao sul, mas isto vai além da necessidade deste texto)
sf
Podemos utilizar a função st_centroid()
para definir
onde escrever os nomes dos países. Há um grande número de funções neste
pacote (e há vários outros pacotes que interagem com ele). Por
exemplo:
st_distance()
: computa a distância entre
geometriasst_intersects()
: verifica se há intersecção (por
exemplo, para saber se determinados pontos estão dentro de um
polígono)st_intersection()
: que cria um novo objeto com a
intersecção de outros.Por exemplo, para desenhar a parte das hidrovias que estão no Estado do Amazonas, podemos adicionar:
# parte da Hidrovia que está no Estado do Amazonas
linha_UF <- which(sfc_br$NM_ESTADO=="AMAZONAS")
interseccao <- sf::st_intersection(sfc_br$geometry[linha_UF],sfc_hidro)
plot(interseccao,add=TRUE,lwd=2,col="purple")
demo_americasul2partes.R
.
Os métodos para encontrar os centróides nos objetos lidos por
|
O pacote ggplot2
traz a poderosa função
ggplot
para a criação de gráficos. Para este exemplo
utilizaremos shapefiles dos pacotes rnaturalearth
,
parte do projeto ROpenSci. Para isto, a seguinte instalação precisa
ser feita:
install.packages("devtools") install.packages("rnaturalearth") install.packages("rnaturalearthdata") devtools::install_github("ropensci/rnaturalearthhires")
Há, nestes pacotes, objetos do tipo sf
contendo mapas de
várias regiões do mundo. Para separar os shapefiles que deseja,
precisará encontrar o nome dos países ou regiões que lhe interessam.
Neste exemplo quero exibir o mapa da América do Sul, com o Brasil e, em
destaque, o Estado de São Paulo. Para localizá-los, usaremos as funções
rnaturalearth::ne_countries
e
rnaturalearth::ne_states
:
df <- rnaturalearth::ne_countries()
continentes <- unique(df$continent)
prmatrix(continentes,collab="",rowlab=rep("",length(continentes)))
"Oceania"
"Africa"
"North America"
"Asia"
"South America"
"Europe"
"Seven seas (open ocean)"
"Antarctica"
"Fiji"
"Tanzania"
"Western Sahara"
"Canada"
"United States"
"Kazakhstan"
"Uzbekistan"
"Papua New Guinea"
"Indonesia"
"Argentina"
"Chile"
"Democratic Republic of the Congo"
"Somalia"
"Kenya"
"Sudan"
"Chad"
"Haiti"
"Dominican Republic"
"Russian Federation"
"Bahamas"
"Falkland Islands / Malvinas"
"Norway"
"Greenland"
"French Southern and Antarctic Lands"
"Timor-Leste"
"South Africa"
"Lesotho"
"Mexico"
"Uruguay"
"Brazil"
"Bolivia"
"Peru"
"Colombia"
"Panama"
"Costa Rica"
"Nicaragua"
"Honduras"
"El Salvador"
"Guatemala"
"Belize"
"Venezuela"
"Guyana"
"Suriname"
"France"
"Ecuador"
"Puerto Rico"
"Jamaica"
"Cuba"
"Zimbabwe"
"Botswana"
"Namibia"
"Senegal"
"Mali"
"Mauritania"
"Benin"
"Niger"
"Nigeria"
"Cameroon"
"Togo"
"Ghana"
"Côte d'Ivoire"
"Guinea"
"Guinea-Bissau"
"Liberia"
"Sierra Leone"
"Burkina Faso"
"Central African Republic"
"Republic of the Congo"
"Gabon"
"Equatorial Guinea"
"Zambia"
"Malawi"
"Mozambique"
"Kingdom of eSwatini"
"Angola"
"Burundi"
"Israel"
"Lebanon"
"Madagascar"
"Palestine"
"The Gambia"
"Tunisia"
"Algeria"
"Jordan"
"United Arab Emirates"
"Qatar"
"Kuwait"
"Iraq"
"Oman"
"Vanuatu"
"Cambodia"
"Thailand"
"Lao PDR"
"Myanmar"
"Vietnam"
"Dem. Rep. Korea"
"Republic of Korea"
"Mongolia"
"India"
"Bangladesh"
"Bhutan"
"Nepal"
"Pakistan"
"Afghanistan"
"Tajikistan"
"Kyrgyzstan"
"Turkmenistan"
"Iran"
"Syria"
"Armenia"
"Sweden"
"Belarus"
"Ukraine"
"Poland"
"Austria"
"Hungary"
"Moldova"
"Romania"
"Lithuania"
"Latvia"
"Estonia"
"Germany"
"Bulgaria"
"Greece"
"Turkey"
"Albania"
"Croatia"
"Switzerland"
"Luxembourg"
"Belgium"
"Netherlands"
"Portugal"
"Spain"
"Ireland"
"New Caledonia"
"Solomon Islands"
"New Zealand"
"Australia"
"Sri Lanka"
"China"
"Taiwan"
"Italy"
"Denmark"
"United Kingdom"
"Iceland"
"Azerbaijan"
"Georgia"
"Philippines"
"Malaysia"
"Brunei Darussalam"
"Slovenia"
"Finland"
"Slovakia"
"Czech Republic"
"Eritrea"
"Japan"
"Paraguay"
"Yemen"
"Saudi Arabia"
"Antarctica"
"Northern Cyprus"
"Cyprus"
"Morocco"
"Egypt"
"Libya"
"Ethiopia"
"Djibouti"
"Somaliland"
"Uganda"
"Rwanda"
"Bosnia and Herzegovina"
"North Macedonia"
"Serbia"
"Montenegro"
"Kosovo"
"Trinidad and Tobago"
"South Sudan"
Como existe Brazil, seus estados estão em
uf <- rnaturalearth::ne_states(country="Brazil")
prmatrix(uf$name_pt,collab="",rowlab=rep("",nrow(uf)))
"Rio Grande do Sul"
"Roraima"
"Pará"
"Acre"
"Amapá"
"Mato Grosso do Sul"
"Paraná"
"Santa Catarina"
"Amazonas"
"Rondônia"
"Mato Grosso"
"Maranhão"
"Piauí"
"Ceará"
"Rio Grande do Norte"
"Paraíba"
"Pernambuco"
"Alagoas"
"Sergipe"
"Bahia"
"Espírito Santo"
"Rio de Janeiro"
"São Paulo"
"Goiás"
"Federal"
"Minas Gerais"
"Tocantins"
Começando por São Paulo, podemos ver seu mapa, que é adicionado a
ggplot2::ggplot
com a função ggplot2::geom_sf
(o pacote ggplot2
tem diversas funções especialmente
desenvolvidas para mapas):
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=SP, fill="gray", color="black")
print(grf)
demo_ggplot_SaoPaulo01.R
.
Este mapa é um tanto sem graça. Vamos, então, detalhar o Estado em
seus municípios. Como esta informação não existe no
rnaturalearth
, podemos procurar shapes de outras
fontes. O (IBGE)[https://www.ibge.gov.br/geociencias/organizacao-do-territorio/malhas-territoriais/15774-malhas.html],
por exemplo, as tem. Baixei o arquivo que nos interessa e coloquei na
pasta IBGE (um nível abaixo de onde está o R Script).
Executamos, então:
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
municipios <- sf::st_read("IBGE/SP_Municipios_2021.shp", quiet=TRUE)
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_sf(data=municipios, fill="transparent", color="#507052", size=0.2)
print(grf)
demo_ggplot_SaoPaulo02.R
.
Observe que o |
Suponha, porém, que eu queira separar apenas os municípios mais populosos. Segundo a Wikipedia há nove municípios com mais que 500.000 habitantes:
Vamos localizá-los e destacar em nosso mapa. Para isto, criaremos um data frame com os nove municípios. No arquivo do IBGE…
[1] "CD_MUN" "NM_MUN" "SIGLA" "AREA_KM2" "geometry"
…os nomes dos municípios estão na coluna NM_MUN
. É
preciso verificar se estão grafados da mesma forma que estão na
Wikipedia (neste caso não houve problema). O R Script que
implementa esta abordagem e destaca os municípios em amarelo (RGB
“#F7CB45”) é o seguinte:
Brazil <- rnaturalearth::ne_states(country="Brazil",
returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
municipios <- sf::st_read(file.path("IBGE",
"SP_Municipios_2021.shp"),
quiet=TRUE)
# data frame com os municipios mais populosos
# fonte: https://pt.wikipedia.org/
mun <- c("São Paulo",
"Guarulhos",
"Campinas",
"São Bernardo do Campo",
"São José dos Campos",
"Santo André",
"Ribeirão Preto",
"Osasco",
"Sorocaba")
pop <- c(12396372,
1404694,
1223237,
849874,
737310,
723889,
720116,
701428,
695328)
dtmun <- data.frame(mun,pop)
names(dtmun) <- c("municipio","populacao")
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_sf(data=municipios, fill="transparent", color="#507052", size=0.2)
# adiciona os municipos selecionados ao grafico, em amarelo
for (m in dtmun$municipio)
{
shapemun <- municipios[municipios$NM_MUN==m,]
if(nrow(shapemun)>0)
{
grf <- grf +
ggplot2::geom_sf(data=shapemun, fill="#F7CB45", color="#507052", size=0.2)
} else
{
cat("\nAlerta: municipio ",m," não foi localizado no IBGE.\n")
}
}
print(grf)
demo_ggplot_SaoPaulo03.R
.
Uma outra alternativa é utilizar longitude e latitude das cidades, em vez de desenhar o contorno dos municípios. Para isto é necessário achar estes dados em algum outro lugar.
O IBGE as tem neste link. Há algumas pastas, incluindo
shapefiles, que não explorei porque buscava uma planilha. Não
está facilitado: os dados estão no formato Destes, o mais simples para o R é
Implementado com
demo_read_dbf.R .
Este arquivo, porém, é trabalhoso para arrumar. A coluna que nos
interessa é Neste tipo de situação, é melhor tentar algo mais fácil (deixo esta narreativa para que vejam que nem sempre os dados estão em formato conveniente; sugerimos que somente invista tempo em arrumar este tipo de dado se não houver alternativa). |
Encontrei latitudes e longitudes de todos os munícipiso brasileiros (5565 no total) em formato em Excel na página
https://groups.google.com/g/qgisbrasil/c/0kJDo2KH0is
José Herlânio de Lima solicitou planilha dos municípios brasileiros
ao IBGE, que lhe enviou esta planilha, a qual ele gentilmente compartilhou.
Baixamos esta planilha na mesma pasta onde estão os shapefiles.
A coluna de interesse é NOME_MUNICIPIO
e seu único
inconveniente é que os nomes estão grafados inteiramente em maiúsculas
(o que se resolve com a funcão toupper
— mas não sei se
Windows consegue fazer isto corretamente). O procedimento é:
Warning in readLines("demo_addlonlat.R"): linha final incompleta encontrada em
'demo_addlonlat.R'
path = file.path("IBGE",
"anexo_16261_Coordenadas_Sedes_5565_Municípios_2010.xls")
dtibge <- readxl::read_excel(path)
print(names(dtibge))
# data frame com os municipios mais populosos
# fonte: https://pt.wikipedia.org/
mun <- c("São Paulo",
"Guarulhos",
"Campinas",
"São Bernardo do Campo",
"São José dos Campos",
"Santo André",
"Ribeirão Preto",
"Osasco",
"Sorocaba")
pop <- c(12396372,
1404694,
1223237,
849874,
737310,
723889,
720116,
701428,
695328)
dtmun <- data.frame(mun,pop)
names(dtmun) <- c("municipio","populacao")
# adicionando latitude e longitude
dtmun$lat <- NA
dtmun$lon <- NA
for (m in 1:nrow(dtmun))
{
row <- which(dtibge$NOME_MUNICIPIO==toupper(dtmun$municipio[m]))
if (length(row)>0)
{
if(length(row)>1)
{
cat("\nAlerta: ",dtmun$municipio[m],"aparece em duas localizacoes: ",row,"\n")
}
dtmun$lat[m] <- dtibge$LATITUDE[row]
dtmun$lon[m] <- dtibge$LONGITUDE[row]
} else
{
cat("\nAlerta: municipio ",m," não foi localizado na planilha do IBGE.\n")
}
}
prmatrix(dtmun,quote=FALSE,rowlab=rep("",nrow(dtmun)))
[1] "GEOCODIGO_MUNICIPIO" "NOME_MUNICIPIO" "LONGITUDE"
[4] "LATITUDE"
Alerta: Santo André aparece em duas localizacoes: 1418 3801
Warning in dtmun$lat[m] <- dtibge$LATITUDE[row]: número de itens a substituir
não é um múltiplo do comprimento do substituto
Warning in dtmun$lon[m] <- dtibge$LONGITUDE[row]: número de itens a substituir
não é um múltiplo do comprimento do substituto
municipio populacao lat lon
São Paulo 12396372 -23.567387 -46.57038
Guarulhos 1404694 -23.468506 -46.53108
Campinas 1223237 -22.907343 -47.06016
São Bernardo do Campo 849874 -23.710305 -46.55026
São José dos Campos 737310 -23.184062 -45.88418
Santo André 723889 -7.220489 -36.63098
Ribeirão Preto 720116 -21.184835 -47.80548
Osasco 701428 -23.533612 -46.78881
Sorocaba 695328 -23.499323 -47.45785
demo_addlonlat.R
.
Esta planilha tem um problema grave: existem os munícipios, mas não
consta o Estado. Existem duas cidades chamadas “Santo André”. Podemos
ver que a primeira Santo André encontrada foi tranferida para
dtmun
e esta não é a do Estado de São Paulo.
Para saber qual é a de São Paulo, podemos verificar se suas
coordenadas estão entre as latitudes e longitudes máximas do
shapefile do Estado de São Paulo (armazenado em
SP
.
Uma forma de resolver este problema é utilizar a função
sf::st_bbox
, aceitando apenas as localidades cujas
coordenadas estejam dentro dos limites, como fizemos nesta segunda
versão:
Warning in readLines("demo_addlonlat02.R"): linha final incompleta encontrada
em 'demo_addlonlat02.R'
# shapefile de São Paulo
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
# data frame com os municipios mais populosos
# fonte: https://pt.wikipedia.org/
mun <- c("São Paulo",
"Guarulhos",
"Campinas",
"São Bernardo do Campo",
"São José dos Campos",
"Santo André",
"Ribeirão Preto",
"Osasco",
"Sorocaba")
pop <- c(12396372,
1404694,
1223237,
849874,
737310,
723889,
720116,
701428,
695328)
dtmun <- data.frame(mun,pop)
names(dtmun) <- c("municipio","populacao")
# adicionando latitude e longitude
# coordenadas do IBGE
path = file.path("IBGE",
"anexo_16261_Coordenadas_Sedes_5565_Municípios_2010.xls")
dtibge <- readxl::read_excel(path)
print(names(dtibge))
# pega o boundary box
limites <- sf::st_bbox(SP)
# cria as colunas lat e lon
dtmun$lat <- NA
dtmun$lon <- NA
warnings <- ""
for (m in 1:nrow(dtmun))
{
if(!is.na(dtmun$lat[m])) {next}
row <- which(dtibge$NOME_MUNICIPIO==toupper(dtmun$municipio[m]))
if (length(row)>0)
{
if(length(row)>1)
{
warnings <- paste0(warnings,"\nAlerta: ",dtmun$municipio[m]," aparece em duas localizacoes: ")
for (r in 1:length(row))
{
warnings <- paste0(warnings,row[r]," ")
}
prmatrix(dtibge[row,])
row.org <- row
for (r in 1:length(row.org))
{
# latitude fora da faixa
if (dtibge$LONGITUDE[row.org[r]] < as.numeric(limites[1]) |
dtibge$LONGITUDE[row.org[r]] > as.numeric(limites[3]))
{
row[r] <- NA
}
# longitude fora da faixa
if (dtibge$LATITUDE[row.org[r]] < as.numeric(limites[2]) |
dtibge$LATITUDE[row.org[r]] > as.numeric(limites[4]))
{
row[r] <- NA
}
}
row <- row[!is.na(row)]
if (length(row)==1)
{
warnings <- paste0(warnings,"\n\tcorrigido, escolhida a linha ",row," \n")
} else
{
warnings <- paste0(warnings,"\n\tnao corrigido, ha duas localidades com o mesmo nome em São Paulo: ",row,"\n")
}
}
dtmun$lat[m] <- dtibge$LATITUDE[row]
dtmun$lon[m] <- dtibge$LONGITUDE[row]
} else
{
warnings <- paste0(warnings,"\nAlerta: municipio ",m," não foi localizado na planilha do IBGE.\n")
}
}
cat(warnings)
prmatrix(dtmun,quote=FALSE,rowlab=rep("",nrow(dtmun)))
[1] "GEOCODIGO_MUNICIPIO" "NOME_MUNICIPIO" "LONGITUDE"
[4] "LATITUDE"
GEOCODIGO_MUNICIPIO NOME_MUNICIPIO LONGITUDE LATITUDE
[1,] "2513851" "SANTO ANDRÉ" "-36.63098" " -7.220489"
[2,] "3547809" "SANTO ANDRÉ" "-46.53087" "-23.657510"
Alerta: Santo André aparece em duas localizacoes: 1418 3801
corrigido, escolhida a linha 3801
municipio populacao lat lon
São Paulo 12396372 -23.56739 -46.57038
Guarulhos 1404694 -23.46851 -46.53108
Campinas 1223237 -22.90734 -47.06016
São Bernardo do Campo 849874 -23.71030 -46.55026
São José dos Campos 737310 -23.18406 -45.88418
Santo André 723889 -23.65751 -46.53087
Ribeirão Preto 720116 -21.18483 -47.80548
Osasco 701428 -23.53361 -46.78881
Sorocaba 695328 -23.49932 -47.45785
demo_addlonlat02.R
.
Agora obtivemos as coordenadas corretas, de forma que podemos
colocá-las no mapa (vamos, também, colocar as cidades em ordem
decrescente de população, transformando o município em fator, com a
ordem adequada, para que o ggplot2::ggplot
a utilize),
implementando:
Brazil <- rnaturalearth::ne_states(country="Brazil",
returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
# data frame com os municipios mais populosos
# fonte: https://pt.wikipedia.org/
mun <- c("São Paulo",
"Guarulhos",
"Campinas",
"São Bernardo do Campo",
"São José dos Campos",
"Santo André",
"Ribeirão Preto",
"Osasco",
"Sorocaba")
pop <- c(12396372,
1404694,
1223237,
849874,
737310,
723889,
720116,
701428,
695328)
dtmun <- data.frame(mun,pop)
names(dtmun) <- c("municipio","populacao")
#m ordem decrescente do tamanho da populacao
dtmun <- dtmun[order(dtmun$populacao, decreasing=TRUE),]
# forcando a mesma ordem para municipio ser fator
# (serve para o ggplot utilizar esta ordem)
dtmun$municipio <- factor(dtmun$municipio,
levels=dtmun$municipio)
# adicionando latitude e longitude
# coordenadas do IBGE
path = file.path("IBGE",
"anexo_16261_Coordenadas_Sedes_5565_Municípios_2010.xls")
dtibge <- readxl::read_excel(path)
print(names(dtibge))
# pega o boundary box
limites <- sf::st_bbox(SP)
# cria as colunas lat e lon
dtmun$lat <- NA
dtmun$lon <- NA
for (m in 1:nrow(dtmun))
{
row <- which(dtibge$NOME_MUNICIPIO==toupper(dtmun$municipio[m]))
if (length(row)>0)
{
if(length(row)>1)
{
cat("\nAlerta: ",as.character(dtmun$municipio[m]),"aparece em duas localizacoes: ",row,"\n")
prmatrix(dtibge[row,])
row.org <- row
for (r in 1:length(row.org))
{
# latitude fora da faixa
if (dtibge$LONGITUDE[row.org[r]] < as.numeric(limites[1]) |
dtibge$LONGITUDE[row.org[r]] > as.numeric(limites[3]))
{
row[r] <- NA
}
# longitude fora da faixa
if (dtibge$LATITUDE[row.org[r]] < as.numeric(limites[2]) |
dtibge$LATITUDE[row.org[r]] > as.numeric(limites[4]))
{
row[r] <- NA
}
}
row <- row[!is.na(row)]
if (length(row)==1)
{
cat("\tcorrigido, escolhida a linha ",row,"\n\n")
} else
{
cat("\tnao corrigido, ha duas localidades com o mesmo nome em São Paulo: ",row,"\n\n")
}
}
dtmun$lat[m] <- dtibge$LATITUDE[row]
dtmun$lon[m] <- dtibge$LONGITUDE[row]
} else
{
cat("\nAlerta: municipio ",m," não foi localizado na planilha do IBGE.\n")
}
}
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_point(data=dtmun, ggplot2::aes(x=lon,y=lat,color=municipio))+
ggplot2::labs(x="Longitude",y="Latitude",color="Cidade")
print(grf)
[1] "GEOCODIGO_MUNICIPIO" "NOME_MUNICIPIO" "LONGITUDE"
[4] "LATITUDE"
Alerta: Santo André aparece em duas localizacoes: 1418 3801
GEOCODIGO_MUNICIPIO NOME_MUNICIPIO LONGITUDE LATITUDE
[1,] "2513851" "SANTO ANDRÉ" "-36.63098" " -7.220489"
[2,] "3547809" "SANTO ANDRÉ" "-46.53087" "-23.657510"
corrigido, escolhida a linha 3801
demo_ggplot_SaoPaulo04.R
.
Neste caso as coordenadas foram adicionadas com
ggplot2::geom_point
que utiliza o dataframe que criamos,
dtmun
, informando quais colunas coordenadas para longitude
e latitude, além mudar a cor de acordo com a coluna
dtmun$municipio
. Usamos, também, a função
ggplot2::labs
para nomear os eixos e a legenda.
Podemos localizar o Estado de São Paulo dentro do Brasil, e o Brasil dentro do continente com [demo_ggplot_Brazil.R]:
AmericaSul <- rnaturalearth::ne_countries(continent = "South America", returnclass="sf")
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=AmericaSul, fill="white", color="gray")+
ggplot2::geom_sf(data=Brazil, fill="lightgray", color="gray")+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_point(data=dtmun, ggplot2::aes(x=lon,y=lat,color=municipio))+
ggplot2::labs(x="Longitude",y="Latitude",color="Cidade")
print(grf)
demo_ggplot_Brazil.R
.
Este mapa tem o defeito de fazer a América do Sul, sem a conexão com
a América Central, parecer-se com uma ilha. Há um problema como os dados
estão organizados nos shapefiles de rnaturalearth
.
Observe:
rnaturalearth::ne_countries(returnclass="sf")
dtpaises <- rnaturalearth::ne_countries(returnclass="sf")
cat("\nCampos:\n")
print(names(dtpaises))
cat("\nContinentes:\n")
print(unique(dtpaises$continent))
Campos:
[1] "featurecla" "scalerank" "labelrank" "sovereignt" "sov_a3"
[6] "adm0_dif" "level" "type" "tlc" "admin"
[11] "adm0_a3" "geou_dif" "geounit" "gu_a3" "su_dif"
[16] "subunit" "su_a3" "brk_diff" "name" "name_long"
[21] "brk_a3" "brk_name" "brk_group" "abbrev" "postal"
[26] "formal_en" "formal_fr" "name_ciawf" "note_adm0" "note_brk"
[31] "name_sort" "name_alt" "mapcolor7" "mapcolor8" "mapcolor9"
[36] "mapcolor13" "pop_est" "pop_rank" "pop_year" "gdp_md"
[41] "gdp_year" "economy" "income_grp" "fips_10" "iso_a2"
[46] "iso_a2_eh" "iso_a3" "iso_a3_eh" "iso_n3" "iso_n3_eh"
[51] "un_a3" "wb_a2" "wb_a3" "woe_id" "woe_id_eh"
[56] "woe_note" "adm0_iso" "adm0_diff" "adm0_tlc" "adm0_a3_us"
[61] "adm0_a3_fr" "adm0_a3_ru" "adm0_a3_es" "adm0_a3_cn" "adm0_a3_tw"
[66] "adm0_a3_in" "adm0_a3_np" "adm0_a3_pk" "adm0_a3_de" "adm0_a3_gb"
[71] "adm0_a3_br" "adm0_a3_il" "adm0_a3_ps" "adm0_a3_sa" "adm0_a3_eg"
[76] "adm0_a3_ma" "adm0_a3_pt" "adm0_a3_ar" "adm0_a3_jp" "adm0_a3_ko"
[81] "adm0_a3_vn" "adm0_a3_tr" "adm0_a3_id" "adm0_a3_pl" "adm0_a3_gr"
[86] "adm0_a3_it" "adm0_a3_nl" "adm0_a3_se" "adm0_a3_bd" "adm0_a3_ua"
[91] "adm0_a3_un" "adm0_a3_wb" "continent" "region_un" "subregion"
[96] "region_wb" "name_len" "long_len" "abbrev_len" "tiny"
[101] "homepart" "min_zoom" "min_label" "max_label" "label_x"
[106] "label_y" "ne_id" "wikidataid" "name_ar" "name_bn"
[111] "name_de" "name_en" "name_es" "name_fa" "name_fr"
[116] "name_el" "name_he" "name_hi" "name_hu" "name_id"
[121] "name_it" "name_ja" "name_ko" "name_nl" "name_pl"
[126] "name_pt" "name_ru" "name_sv" "name_tr" "name_uk"
[131] "name_ur" "name_vi" "name_zh" "name_zht" "fclass_iso"
[136] "tlc_diff" "fclass_tlc" "fclass_us" "fclass_fr" "fclass_ru"
[141] "fclass_es" "fclass_cn" "fclass_tw" "fclass_in" "fclass_np"
[146] "fclass_pk" "fclass_de" "fclass_gb" "fclass_br" "fclass_il"
[151] "fclass_ps" "fclass_sa" "fclass_eg" "fclass_ma" "fclass_pt"
[156] "fclass_ar" "fclass_jp" "fclass_ko" "fclass_vn" "fclass_tr"
[161] "fclass_id" "fclass_pl" "fclass_gr" "fclass_it" "fclass_nl"
[166] "fclass_se" "fclass_bd" "fclass_ua" "geometry"
Continentes:
[1] "Oceania" "Africa"
[3] "North America" "Asia"
[5] "South America" "Europe"
[7] "Seven seas (open ocean)" "Antarctica"
demo_naotemCentral.R
.
Não existe “Central America”. Se usarmos a América do Norte fica assim:
AmericaNorte <- rnaturalearth::ne_countries(continent = "North America", returnclass="sf")
AmericaSul <- rnaturalearth::ne_countries(continent = "South America", returnclass="sf")
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=AmericaNorte, fill="white", color="gray")+
ggplot2::geom_sf(data=AmericaSul, fill="white", color="gray")+
ggplot2::geom_sf(data=Brazil, fill="lightgray", color="gray")+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_point(data=dtmun, ggplot2::aes(x=lon,y=lat,color=municipio))+
ggplot2::labs(x="Longitude",y="Latitude",color="Cidade")
print(grf)
demo_ggplot_Brazil02.R
.
Depois de alguma investigação percebe-se que a América do Norte está subdivida em três áreas, sendo “Central America” uma delas, além da América do Norte propriamente dita e o Caribe:
rnaturalearth::ne_countries(returnclass="sf")
dtpaises <- rnaturalearth::ne_countries(returnclass="sf")
cat("\nCampos:\n")
print(names(dtpaises))
cat("\nContinentes:\n")
print(unique(dtpaises$continent))
cat("\nSub regioes:\n")
print(unique(dtpaises$subregion[dtpaises$continent=="North America"]))
Campos:
[1] "featurecla" "scalerank" "labelrank" "sovereignt" "sov_a3"
[6] "adm0_dif" "level" "type" "tlc" "admin"
[11] "adm0_a3" "geou_dif" "geounit" "gu_a3" "su_dif"
[16] "subunit" "su_a3" "brk_diff" "name" "name_long"
[21] "brk_a3" "brk_name" "brk_group" "abbrev" "postal"
[26] "formal_en" "formal_fr" "name_ciawf" "note_adm0" "note_brk"
[31] "name_sort" "name_alt" "mapcolor7" "mapcolor8" "mapcolor9"
[36] "mapcolor13" "pop_est" "pop_rank" "pop_year" "gdp_md"
[41] "gdp_year" "economy" "income_grp" "fips_10" "iso_a2"
[46] "iso_a2_eh" "iso_a3" "iso_a3_eh" "iso_n3" "iso_n3_eh"
[51] "un_a3" "wb_a2" "wb_a3" "woe_id" "woe_id_eh"
[56] "woe_note" "adm0_iso" "adm0_diff" "adm0_tlc" "adm0_a3_us"
[61] "adm0_a3_fr" "adm0_a3_ru" "adm0_a3_es" "adm0_a3_cn" "adm0_a3_tw"
[66] "adm0_a3_in" "adm0_a3_np" "adm0_a3_pk" "adm0_a3_de" "adm0_a3_gb"
[71] "adm0_a3_br" "adm0_a3_il" "adm0_a3_ps" "adm0_a3_sa" "adm0_a3_eg"
[76] "adm0_a3_ma" "adm0_a3_pt" "adm0_a3_ar" "adm0_a3_jp" "adm0_a3_ko"
[81] "adm0_a3_vn" "adm0_a3_tr" "adm0_a3_id" "adm0_a3_pl" "adm0_a3_gr"
[86] "adm0_a3_it" "adm0_a3_nl" "adm0_a3_se" "adm0_a3_bd" "adm0_a3_ua"
[91] "adm0_a3_un" "adm0_a3_wb" "continent" "region_un" "subregion"
[96] "region_wb" "name_len" "long_len" "abbrev_len" "tiny"
[101] "homepart" "min_zoom" "min_label" "max_label" "label_x"
[106] "label_y" "ne_id" "wikidataid" "name_ar" "name_bn"
[111] "name_de" "name_en" "name_es" "name_fa" "name_fr"
[116] "name_el" "name_he" "name_hi" "name_hu" "name_id"
[121] "name_it" "name_ja" "name_ko" "name_nl" "name_pl"
[126] "name_pt" "name_ru" "name_sv" "name_tr" "name_uk"
[131] "name_ur" "name_vi" "name_zh" "name_zht" "fclass_iso"
[136] "tlc_diff" "fclass_tlc" "fclass_us" "fclass_fr" "fclass_ru"
[141] "fclass_es" "fclass_cn" "fclass_tw" "fclass_in" "fclass_np"
[146] "fclass_pk" "fclass_de" "fclass_gb" "fclass_br" "fclass_il"
[151] "fclass_ps" "fclass_sa" "fclass_eg" "fclass_ma" "fclass_pt"
[156] "fclass_ar" "fclass_jp" "fclass_ko" "fclass_vn" "fclass_tr"
[161] "fclass_id" "fclass_pl" "fclass_gr" "fclass_it" "fclass_nl"
[166] "fclass_se" "fclass_bd" "fclass_ua" "geometry"
Continentes:
[1] "Oceania" "Africa"
[3] "North America" "Asia"
[5] "South America" "Europe"
[7] "Seven seas (open ocean)" "Antarctica"
Sub regioes:
[1] "Northern America" "Caribbean" "Central America"
demo_naotemCentral02.R
.
Basta, então, filtrá-la para colocar a imagem:
AmericaNorte <- rnaturalearth::ne_countries(continent = "North America", returnclass="sf")
AmericaCentral <- AmericaNorte[AmericaNorte$subregion=="Central America",]
Caribe <- AmericaNorte[AmericaNorte$subregion=="Caribbean",]
AmericaSul <- rnaturalearth::ne_countries(continent = "South America", returnclass="sf")
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=AmericaCentral, fill="white", color="gray")+
ggplot2::geom_sf(data=Caribe, fill="white", color="gray")+
ggplot2::geom_sf(data=AmericaSul, fill="white", color="gray")+
ggplot2::geom_sf(data=Brazil, fill="lightgray", color="gray")+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_point(data=dtmun, ggplot2::aes(x=lon,y=lat,color=municipio))+
ggplot2::labs(x="Longitude",y="Latitude",color="Cidade")
print(grf)
demo_ggplot_Brazil03.R
.
Outra possibilidade é cortar o gráfico, para aparecer somente o que nos interessa (o Estado de São Paulo e sua vizinhança):
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=Brazil, fill="lightgray", color="gray")+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_point(data=dtmun, ggplot2::aes(x=lon,y=lat,color=municipio))+
ggplot2::labs(x="Longitude",y="Latitude",color="Cidade")+
ggplot2::ylim(-26,-19)+
ggplot2::xlim(-55,-43)
print(grf)
demo_ggplot_Brazil04.R
.
Não satisfeito com o quadriculado em cinza aparecendo ao fundo? Há temas e configurações que podem ser usadas:
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=Brazil, fill="lightgray", color="gray")+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_point(data=dtmun, ggplot2::aes(x=lon,y=lat,color=municipio))+
ggplot2::labs(x="Longitude",y="Latitude",color="Cidade")+
ggplot2::ylim(-26,-19)+
ggplot2::xlim(-55,-43)+
ggplot2::theme_light()+
ggplot2::theme(panel.grid.major = ggplot2::element_line(color = gray(.5),
linetype = 'dashed',
size = 0.2),
panel.grid.minor = ggplot2::element_blank(),
panel.background = ggplot2::element_rect(fill=NA,color = 'black'),
panel.ontop = TRUE)
print(grf)
Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
ℹ Please use the `linewidth` argument instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
generated.
demo_ggplot_Brazil05.R
.
Falta o Oceano. Um pedaço que parece adequado está em MarineRegions.org.
O shapefile foi colocado nem pasta chamada Ocean
e
tem o nome eez_iho.shp. Obtém-se:
Ocean <- sf::st_read(file.path("Ocean","eez_iho.shp"), quiet=TRUE)
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=Ocean, fill="#A0D8D8", color="#A0D8D8")+
ggplot2::geom_sf(data=Brazil, fill="lightgray", color="gray")+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_point(data=dtmun, ggplot2::aes(x=lon,y=lat,color=municipio))+
ggplot2::labs(x="Longitude",y="Latitude",color="Cidade")+
ggplot2::ylim(-26,-19)+
ggplot2::xlim(-55,-43)+
ggplot2::theme_light()+
ggplot2::theme(panel.grid.major = ggplot2::element_line(color = gray(.5),
linetype = 'dashed',
size = 0.2),
panel.grid.minor = ggplot2::element_blank(),
panel.background = ggplot2::element_rect(fill=NA,color = 'black'),
panel.ontop = TRUE)
print(grf)
demo_ggplot_Brazil06.R
.
O área dos círculos pode ser proporcional à população (o município de
São Paulo concentra quase 64% dos habitantes destas nove regiões). Além
disto, podemos controlar as cores das cidades selecionadas (usando
ggplot2::scale_color_manual
), usando uma paleta que
facilita o discernimento para daltônicos. Por exemplo:
source("eiras.friendlycolor.R")
Ocean <- sf::st_read(file.path("Ocean","eez_iho.shp"), quiet=TRUE)
Brazil <- rnaturalearth::ne_states(country="Brazil", returnclass="sf")
SP <- Brazil[Brazil$name_pt=="São Paulo",]
# circle diameters proportional to population
dtmun$pop.perc <- (dtmun$populacao/sum(dtmun$populacao)*100)
# area do circulo é area=pi*(radius^2) -> radius <- (area/pi)^0.5
# diameter = 2 radius
# k se precisar para ajeitar a escala
k <- 0.7
dtmun$diameter <- 2*((dtmun$pop.perc/pi)^0.5)*k
prmatrix(dtmun,quote=FALSE,rowlab=rep("",nrow(dtmun)))
grf <- ggplot2::ggplot()+
ggplot2::geom_sf(data=Ocean, fill="#A0D8D8", color="#A0D8D8")+
ggplot2::geom_sf(data=Brazil, fill="lightgray", color="gray")+
ggplot2::geom_sf(data=SP, fill="#CAE0AB", color="black")+
ggplot2::geom_point(data=dtmun, size=dtmun$diameter[1:nrow(dtmun)],
ggplot2::aes(x=lon,y=lat,color=municipio))+
ggplot2::scale_color_manual(labels = dtmun$municipio,
values = c(eiras.friendlycolor(seq(1,25,by=6)),
eiras.friendlycolor(seq(4,28,by=6)))) +
ggplot2::labs(x="Longitude",y="Latitude",color="Cidade")+
ggplot2::ylim(-26,-19)+
ggplot2::xlim(-55,-43)+
ggplot2::theme_light()+
ggplot2::theme(panel.grid.major = ggplot2::element_line(color = gray(.5),
linetype = 'dashed',
size = 0.2),
panel.grid.minor = ggplot2::element_blank(),
panel.background = ggplot2::element_rect(fill=NA,color = 'black'),
panel.ontop = TRUE)
print(grf)
municipio populacao lat lon pop.perc diameter
São Paulo 12396372 -23.56739 -46.57038 63.727195 6.305441
Guarulhos 1404694 -23.46851 -46.53108 7.221243 2.122556
Campinas 1223237 -22.90734 -47.06016 6.288409 1.980722
São Bernardo do Campo 849874 -23.71030 -46.55026 4.369027 1.650994
São José dos Campos 737310 -23.18406 -45.88418 3.790359 1.537777
Santo André 723889 -23.65751 -46.53087 3.721364 1.523717
Ribeirão Preto 720116 -21.18483 -47.80548 3.701968 1.519740
Osasco 701428 -23.53361 -46.78881 3.605897 1.499891
Sorocaba 695328 -23.49932 -47.45785 3.574538 1.493355
demo_ggplot_Brazil07.R
.
Há vários outros recursos, ainda. Imagine a representação de seus dados como quiser, e encontrará alguém que fez algo similar para adaptar ao seu caso.
Entre outras fontes, o Ministério da Saúde disponibiliza dados de casos e óbitos por COVID-19 no Brasil, estratificados por Unidade da Federação e por Município em https://covid.saude.gov.br/.
Já modificaram o formato do arquivo algumas vezes. Desde o ano
passado é atualizado um arquivo compactado no formato .zip
,
acessível a partir de um botão com o texto Arquivo CSV no canto
superior-direito da página.
Parte da tela de https://covid.saude.gov.br/ (acesso em 21 de junho de 2022).
O arquivo compactado .rar baixado em 21 de junho de 2022
continha cinco arquivos .csv
:
O painel muda, atualizando a situação. Em 31 de maio de 2023 e agosto de 2024 encontramos o seguinte:
Parte da tela de https://covid.saude.gov.br/ (acessos em 31 de maio de 2023 e 29 de agosto de 2024).
O arquivo baixado tem formato .zip e traz subdivisões com o formato:
onde 20XX vai de 2020 a 2024, Partes 1 e 2 correspondem ao primeiro e segundo semestres, e DDmesYYYY é a data da totalização dos dados. Atualmente os dados são apresentados com a soma de ocorrências de cada semana (no momento da pandemia o dado era diário).
Não encontrei documentação alguma sobre a organização dos dados nestes arquivos (e já fizeram mudanças ao longo do tempo) mas, através de um exercício rápido de exploração, é possível entendê-lo. Todos os arquivos têm a mesma estrutura, de forma que podem ser lidos e integrados em um único data frame. Descompactando o arquivo .zip em uma pasta subordinada MS_COVID, a leitura dos dados pode ser feita com:
COVID <- NULL
folder.in <- "MS_COVID"
folder.out <- "COVID2024"
sufixo <- "23ago2024"
year <- 2020
ok <- TRUE
try(dir.create(folder.out),silent=TRUE)
cat("\nReading COVID data:\n")
while(ok)
{
for(p.aux in 1:2)
{
filename <- file.path(folder.in,
paste0("HIST_PAINEL_COVIDBR_",year,
"_Parte", p.aux,"_",sufixo,".csv"))
if(file.exists(filename))
{
dt_tmp <- read.csv2(filename)
if(is.null(COVID))
{
COVID <- dt_tmp
} else
{
COVID <- rbind(COVID,dt_tmp)
}
cat("\n",filename)
} else
{
ok <- FALSE
}
}
year <- year+1
}
rm(dt_tmp)
cat("\nFinished\n")
COVID$datanum <- as.integer(as.Date(COVID$data,origin = "1899-12-30"))+25569
saveRDS(COVID,file.path(folder.out,"COVID.rds"))
Este arquivo tem …
# exibe o nome das colunas
folder.out <- "COVID2024"
COVID <- readRDS(file.path(folder.out,"COVID.rds"))
print(names(COVID))
[1] "regiao" "estado" "municipio"
[4] "coduf" "codmun" "codRegiaoSaude"
[7] "nomeRegiaoSaude" "data" "semanaEpi"
[10] "populacaoTCU2019" "casosAcumulado" "casosNovos"
[13] "obitosAcumulado" "obitosNovos" "Recuperadosnovos"
[16] "emAcompanhamentoNovos" "interior.metropolitana" "datanum"
9053077 linhas
Este número de linhas é explicado porque nem todas as colunas estão preenchidas ao longo do data frame. Por exemplo, observe que região contém “Brasil” em …
1642 linhas
e
datas <- COVID$data[COVID$regiao=="Brasil"]
cat(paste0("Total de datas diferentes: ",length(unique(datas)),
"\nde ",min(datas)," a ",max(datas)))
Total de datas diferentes: 1642
de 2020-02-25 a 2024-08-23
São os 1642 dias de registro da pandemia, iniciando-se em “2020-02-25” e terminando em “2024-08-23”.
O número acumulado de casos e de óbitos podem ser exibidos:
datas <- COVID$data[COVID$regiao=="Brasil"]
datas.num <- as.integer(as.Date(datas,origin = "1899-12-30"))+25569
# strings dos meses e numero correspondente ao dia 1 de cada mes
ano.inicial <- as.numeric(substr(datas[1],1,4))
mes.inicial <- as.numeric(substr(datas[1],6,7))
ano.final <-as.numeric(substr(datas[length(datas)],1,4))
mes.final <- as.numeric(substr(datas[length(datas)],6,7))
label.datas <- c()
label.num <- c()
y.aux <- ano.inicial
m.aux <- mes.inicial-1; if(m.aux<=0){m.aux<-1}
mes.final <- mes.final+1; if(mes.final>12){mes.final<-12}
while (!(y.aux == ano.final & m.aux == mes.final))
{
m.aux <- m.aux+1
if (m.aux>12)
{
m.aux <- 1
y.aux <- y.aux+1
}
label.datas <- c(label.datas,paste0(m.aux,"/",y.aux))
label.num <- c(label.num, as.integer(as.Date(paste0(y.aux,"-",m.aux,"-01"),origin = "1899-12-30"))+25569)
}
# graficos
casos.acm <- COVID$casosAcumulado[COVID$regiao=="Brasil"]
obitos.acm <- COVID$obitosAcumulado[COVID$regiao=="Brasil"]
plot(datas.num, casos.acm,
ylim = c(0,max(casos.acm,na.rm=TRUE)),
xlab="", ylab="Número de casos (acumulado)",
type="l", lwd=2, col="darkblue", axes=FALSE)
axis(1, labels = label.datas, at = label.num, las=2)
axis(2)
plot(datas.num, obitos.acm,
ylim = c(0,max(obitos.acm,na.rm=TRUE)),
xlab="", ylab="Número de óbitos (acumulado)",
type="l", lwd=2, col="darkred", axes=FALSE)
axis(1, labels = label.datas, at = label.num, las=2)
axis(2)
A partir dos dados conta-se 38867008 casos e 712957 mortes no Brasil, os mesmos valores que o painel registra.
Há mais conteúdo nestes dados, pois vimos que há 9053077 linhas no arquivo. Após um processo de tentativa-e-erro vasculhando o banco encontramos…
Regiões encontradas: Brasil Norte Nordeste Sudeste Sul Centro-Oeste
estados <- unique(COVID$estado)
estados <- estados[!is.na(estados)]
estados <- estados[nchar(estados)>0]
cat("Estados encontrados: ",estados," (total de ",length(estados)," estados)\n")
Estados encontrados: RO AC AM RR PA AP TO MA PI CE RN PB PE AL SE BA MG ES RJ SP PR SC RS MS MT GO DF (total de 27 estados)
municipios <- c()
for (e in estados)
{
m <- unique(COVID$municipio[COVID$estado==e])
m <- m[!is.na(m)]
m <- m[nchar(m)>0]
cat("\t",e,": ",length(m)," municipios\n")
municipios <- c(municipios,m)
}
cat("\nTotal de municípios encontrados:",length(municipios),"\n")
RO : 52 municipios
AC : 22 municipios
AM : 62 municipios
RR : 15 municipios
PA : 144 municipios
AP : 16 municipios
TO : 139 municipios
MA : 217 municipios
PI : 224 municipios
CE : 184 municipios
RN : 167 municipios
PB : 223 municipios
PE : 185 municipios
AL : 102 municipios
SE : 75 municipios
BA : 417 municipios
MG : 853 municipios
ES : 78 municipios
RJ : 92 municipios
SP : 645 municipios
PR : 399 municipios
SC : 295 municipios
RS : 497 municipios
MS : 79 municipios
MT : 141 municipios
GO : 246 municipios
DF : 1 municipios
Total de municípios encontrados: 5570
Este banco está organizado com base em regiao
,
estado
e municipio
. O segmento de interesse
pode ser separado combinando-se esses três elementos:
regiao
está preenchida com “Brasil”
(estado
e municipio
em branco), os dados são a
totalização do país.regiao
está preenchida (estado
e
municipio
em branco), os dados são a totalização da
região.regiao
e estado
estão preenchidos
(municipio
em branco), os dados são a totalização do
Estado.estado
e municipio
estão
preenchidos, os dados são a totalização do município.Assim:
total.linhas <- 0
df_brasil <- COVID[COVID$regiao=="Brasil",]
cat("df_brasil: data frame com ",nrow(df_brasil)," linhas\n", sep="")
total.linhas <- total.linhas+nrow(df_brasil)
df_estados <- COVID[COVID$regiao!="Brasil" & nchar(COVID$estado)>0 & nchar(COVID$municipio)==0,]
cat("df_estados: data frame com ",nrow(df_estados)," linhas\n", sep="")
total.linhas <- total.linhas+nrow(df_estados)
estados <- unique(df_estados$estado)
for (idx in 1:length(estados))
{
regiao <- unique(COVID$regiao[COVID$estado==estados[idx]])
df_municipios <- COVID[COVID$regiao==regiao & COVID$estado==estados[idx] & nchar(COVID$municipio)>0,]
cat(estados[idx], " (regiao ",regiao,"): data frame com ",nrow(df_municipios)," linhas, incluindo municipios\n", sep="")
total.linhas <- total.linhas+nrow(df_municipios)
}
cat("\nTotal de linhas aproveitadas do arquivo: ",total.linhas," de ",nrow(COVID),"\n",sep="")
if (total.linhas==nrow(COVID)) {cat("\nTodas as linhas foram encontradas\n")}
df_brasil: data frame com 1642 linhas
df_estados: data frame com 78165 linhas
RO (regiao Norte): data frame com 83772 linhas, incluindo municipios
AC (regiao Norte): data frame com 35442 linhas, incluindo municipios
AM (regiao Norte): data frame com 99882 linhas, incluindo municipios
RR (regiao Norte): data frame com 24165 linhas, incluindo municipios
PA (regiao Norte): data frame com 231984 linhas, incluindo municipios
AP (regiao Norte): data frame com 25776 linhas, incluindo municipios
TO (regiao Norte): data frame com 223929 linhas, incluindo municipios
MA (regiao Nordeste): data frame com 349587 linhas, incluindo municipios
PI (regiao Nordeste): data frame com 360864 linhas, incluindo municipios
CE (regiao Nordeste): data frame com 296424 linhas, incluindo municipios
RN (regiao Nordeste): data frame com 269037 linhas, incluindo municipios
PB (regiao Nordeste): data frame com 359253 linhas, incluindo municipios
PE (regiao Nordeste): data frame com 298035 linhas, incluindo municipios
AL (regiao Nordeste): data frame com 164322 linhas, incluindo municipios
SE (regiao Nordeste): data frame com 120825 linhas, incluindo municipios
BA (regiao Nordeste): data frame com 671787 linhas, incluindo municipios
MG (regiao Sudeste): data frame com 1374183 linhas, incluindo municipios
ES (regiao Sudeste): data frame com 125658 linhas, incluindo municipios
RJ (regiao Sudeste): data frame com 148212 linhas, incluindo municipios
SP (regiao Sudeste): data frame com 1039095 linhas, incluindo municipios
PR (regiao Sul): data frame com 642789 linhas, incluindo municipios
SC (regiao Sul): data frame com 475245 linhas, incluindo municipios
RS (regiao Sul): data frame com 800667 linhas, incluindo municipios
MS (regiao Centro-Oeste): data frame com 127269 linhas, incluindo municipios
MT (regiao Centro-Oeste): data frame com 227151 linhas, incluindo municipios
GO (regiao Centro-Oeste): data frame com 396306 linhas, incluindo municipios
DF (regiao Centro-Oeste): data frame com 1611 linhas, incluindo municipios
Total de linhas aproveitadas do arquivo: 9053077 de 9053077
Todas as linhas foram encontradas
Desta forma pudemos produzir os gráficos da evolução diária de casos
e óbitos e armazenamos os resultados em um PDF, indo até junho de 2023 (os dados
deixaram de ser anotados diariamente para serem atualizados
semanamente). Nesses gráficos, as linhas mais finas correspondem aos
dados e a linha mais grossa é uma curva ajustada:
Criamos uma sequência de imagens para visualizar no mapa a progressão da pandemia no Brasil, colorindo os polígonos que representam as Unidades da Federação. O resultado está em COVID_UF.mp4 (esta é a versão de junho/2022).