Observações: (1). Este documento é destinado a usuários sem conhecimento prévio em programação e é parte integrante do curso de Tópicos Especiais em Geotecnologias, ofertado para o curso de geografia da Universidade Federal Fluminense, campus de Campos dos Goytacazes, no 1º semestre de 2020. Sinta-se livre para divulga-lo desde que referencie o autor do documento original.

(2). Este documento foi preparado para ser desenvolvido no console do R. Entretanto, o uso do RStudio deixa tudo mais organizado e mais simples.

(3). PÁGINA EM CONSTRUÇÃO.

1 Introdução

Os dados do Censo Demográfico são divulgados de várias formas que podem ser consutadas em site do IBGE (2020). Este dodumento está direcionado à leitura e processamento dos dados Agregados por Setores Censitários, referentes ao Censo Demográfico de 2010. O setor censitário é a unidade territorial formado por área contínua, totalmente contida nas áreas clssificadas como urbanas ou rurais, dimensionada com o número de domicílios que permitam o levantamento por um único recenseador (IBGE (2011)). O setor censitário é a menor unidade de análise e de divulgação dos dados de forma georreferenciada e é publicada pelo IBGE a partir de um conjunto planilhas em formato Excel/CSV.

No camonado a seguir os pacotes uados por este documento são carregados:

#Baixa e instala pacote ainda não instalados
list.of.packages <- c("RCurl", "sf","RColorBrewer","ggsn", 'knitr','dplyr','readr','ggplot2','stringr')
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)
#Carrega os pacotes
#library(RCurl) #baixar arquivos
library(sf) #Work with shape files
library(RColorBrewer) #Create color palletes (colorbrewer2.org)
library(ggsn) # Adds north symbols and scale bars im maps created with 'ggplot2' or 'ggmap'
library(readr)
library(ggplot2)
library(stringr)
library(dplyr)

Dica: Material sobre pacotes do R podem ser obtidos, por exemplo, nos links R/Pacotes, 36 Instalando e usando pacotes (packages) do R, R Packages: A Beginner’s Guide, e R - Packages

2 Preparação dos dados

Este documento pressupõe que você criou um projeto no RStudio. Você oode baixar todos os arquivos e descompacta-los rodando os comandos a seguir no console do R. Se decidir rodar os comandos no seu console, tenha paciencia pois provavelmente demorar vários minutos. A sequencia de comandos unzip() descompactam apenas os arquivos que serão usados.

#Dados por setor censitário RJ
download.file('ftp://ftp.ibge.gov.br/Censos/Censo_Demografico_2010/Resultados_do_Universo/Agregados_por_Setores_Censitarios/RJ_20171016.zip','RJ_20171016.zip')
fileslist<-unzip('RJ_20171016.zip',list=T)
fileslist<-c(fileslist$Name[grep('.csv', fileslist$Name)])
unzip('RJ_20171016.zip',exdir='./CSV',files=fileslist,junkpaths=T)

#Documentação arquivo de dados
download.file('ftp://ftp.ibge.gov.br/Censos/Censo_Demografico_2010/Resultados_do_Universo/Agregados_por_Setores_Censitarios/Documentacao_Agregado_dos_Setores_20180416.zip','Documentacao_Agregado_dos_Setores_20180416.zip')
fileslist<-unzip('Documentacao_Agregado_dos_Setores_20180416.zip',list=T)
fileslist<-c(fileslist$Name[grep('Universo', fileslist$Name)])
unzip('Documentacao_Agregado_dos_Setores_20180416.zip',exdir='./',files=fileslist,junkpaths=T)

#Shapes dos setores censitários
download.file('ftp://geoftp.ibge.gov.br/organizacao_do_territorio/malhas_territoriais/malhas_de_setores_censitarios__divisoes_intramunicipais/censo_2010/setores_censitarios_shp/rj/rj_setores_censitarios.zip','rj_setores_censitarios.zip')
fileslist<-unzip('rj_setores_censitarios.zip',list=T)
fileslist<-c(fileslist$Name[grep('33SEE250GC_SIR', fileslist$Name)])
unzip('rj_setores_censitarios.zip',exdir='./SHP',files=fileslist,junkpaths=T)

#Shapes da massa d'água
download.file('ftp://geoftp.ibge.gov.br/cartas_e_mapas/bases_cartograficas_continuas/bc250/versao2019/Shapefile/bc_250_shapefile_06_11_2019.zip','bc_250_shapefile_06_11_2019.zip')
fileslist<-unzip('bc250_shapefile_06_11_2019.zip',list=T)
fileslist<-c(fileslist$Name[grep('hid_massa_dagua_a', fileslist$Name)])
unzip('bc250_shapefile_06_11_2019.zip',exdir='./SHP',files=fileslist,junkpaths=T)

Uma outra alternativa (e preferível na minha opinião) é baixar diretamente os arquivos do IBGE e descompacta-los na sua pasta raiz.

  1. As planilhas foram divulgadas com um conjunto de 26 planilhas. Para o Rio de Janeiro, baixe o arquivo RJ_20171016 aqui. Os números se referem à data da última atualização: 16/07/2017. Uma pasta de nome CSV foi criada no pasta raiz do projeto e apenas as planilhas no formato CSV foram salvas descompacatas nessa pasta. Estes arquivos foram disponibilizados nessa pasta do Google Drive.

  2. O arquivo de documentação necessário para a compreensão das planilas (Documentacao Agregado dos Setores). Este arquivo é muito importante. Este arquivo foi salvo na pasta raiz do projeto e disponibilizado nessa pasta do Google Drive.

  3. Malha digital dos setores censitários. É uma shape para cada undiade da federação e para o estado do Rio de Janeiro baixe o arquivo shape aqui. Os arquivos que compõem a shape do estado do Rio de Janerio foram salvos na pasta ./SHP/ e disponibilizados nessa pasta do Google Drive. O IBGE também disponibiliza essa malha digital no formato kmz.

  4. Shape com as massas d’água. É uma shape para o país todo e o arquivo zipado contém inúmeras shpaes sobre a vesão de 2015 da "Base cartográfica Contínua na escala 1:250.000 do IBGE. Essa escala é compatível com a grade setores censitários (ou, pelo menos, deveria ser) e os arquivos dessa shape foram salvos na pasta ./SHP/ do projeto. A base completa pode ser baixada no link ou nessa pasta do Google Drive.

Dica: Os arquivos foram descompactados no R e por isso os diretórios utilizados usam o padrão adotado dos códigos apresentados no script acima. Outros programas de descompactação (WinZip, por exemplo), criam suas próprias pastas, que podem não ter caminhos iguais aos apresentados no decorrer deste documento. Como dito anteriormente, os arquivos a serem utilizado foram salvos em pastas específicas do diretório de trabalho (pasta raiz ./, pasta SHP e pasta CSV).

2.1 Incialização dos objetos

Obviamente, a primeira tarefa para qualquer processamento de dados é ler estes dados e convertê-los em objetos compatíveis com o R. Na sequencia são apresentados comandos para (1) leitura do banco de dados dos setores censitários; (2) leitura das shapes dos setores censitários e (3) leitura da shape das massas d’água.

2.1.1 Dataframe (df) contendo dados por setores censitários contidos no 1º subdistrito de Campos dos Goytacazes

O comando read_csv2, do pacote readr, lê arquivos em formato .csv que tenham o ponto e vírgula como separador (;) e retorna um dataframe (df). A sequencia de comandos a seguir incialmente le o arqvivo Basico_RJ.csv que estaria no diretório ./CSV/ e o grava no objeto RJ.df. Na sequencia, o dataframe SD1Campos.df é gerado para conter apenas as informações dos setores censitários do primeiro subdistrito de Campos.

Dica: A variável Cod_setor contém o um código único para os setores censitários, denominado pelo IBGE de Geocódigo. Um geocódigo é sempre formado pela recomposição da hierarquia político-administrativa que a unidade territorial faz parte. No caso do geocógico do setor censitario os dois primeiros dígitos se referem ao código do estado (33=Rio de Janeiro); os cinco subsequentes se relacionam ao município (01009=Campos dos Goytacazes); os dois seguintes indicam o distrito (05=Sede do município); os dois na sequência apontam o subdistrito (06=primeiro subdistrito); e, por fim, os cinco últimos ao setor censitário (33+01009+05+06+SSSSSS). Para saber mais sobre a construção deste geocódigo consulte o link. No caso da relação de igualdade que seleciona as linhas do dataframe RJ.df, foram selecionados apenas os setores contidos no primeiro subdistrito do distrito sede de Campos (Cod do Subdistrito == 33…01009…05…06).

RJ.df<-read_csv2('CSV/Basico_RJ.csv',locale=locale(encoding = "latin1")) #Dados do Censo 2010 por Setor Censitário (RJ)
SD06Campos.df <- RJ.df %>%
  mutate(CD_SUBDIST=as.character(Cod_subdistrito))%>%
  filter(CD_SUBDIST=='33010090506')

2.1.2 Simple Feature (sf) contendo os setores censitários do 1º subdistrito de Campos dos Goytacazes

A sequencia de comandos a seguir inicialmente lê a shape 33SEE250GC_SIR.shp que estaria no diretório ./SHP/, a grava no objeto RJ.sf. O comando st_read é parte do pacote sf (Simple Feature for R) e traduz shapes comuns em objetos da classe simple feature (sf). Objetos sf são mapas vetoriais no ambiente do R e que podem ser impressos por uma sequencia de comandos do ggplot. Na sequencia, o dataframe SD06Campos.sf, que contém apenas as informações dos setores censitários do primeiro subdistrito da cidade de Campos (geocodigo = 06). O comando ggplot desenha o mapa que foi gerado.

RJ.sf<-st_read('SHP/33SEE250GC_SIR.shp') #Sf dos setores censitário RJ
## Reading layer `33SEE250GC_SIR' from data source `/Volumes/GoogleDrive/Meu Drive/TEGeotec/ASC2010_RJ/SHP/33SEE250GC_SIR.shp' using driver `ESRI Shapefile'
## Simple feature collection with 28318 features and 13 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -44.88932 ymin: -23.36893 xmax: -40.95852 ymax: -20.76321
## geographic CRS: SIRGAS 2000
SD06Campos.sf <- RJ.sf %>%
  filter(CD_GEOCODS=="33010090506") #Sf dos setores censitários 1º Subdistrito de Campos
ggplot(data=SD06Campos.sf)+
  geom_sf(fill='lightsalmon1',col='grey10',lwd=.1) #Desenha um mapa com os setores censitários do 1º subdistrito de Campos

Dica: Se quiser alterar as cores, busque por imagens no Google com os termos named colors in r e se divirta.

2.1.3 Simple Feature (sf) das massas d’água contidas nos limites cartográficos do 1º subdistrito de Campos dos Goytacazes

A leitura da shape da massa d’água do Brasil também é feita pelo comando st_read. Entretanto o objeto massa_Brasil.sf é muito grande (462 mil entidades) e consome muito tempo de computação para ser desenhada na janela de gráficos do R. Uma opção é cortar (crop) essa shape para que ela tenha apenas as massas líquidas contidas em um retângulo cuja coordenadas coincidam com as coordenadas limites do shape do 1º Subdistrito de Campos. Os comandos a seguir executam o seguinte algoritmo

  1. lê a shape da massa d’água do Brasil (massa_Brasil.sf);
  2. cria um objeto Bounding Box chamado bb dos limites cartográfico de SD06Campos.sf;
  3. transforma o objeto bb, da classe Boundig Box para um vetor simples (evita eventuais diferenças nos nomes das projeções cartográficas);
  4. cria o objeto massa_1SDCampos.sf cortando (comando st_crop) a massa d’água do Brasil todo (massa_Brasil.sf), e;
  5. desenha o objeto massa_1SDCampos.sf na cor azul O objeto massa_SD06Campos.sf, criado ao fim desse algoritmo, é um sf contendo apenas as 26 massas líquidas dentro dos limites definidos territoriais do simple feature SD1Campos.sf (escala 1:250.000).
massa_Brasil.sf<-st_read('SHP/hid_massa_dagua_a.shp') #1. Lê a shape das massas d'água do Brasil
## Reading layer `hid_massa_dagua_a' from data source `/Volumes/GoogleDrive/Meu Drive/TEGeotec/ASC2010_RJ/SHP/hid_massa_dagua_a.shp' using driver `ESRI Shapefile'
## Simple feature collection with 46285 features and 8 fields
## geometry type:  MULTIPOLYGON
## dimension:      XY
## bbox:           xmin: -72.85706 ymin: -38.02726 xmax: -24.89737 ymax: 9.053134
## geographic CRS: SIRGAS 2000
bb<-st_bbox(SD06Campos.sf) #2. Caixa (Bounding Box) com os limites dos setores do 1º Subdistrito de Campos
bb<-c(bb$xmin,bb$ymin,bb$xmax,bb$ymax) #3. Simplifica o objeto bb, da classe Boundig Box, em um vetor
massa_SD06Campos.sf<-st_crop(massa_Brasil.sf,bb) #4. Corta a sf massa_Brasil a simple feature SD06Campos.sf
ggplot(data=massa_SD06Campos.sf)+
  geom_sf(fill='blue',col='darkblue',lwd=.1) #5. Desenha SD06Campos.sf

Dica: Nunca se esqueça das coordenadas de origem dos mapas que você está trabalhando. Para maiores informações sobre conversões de sistemas de coordenadas ou manipulação de objetos de mapas vetoriais consulte a documentação dos pacotes rgdal e sf.

2.2 Unindo a Simple Feature com o Dataframe

O comando merge une dois dataframes ou, neste caso, um dataframe (SD06Campos.df) com um simple feature (SD06Campos.sf) a partir de uma variável de indentificação (o geocodigo do setor censitário). No caso deste exercício e é desejável e esperado que os dois objetos tenham extamente a mesma quantidade de linhas (o mesmo número de setores censitários).

A sequencia de comando a seguir confirma que

  1. os objetos tem o mesmo número de linhas (95, contadas pelo comnandolength(x));
  2. os dois oobetjos não possuem setores duplicados (any(duplicated(x)) retorna FALSE);
  3. todos os objetos de um estão contidos no outro (all(x %in% y) retorna TRUE), e;
  4. faz a união entre os dois objetos (comando inner_join do pacote dplyr)
  5. Desenha os setores colorindo-os de acordo com o nível da renda
#1. Qual o tamanho dos objetos?
length(SD06Campos.sf$CD_GEOCODI)
## [1] 95
length(SD06Campos.df$Cod_setor)
## [1] 95
#2. Tem setores duplicados nos objetos sf e dataframe?
any(duplicated(SD06Campos.sf$CD_GEOCODI))
## [1] FALSE
any(duplicated(SD06Campos.df$Cod_setor))
## [1] FALSE
#3. Todos os setores do objeto Basico_1SDCampos (df) estão no Setores_1SDCampos (sf)?
all(SD06Campos.df$Cod_setor %in% SD06Campos.sf$CD_GEOCODI)
## [1] TRUE
#4. Merge
#Cria um campo chamado CD_GEOCODI no df do tipo caracter
SD06Campos.df<-SD06Campos.df%>%
  mutate(CD_GEOCODI=as.character(Cod_setor))
#inner_join
SD06Campos_merged.sf<-SD06Campos.sf %>%
  inner_join(SD06Campos.df,by=c('CD_GEOCODI'='CD_GEOCODI'))

#5. ggplot
ggplot(data=SD06Campos_merged.sf)+
  geom_sf(aes(fill=V005),col='grey70',lwd=.1) +
  scale_fill_gradientn(colors=brewer.pal(7,'Greens')) #5. Desenha SD06Campos.sf

Neste ponto uma observação é importante: tenha em mente que, nem sempre o total de linhas de um ojeto será igual a do outro. Nõa faz sentido, por exemplo, unir uma sf dos municípios do Brasil com o dataframe dos setores censitários do Rio de Janeiro. Ou seja, antes de unir dois objetos (independente da classe) é importante ter certeza que a união resultante será aquilo que você procura:

x tem o mesmo número de linhas que y (1 para 1)? ou

x tem mais linhas que y (muitos para um); ou

x tem menos linhas que y (um para muitos)?

No caso deste exemplo é desejável que a relação seja 1 para 1. Mas, em várias ocasiões nota-se erros nos dados. Ou, em outras palavras, grandes setores censitários não tem população alguma (grandes áreas de mineradoras, por exemplo). Ou, também, setores censitarios contêm apenas domicílios coletivos, sem declaração de renda (presídios, por exemplo). Vários outros motivos podem ser listados: aldeias indígenas, cemitérios, quartéis, dentre outros que podem não aparecer na tabela de dados (o df) por motivos variados. A união, em alguns casos, pode nem fazer sentido. Ou, em outros casos, variáveis numéricas (da renda, por exemplo) podem ser nulas NA. A última seção deste documento sugere uma forma de contornar estas questões mas é dispensável para fazer o restante do tutorial.

3 Dsenhando o mapa

3.1 Ggplot para o desenho de mapas

Neste ponto, praticamente todos os objetos necessários para nosso mapa já estão no ambiente do R. Para dar continuidade no mapeamento basta ir somando as layers ao comando ggplot, como a seguir.

ggplot(data=SD06Campos_merged.sf)+
  geom_sf(aes(fill=V005),col='grey80',lwd=.3)+
  scale_fill_gradientn(colors=brewer.pal(7,'Greens'))+
  geom_sf(data=massa_SD06Campos.sf,col="darkblue",fill='blue')

Entretanto, seria interessante acrescentar outros elementos ao gráfico (escala, simbolo de norte, nome de bairros, etc.). As seções a seguir tratam disto.

3.2 Nomes de bairros

O primeiro ponto seria acrescentar os nomes dos bairros aos mapas. Tanto o sf quando o df possuem uma variáveis com os nomes dos bairros. Neste exercecício vamos utilizar um comando que dissolve os setores censitários de acordo com o bairro que pertencem. Para isso é utilizado o comando st_dissolve. Após o comando dissove é acrescentada a geometria geom_sf com os limites dos bairros e geom_sf_label com os nomes dos bairros. Uma função (abrev) foi criada para abreviar os nomes dos bairros e, para funcionar, é necessário baixar o arquivo abreviaturas.csv disponível do Google Drive.

#Função para Resumir Toponímias
  Abreviaturas <- read_csv2('Abreviaturas.csv')
  abrev<- function(x,enc="latin1") {
    Encoding(x)<-enc
    y<-x
    for(i in 1:dim(Abreviaturas)[1]) {
      y<-str_replace(y,Abreviaturas$Nome[i],Abreviaturas$Abr_Down[i])
    }
    y
  }


#1. 'Dissolve' a sf de setores em relação aos nos dos bairros.
bairros.sf<-SD06Campos.sf %>%
  group_by(CD_GEOCODB,NM_BAIRRO) %>%
  summarize()%>%
  ungroup()

#1.1 Resumindo os nomes dos bairros
  bairros.sf$RES_NM_BAIRRO<-abrev(bairros.sf$NM_BAIRRO)
  # bairros.sf$RES_NM_BAIRRO<-bairros.sf$NM_BAIRRO

#2. Nomes dos bairros
ggplot(data=SD06Campos_merged.sf)+
  geom_sf(aes(fill=V005),col='grey80',lwd=.3)+
  scale_fill_gradientn(colors=brewer.pal(7,'Greens'))+
  geom_sf(data=massa_SD06Campos.sf,col="darkblue",fill='blue')+
  geom_sf(data=bairros.sf,col="grey50",fill=NA,lwd=.5)+
  geom_sf_text(data=bairros.sf,aes(label=RES_NM_BAIRRO),size=3)

3.3 Para excluir setores que podem não nos interessar

Entretanto, percebam a confusão do mapa: nomes muito grandes e o poucos bairros que estão nomeados estão na área central. Para contornar este problema de visualização, uma opção, este caso, é excluir todos as áreas que nào estão dentreo da área central. Adiconalmente, o desenho é muito alongado e, mesmo selecionando o 1º Subdistrito, existem setores muito grandes, sem toponímia de bairros. A tabela de frequencia a seguir sugere que 24 setores não estão localizados em regiões que tem nome de bairros atribuidos que receberam o nome genérico CAMPOS DOS GOYTACAZES (demais setores) e o código 3301009000.

head(table(SD06Campos.df$Nome_do_bairro))
## 
##                                   Caju CAMPOS DOS GOYTACAZES (demais setores) 
##                                      7                                     24 
##                Jardim Maria de Queiroz                  Parque Alberto Torres 
##                                      2                                      4 
##                 Parque Avenida Pelinca        Parque Conselheiro Tomaz Coelho 
##                                      5                                      6
 head(table(SD06Campos.df$Cod_bairro))
## 
## 3301009000 3301009002 3301009003 3301009004 3301009005 3301009006 
##         24          5          6          1          4          5

No algoritmo a seguir, vamos excluir os setores com bairros sem nomes e gerar o mapa novamente.

#1. Exclui bairros com o nome 'CAMPOS DOS GOYTACAZES (demais setores)' e cria o objeto xyy_SohCentro_merged.sf
SD06Campos_SohCentro_merged.sf <- SD06Campos_merged.sf[SD06Campos_merged.sf$Cod_bairro!="3301009000",]

#2. Recorta a massa d'água do 1º subdistrito para o objeto sf para a massa d'ágda só da área central do 1º Subdistrito de Campos
bb<-st_bbox(SD06Campos_SohCentro_merged.sf) #2. Caixa (Bounding Box) com os limites de SD06Campos_SohCentro_merged.sf
bb<-c(bb$xmin,bb$ymin,bb$xmax,bb$ymax) #3. Simplifica o objeto bb, da classe Boundig Box, em um vetor simples
massa_SD06Campos_SohCentro.sf<-st_crop(massa_SD06Campos.sf,bb) #4. Corta a sf massa_Brasil a simple featura SD06Campos.sf

#3. 'Dissolve' a sf de setores para criar uma shape de bairros.
bairros_SohCentro.sf<-SD06Campos_SohCentro_merged.sf %>%
  group_by(CD_GEOCODB,NM_BAIRRO) %>%
  summarize()%>%
  ungroup()

#4. Resume os nomes dos bairros
bairros_SohCentro.sf$RES_NM_BAIRRO<-abrev(bairros_SohCentro.sf$NM_BAIRRO)

ggplot(data=SD06Campos_SohCentro_merged.sf)+
  geom_sf(aes(fill=V005),col='grey80',lwd=.3)+
  scale_fill_gradientn(colors=brewer.pal(7,'Greens'))+
  geom_sf(data=bairros_SohCentro.sf,col="grey50",fill=NA,lwd=.5)+
  geom_sf(data=massa_SD06Campos_SohCentro.sf,col="darkblue",fill='blue')+
  geom_sf_text(data=bairros_SohCentro.sf,aes(label=RES_NM_BAIRRO),size=1.5)

3.4 Outras perfumarias

O pacote ggsnacrescenta simbolo de norte e barras de escalas nos mapas. Ele funciona com o ggplot e é somando ao comando como se fosse uma layer. Para evitar de ficar digitando o comando do gráfico toda vez, salve o gráfico em uma variável (neste caso m) e some os demais comandos a ela, como apresentado nos algoritmos a seguir.

m<-ggplot(data=SD06Campos_SohCentro_merged.sf)+
  geom_sf(aes(fill=V005),col='grey80',lwd=.3)+
  scale_fill_gradientn(colors=brewer.pal(7,'Greens'))+
  geom_sf(data=massa_SD06Campos_SohCentro.sf,col="darkblue",fill='blue')+
  geom_sf_text(data=bairros_SohCentro.sf,aes(label=RES_NM_BAIRRO),size=1.5)

m + north(data=bairros_SohCentro.sf, symbol=1) +
    scalebar(data=bairros_SohCentro.sf,
             transform = T, model='WGS84', dist_unit = 'm',dist=500) # comandos necessários à conversão de coordenadas

Para ajudar a escala:

m + north(data=bairros_SohCentro.sf, symbol=1) +
    scalebar(data=bairros_SohCentro.sf,                 #Base de dados de referencia
         transform = T,model='WGS84',               #Conversão de coordenadas Geográficas em UTM
         dist_unit = 'm',dist=500,                  #Tamanho de cada barra da escala também usada na conversão
         location='bottomleft',                     #Localização do simbolo de escala
         height=.01,st.size = 4,border.size = .1)   #Tamanho do simbolo de escala (proporcional ao gráfico)

4 Apeêndice: E se a simple feature tem mais setores censitários que o dataframe?

A sequencia de comandos a seguir sugere formas de contornar casos qem que simple feature tem mais setores censitários que o dataframe, procurando por setores que estariam em um banco de dados e não no outro. Uma solução adotada aqui é acrescentar com setores faltantes ou excluir setores em excesso. No caso a seguir é criada uma sf (SD06Campos_sf_NOTin_df.sf ) que contém os setores que estão no sf e não estão listados no df. Para o exemplo deste exercício, o objeto ``SD06Campos_sf_NOTin_df.sf``` ficou com zero linhas, uma vez que o número de linhas são iguais nos dois objetos que foram unidos. Mas, isso não pode ser verdadeiro em outros subdistritos: algumas áreas de usinas de cana-de-açucar são setores censitários sem população que aprecem na sf mas não aparecem no df. *Este é um coteúdo adicional e não interefere a compreensão de todo

#Cria um comando chamado de %NOTin%  que é o oposto ao %in%. Algo do tipo, 'Tudo que não está listado em...'
`%NOTin%` <- Negate(`%in%`)

#sf com setores que estão no sf mas não estão no df
SD06Campos_sf_NOTin_df.sf<-
  SD06Campos.sf[SD06Campos.sf$CD_GEOCODI %in% 
                  SD06Campos.sf$CD_GEOCODI[
                    SD06Campos.sf$CD_GEOCODI %NOTin% SD06Campos.df$Cod_setor],
                ]

Afinal, para que serve o sf xxyyCampos_sf_NOTin_df.sf? No caso deste execício, ele não tem função alguma. Mas se o mesmo exercício fosse executado para tada a área urbana da sede (Distrito=05) o resultado seria outro. Existem 4 setores na sf (no mapa) que não estão no df (nos dados). Tente entender a sequencia de comandos a seguir.

DD05Campos.df <- RJ.df %>%
  filter(Cod_distrito=="330100905") %>% #Dados do Censo 2010 por Setor Censitário (Sede de Campos)
  mutate(CD_GEOCODD=as.character(Cod_distrito))
DD05Campos.sf <- RJ.sf %>%
  filter(CD_GEOCODD=="330100905") #Sf dos setores censitários para toda a sede de (Sede de Campos)

bb<-st_bbox(DD05Campos.sf) #2. Caixa (Bounding Box) com os limites dos setores do 2º Subdistrito de Campos
bb<-c(bb$xmin,bb$ymin,bb$xmax,bb$ymax) #3. Simplifica o objeto bb, da classe Boundig Box, em um vetor
massa_DD05Campos.sf<-st_crop(massa_Brasil.sf,bb) #4. Corta a sf massa_Brasil a simple feature SD07Campos.sf

#Shape com os limites dos Subdistritos
Subdistritos.sf<-DD05Campos.sf %>%
  group_by(CD_GEOCODS,NM_SUBDIST) %>%
  summarize() %>%
  ungroup()

#1. Qual o tamanho dos objetos?
length(DD05Campos.sf$CD_GEOCODI)
## [1] 485
length(DD05Campos.df$Cod_setor)
## [1] 481
#2. Tem setores duplicados nos objetos sf e dataframe?
any(duplicated(DD05Campos.sf$CD_GEOCODI))
## [1] FALSE
any(duplicated(DD05Campos.df$Cod_setor))
## [1] FALSE
#3. Todos os setores do objeto Basico_1SDCampos (df) estão no Setores_1SDCampos (sf)?
all(DD05Campos.df$Cod_setor %in% DD05Campos.sf$CD_GEOCODI)
## [1] TRUE
#4. Merge
DD05Campos_merged.sf<-merge(DD05Campos.sf,DD05Campos.df,by.x='CD_GEOCODI',by.y='Cod_setor')
#4.1 Qual o tamanho do sf depois do merge?
length(DD05Campos_merged.sf$CD_GEOCODI)
## [1] 481
## 480 setores. O DD05Campos.sf tinha 485, ou seja, cinco setores não estão na tabela mergeada. Ou seja, vão ficar buracos no mapa...

#Desenhando o mapa sem SD07Campos_sf_NOTin_df.sf
#   Usei um tema mais escuro para destacar os setores que sumiram
ggplot(data=DD05Campos_merged.sf)+
  geom_sf(aes(fill=V005),col='grey80',lwd=.1)+
  scale_fill_gradientn(colors=brewer.pal(7,'Greens'))+
  geom_sf(data=massa_DD05Campos.sf,col="darkblue",fill='blue')+
  geom_sf(data=Subdistritos.sf,col="grey50",fill=NA,lwd=.5)+
  geom_sf_text(data=Subdistritos.sf,aes(label=NM_SUBDIST),size=3)+
  theme_dark()

# Dando um zoom
ggplot(data=DD05Campos_merged.sf)+
  geom_sf(aes(fill=V005),col='grey80',lwd=.1)+
  scale_fill_gradientn(colors=brewer.pal(7,'Greens'))+
  geom_sf(data=massa_DD05Campos.sf,col="darkblue",fill='blue')+
  geom_sf(data=Subdistritos.sf,col="black",fill=NA,lwd=.3)+
  geom_sf_text(data=Subdistritos.sf,aes(label=NM_SUBDIST),size=3)+
  coord_sf(xlim = c(-41.34,-41.26), ylim = c(-21.79, -21.73))+
  theme_dark()

Observe que surgem alguns setores ‘cinzas’ no mapa. Parte deles são consequencia de erros no mapeamento do IBGE que deixa linhas pretas de limite sobrando após o comando st_dissolve. Outros são quatro setores que estão no sf e não estão no sf. O objeto DD05Campos_sf_NOTin_df.sf criado na sequencia isola tem esses quatro setores.

#sf com setores que estão no sf mas não estão no df
`%NOTin%` <- Negate(`%in%`)
DD05Campos_sf_NOTin_df.sf<-DD05Campos.sf[
  DD05Campos.sf$CD_GEOCODI %in%
    DD05Campos.sf$CD_GEOCODI[DD05Campos.sf$CD_GEOCODI %NOTin% DD05Campos.df$Cod_setor],]

Para mapear esses quatro setores, basta acrescentar a layer ao comando ggplot, como a seguir

#Desenhando o mapa com SD07Campos_sf_NOTin_df.sf
#  Um 'x' foi acrescentado nas cordenadas do setores sem dados
#  Foi usado o tema light para deixar o mapa mais 'light'
m<-ggplot(data=DD05Campos_merged.sf)+
  geom_sf(aes(fill=V005),col='grey80',lwd=.1)+
  scale_fill_gradientn(colors=brewer.pal(7,'Greens'))+
  geom_sf(data=massa_DD05Campos.sf,col="darkblue",fill='blue')+
  geom_sf(data=Subdistritos.sf,col="grey50",fill=NA,lwd=.5)+
  geom_sf_text(data=Subdistritos.sf,aes(label=NM_SUBDIST),size=3)+
  geom_sf(data=DD05Campos_sf_NOTin_df.sf,col="red",fill='darkred')+
  north(data=bairros_SohCentro.sf, symbol=1) +
  scalebar(data=bairros_SohCentro.sf,                 #Base de dados de referencia
           transform = T,model='WGS84',               #Conversão de coordenadas Geográficas em UTM
           dist_unit = 'km',dist=0.5,                  #Tamanho de cada barra da escala também usada na conversão
           location='bottomleft',                     #Localização do simbolo de escala
           height=.01,st.size = 4,border.size = .1)   #Tamanho do simbolo de escala (proporcional ao gráfico)

z<-coord_sf(xlim = c(-41.34,-41.26), ylim = c(-21.79, -21.73))

t<-theme_light()
m+z+t

References

IBGE. 2011. “Base de informações do Censo Demográfico 2010. Resultados do Universo por setor censitário. Documentação do Arquivo Sumário.” Rio de Janeiro: IBGE. ftp://ftp.ibge.gov.br/Censos/Censo{\_}Demografico{\_}2010/Resultados{\_}do{\_}Universo/Agregados{\_}por{\_}Setores{\_}Censitarios/.