SAUDAÇÕES!

Seja bem vindo à página do professor Pedro Albuquerque. Para saber mais sobre meu currículo, disciplinas ministradas e interesses de pesquisa, navegue no menu disponível no topo da página.
Mostrando postagens com marcador ggmap. Mostrar todas as postagens
Mostrando postagens com marcador ggmap. Mostrar todas as postagens

quinta-feira, 15 de dezembro de 2016

Mapas Temáticos usando o R - Parte 2.


Como continuação do post Mapas Temáticos usando o R, mostraremos aqui como é possível unir informações pontuais (Point Process) e dados regionais (Lattice Data) além de unir esses dados com o Google maps.

O primeiro passo é a obtenção da malha (shapefile) e dos dados (DadosMapa.csv) para o processo de georeferenciamento.

O primeiro passo é invocar as bibliotecas necessárias bem como definir o Working Directory no qual o arquivo DadosMapa.csv está e também a pasta Shapes

#Limpa o Working Directory
rm(list=ls())
#Define working directory
setwd("C:\\Blog\\ExemploMapas")
#Invoca os pacotes necessários
library(RColorBrewer)
library(maptools)
library(rgdal)
library(rgeos)
library(RgoogleMaps)
library(sp)
library(spdep)
library(ggmap)
library(plyr)
library(Hmisc)

Em seguida, importamos para o R os dados e a malha de interesse:

#Importa os dados
dados<-read.csv("DadosMapa.csv")
#Lê os shapefiles que estão na pasta Shapes dentro do working directory
sfn <- readOGR("Shapes","11MUE250GC_SIR",verbose = FALSE) 
Uma vez lidos os dados e malhas, é preciso saber qual a região devemos importar do GoogleMaps, para isso fazemos:
#Bounding box a ser utilizada no ggmap
b <- bbox(sfn)
#Cria uma variável ID para o georeferenciamento
sfn@data$id <- rownames(sfn@data)
#Define a projeção (Shapefile)
sfn <- spTransform(sfn, CRS("+proj=longlat +datum=WGS84"))
#Cria um SpatialPointsDataFrame com as latitudes e longitudes dos dados
spdf <- SpatialPointsDataFrame(coords=dados[,c("Longitude","Latitude")], data=dados)
#Define a projeção para os pontos
proj4string(spdf) <-CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0")
#Trasnforma o objeto espacial em um objeto que pode ser lido pelo ggplot2
sfn.df <- fortify(sfn, region="CD_GEOCMU")
#Substring a variável ID para ficar com 6 dígitos (ignora o dígito verificador)
sfn.df$V007<-substr(sfn.df$id,1,6)
#Left Join do CSV com o Shapefile
sfn.df<-merge(sfn.df,dados,by="V007",all.x=T)
#Ordena os dados
sfn.df<-sfn.df[order(sfn.df$order), ] 
Finalmente, após a união dos dados com o Shapefile podemos construir o mapa. Para isso passamos como argumento do ggmap a bounding box obtida nos passos anteriores e definimos também as cores, escalas, títulos do mapa:
#Aumenta ou diminui a Bounding Box (aumenta em 1%)
bbox <- ggmap::make_bbox(sfn.df$long, sfn.df$lat, f = 0.1)
#Escolhe as cores
myPalette <- colorRampPalette(rev(brewer.pal(11, "Spectral")))
#Obtêm o mapa do Google Maps (Existem outras possibilidades...)
map <- get_map(location=bbox, source='google', maptype = 'terrain', color='bw')
#Constrói o mapa:
map <- ggmap(map, base_layer=ggplot(data=sfn.df, aes(x=long, y=lat)), 
             extent = "normal", maprange=FALSE)
map <- map + geom_polygon(data=sfn.df,aes(x = long, y = lat, group = group, fill=Valor), alpha = .6)  
map <- map +   geom_path(aes(x = long, y = lat, group = group),
                         data = sfn.df, colour = "grey50", alpha = .7, size = .4, linetype=2)  
map <- map + coord_equal() 
map <- map + scale_fill_gradientn(colours = myPalette(4))
map<-map+  geom_point(aes(x=Longitude, y=Latitude),color="black", size=1,
                      alpha = 0.70,
                      data=spdf@data)
map<-map +  ggtitle("Postos SINE") +  labs(x="Longitude",y="Latitude") 
#Plota o mapa
plot(map)
Pode-se ainda definir outras bases para o shapefile, alguns exemplos são apresentados a seguir:
##Pode-se trocar o código:
map <- get_map(location=bbox, source='google', maptype = 'terrain', color='bw')
##Do bloco anterior, por algum desses outros:
#map <- get_map(location=bbox, source='osm', color='bw'))
#map <- get_map(location=bbox, source='stamen', color='watercolor'))
#map <- get_map(location=bbox, source='stamen', color='toner'))
#map <- get_map(location=bbox, source='stamen', color='terrain'))
#map <- get_map(location = bbox, source = 'google', maptype = 'terrain')
#map <- get_map(location = bbox, source = 'google', maptype = 'satellite')
#map <- get_map(location = bbox, source = 'google', maptype = 'roadmap')
#map <- get_map(location = bbox, source = 'google', maptype = 'hybrid')

segunda-feira, 15 de agosto de 2016

Mapas Temáticos usando o R.


Mapas Temáticos são muito utilizados na etapa de Análise Espacial Exploratória, a qual tem por principal objetivo apresentar visualmente a existência de algum possível padrão espacial.

O objetivo desse post é apresentar como é possível construir Mapas Temáticos usando o R.

O primeiro passo é a obtenção de uma malha digital. Usualmente, uma malha digital é um conjunto de pelo menos três arquivos com o mesmo nome, mas extensões diferentes (*.dbf,*.shx,*.shp). Essa malha nada mais é do que as delimitações geográficas do mapa de interesse. Por exemplo, suponha que desejamos construir um Mapas Temático para os municípios brasileiros, precisamos então da malha municipal.

O principal repositório de malhas digitais no Brasil é do IBGE. Nesse link (ftp://geoftp.ibge.gov.br/malhas_digitais/) podemos obter as mais diversas malhas digitais. Nesse exercício trabalharemos com a malha municipal de 2005.

O código a seguir lê a malha digital (55mu2500pc) e cria uma outra malha somente com o contorno das Unidades da Federação:

#Limpa o Workspace
rm(list=ls())
#Chama a biblioteca
library(ggplot2)
library(rgdal)
library(plyr)
library(rgeos)
#Carrega o objeto SpatialPolygon
br <- readOGR(dsn = ".", "55mu2500pc", verbose=FALSE)
#Faz o dissolve para as UF's
UF <- gUnaryUnion(br, id = br@data$UF)
UF <- fortify(UF, region="UF")
Em seguida, precisamos obter um conjunto de dados que desejamos plotar no mapa. Esse conjunto deve possuir pelo menos uma variável identificada pelo Código do Município também presente na malha 55mu2500pc. Vamos usar como exercício os dados do IpeaData (basta pesquisar no campo Regional pelo tema "Número de homicídios" ou baixe o arquivo aqui.).
#Lê os dados
all_content <- readLines("ipeadata.csv")
#Pula o nome das colunas
skip_first = all_content[-1]
#Lê os dados
indice<- read.csv2(textConnection(skip_first), header = TRUE, stringsAsFactors = FALSE)
#Transforma o NA em zero
indice[is.na(indice)] <- 0
#Corrige o nome dos municípios enconding
indice[,3]<-iconv(indice[,3], "UTF-8", "LATIN2")
indice<-indice[,-9]
colnames(indice)<-c("Sigla","Codigo","Mun","C2005","C2006","C2007","C2008","C2009")

#Renomeia as colunas
indice$GEOCODIGO<-as.character(indice$Codigo)
#Indice de Criminalodade em 2005
indice$Indice<-indice$C2005/sum(indice$C2005)
#Cria as categorias
indice$Categorias1<-cut(indice$Indice,c(0, 0.25,0.50,0.75,1),
                     labels=c('<0.25','0.25|-0.50','0.50|-0.75','>=0.75'))
#Categorias por quartil
breaks<-c(quantile(indice$Indice, probs = seq(0, 1, by = 0.25)))
breaks[1]<-breaks[2]-1e-5
indice$Categorias2<-cut(indice$Indice, breaks=breaks, 
  labels=c("1º Quartil","2º Quartil","3º Quartil","4º Quartil"),
  include.lowest=TRUE)
Agora é preciso unir os dados com a malha:
#Faz o merge com os dados
br@data$id <- rownames(br@data)
#Caso o código tenha apenas 6 dígitos: br@data$IBGE<-substr(br@data$GEOCODIGO,1,6)
br@data   <- join(br@data, indice, by="GEOCODIGO")
#Cria o objeto para ggplot2
br.df <- fortify(br)
br.df <- join(br.df,br@data, by="id")
Em seguida fazemos o mapa:
#Define as cores do mapa
library(RColorBrewer)
myPalette <- colorRampPalette(brewer.pal(11, "Spectral"))
#Faz o mapa
Map <- ggplot(br.df, aes(long, lat)) + geom_polygon(aes(group = group, fill = Categorias2)) + 
  coord_equal() + labs(x = "Longitude", y = "Latitude", fill = "Criminalidade\nRegional") + 
  ggtitle("Índice:\n Criminalidade Regional") + 
  geom_polygon(data=UF, aes(group=group), alpha=1,colour="black", fill=NA, size=0.5)
Map
Caso deseje fazer o mapa com o valor numérico também é possível usar o argumento scale_fill_gradientn:
#Faz o mapa
Map2 <- ggplot(br.df, aes(long, lat)) + geom_polygon(aes(group = group, fill = Indice)) + 
  coord_equal() + labs(x = "Longitude", y = "Latitude", fill = "Criminalidade\nRegional") + 
  ggtitle("Índice:\n Criminalidade Regional") + 
  scale_fill_gradientn(colours = myPalette(4))+
  geom_polygon(data=UF, aes(group=group), alpha=1,colour="black", fill=NA, size=0.5)
Map2

segunda-feira, 16 de maio de 2016

Geomarketing com Aprendizado de Máquina.


Geomarketing é um campo interessante de pesquisa que objetiva auxiliar os analistas de marketing em suas decisões através do GIS (Geographic Information Systems).

A proposta desse post é apresentar o mesmo processo de modelagem desenvolvido no trabalhos Mercado de comida japonesa no Distrito Federal : análise das oportunidades de negócio por meio de Geomarketing e Máquinas de Suporte Vetorial.

Basicamente, o processe de modelagem envolve os seguintes passos baseados no trabalho de Silva, C.A (2014) [pág. 70]:


O primeiro passo é obter as variáveis de interesse na mesma unidade observacional da malha digital que será utilizada no Geomarketing:

#Limpa o workspace
rm(list=ls())
### Define o  Working Directory
setwd("C:\\Users\\Dados\\POF 2008")
source("LeBasesPosicaoFixa.R")
### Cria um novo arquivo somente com as informações necessárias
# Seleciona tudo: 
fselpr<-function(x) x
#Seleciona somente UF 53: fselpr <- function(x) x[substring(x,3,4)==53]
rcsel.pfix(file.inp="T_MORADOR_S.txt", file.out="MORADOR.txt",
           first=c(3,5,8,9,11,12,60,112),
           last=c(4,7,8,10,11,13,62,127),
           fselpr)
###Lê os dados do arquivo de interesse
dados<-read.table("MORADOR.txt")
###Deleta o arquivo MORADOR.txt
file.remove("MORADOR.txt")
#Coloca os nomes das variáveis
colnames(dados)<-c("COD_UF","NUM_SEQ","NUM_DV","COD_DOMC","NUM_UC","NUM_INFORMANTE",
                   "IDADE_ANOS","RENDA_BRUTA_MONETARIA")
#Coloca os labels nas variáveis
library(Hmisc)
label(dados$COD_UF)<-'CÓDIGO DA UF'
label(dados$NUM_SEQ)<-'NÚMERO SEQUENCIAL'
label(dados$NUM_DV)<-'DV DO SEQUENCIAL'
label(dados$COD_DOMC)<-'NÚMERO DO DOMICÍLIO'
label(dados$NUM_UC)<-'NÚMERO DA UC'
label(dados$NUM_INFORMANTE)<-'NÚMERO DO INFORMANTE'
label(dados$IDADE_ANOS)<-'IDADE CALCULADA EM ANOS'
label(dados$RENDA_BRUTA_MONETARIA)<-'RENDA MONETÁRIA MENSAL DA UC'
describe(dados)
##Lê os dados do arquivo T_DESPESA_INDIVIDUAL_S.txt
rcsel.pfix(file.inp="T_DESPESA_INDIVIDUAL_S.txt", file.out="DESPESA.txt",
           first=c(3,5,8,9,11,12,44,46,53),
           last=c(4,7,8,10,11,13,45,50,63), fselpr)
###Lê os dados do arquivo de interesse
desp<-read.table("DESPESA.txt")
###Deleta o arquivo DESPESA.txt
file.remove("DESPESA.txt")
#Coloca os nomes das variáveis
colnames(desp)<-c("COD_UF","NUM_SEQ","NUM_DV","COD_DOMC","NUM_UC",
                  "NUM_INF","NUM_QUADRO","COD_ITEM","VAL_DESPESA")
#Coloca os labels nas variáveis
label(desp$COD_UF)<-'CÓDIGO DA UF'
label(desp$NUM_SEQ)<-'NÚMERO SEQUENCIAL'
label(desp$NUM_DV)<-'DV DO SEQUENCIAL'
label(desp$COD_DOMC)<-'NÚMERO DO DOMICÍLIO'
label(desp$NUM_UC)<-'NÚMERO DA UC'
label(desp$NUM_INF)<-'NÚMERO DO INFORMANTE'
label(desp$NUM_QUADRO)<-'NÚMERO DO QUADRO'
label(desp$COD_ITEM)<-'CÓDIGO DO ITEM'
label(desp$VAL_DESPESA)<-'VALOR DA DESPESA / AQUISIÇÃO'
O código anterior utiliza as bases da Pesquisa de Orçamentos Familiares de 2008: T_DESPESA_INDIVIDUAL_S.txt e T_MORADOR_S.txt além da função de leitura LeBasesPosicaoFixa.R. Em seguida, as bases de morador e despesas são unidas através do merge entre os dados:
#Mostrar até 8 casas decimais 
options("scipen" = 8)
##Faz o merge entre as bases
#Renomeia a variável NUM_INFORMANTE
colnames(dados)[6]<-"NUM_INF"
#Faz o merge
tudo<-merge(dados,desp,by=c("COD_UF","NUM_SEQ","NUM_DV","COD_DOMC",
                            "NUM_UC","NUM_INF"),all=TRUE)
#Obtêm a base somente com os itens 101 e 102 do quadro 28
ingresso<-tudo[which(tudo$NUM_QUADRO==28&
                       tudo$COD_ITEM%in%c(101,201)),]
As últimas linhas obtêm somente os registros para o gasto com ingressos para cinema e teatro. Esses valores podem ser consultados na documentação da POF 2008. Como os dados de interesse estão por Setor Censitário ou Área de Ponderação, precisamos estudar quais variáveis já existem nessas bases para padronizar com as variáveis da POF. Para isso, é necessário consultar o documento Descrição das variáveis - Microdados da amostra do Censo. Nesse exercício, vamos trabalhar com as variáveis V6036 – Idade calculada em anos e V5070 - Rendimento familiar per capita em julho de 2010 assim a leitura dos dados é feito de maneira similar:
### Cria um novo arquivo somente com as informações necessárias
# Seleciona tudo: 
fselpr<-function(x) x
rcsel.pfix(file.inp="Amostra_Pessoas_53.txt", file.out="CENSO.txt",
           first=c(8,62,406),
           last=c(20,64,413),
           fselpr)
###Lê os dados do arquivo de interesse
censo<-read.table("CENSO.txt")
###Deleta o arquivo CENSO.txt
file.remove("CENSO.txt")
#Coloca os nomes das variáveis
colnames(censo)<-c("CD_APONDE","IDADE_ANOS","RENDA_BRUTA_MONETARIA")
#Arruma a renda pois tem duas casas decimais
censo$RENDA_BRUTA_MONETARIA<-censo$RENDA_BRUTA_MONETARIA/100
Note que o arquivo Amostra_Pessoas_53.txt pode ser obtido diretamente do sítio do IBGE. Nesse exercício não utilizaremos os pesos amostrais fornecidos para que a abordagem seja a mais simples possível, dessa forma, precisamos obter por Área de Ponderação a idade média e a renda média:
#Remove outliers
censo<-censo[which(censo$RENDA_BRUTA_MONETARIA<999999),]
#Calcula a média da idade e renda por área de ponderação:
library(dplyr)
by_pes <- group_by(censo,CD_APONDE)
geo<-summarise(by_pes, 
               IDADE_ANOS=mean(IDADE_ANOS), 
               RENDA_BRUTA_MONETARIA=mean(RENDA_BRUTA_MONETARIA)
               )
Em seguida, precisamos treinar a Máquina de Suporte Vetorial para que reconheça o padrão de consumo médio nas regiões, para isso fazemos:
#Junta os dads com quem incluisve não gatsou com ingresso
#Faz o merge
pof<-merge(dados,ingresso,
           by=c("COD_UF","NUM_SEQ","NUM_DV","COD_DOMC",
                "NUM_UC","NUM_INF"),all=TRUE)
#Quando VAL_DESPESA==NA então não gastou com ingresso
pof$VAL_DESPESA[is.na(pof$VAL_DESPESA)]<-0
#Treina a máquina
library(kernlab)
svm<-ksvm(VAL_DESPESA~IDADE_ANOS.x+RENDA_BRUTA_MONETARIA.x,data=pof,
          C = 1, epsilon = 0.1,type="eps-svr",kernel="rbfdot",
          kpar=list(sigma=4),cross=3)
Aqui novamente por simplicidade, não faremos uma busca exaustiva nos parâmetros ótimos do SVM para tentar manter a abordagem o mais simples possível. Uma vez treinada a máquina, fazemos a previsão do valor gasto com ingressos na base do CENSO:
#Faz a previsão:
colnames(geo)<-c("CD_APONDE","IDADE_ANOS.x","RENDA_BRUTA_MONETARIA.x")
VAL_DESPESA<-predict(svm,geo)
#Junta com a base do CENSo o valor predito
geo<-cbind(geo,VAL_DESPESA)
Pronto!! Apesar do modelo não ter se ajustado muito bem (pois não procuramos pelos parâmetros ótimos e nem utilizamos o peso amostral para ponderar as estatísticas) podemos agora esboçar o mapa com as previsões de gasto com ingressos:
#Baixa a imagem do mapa
library(ggmap)
library(RgoogleMaps)
CenterOfMap <- geocode("Brasilia, DF")
#Pode usar terrain, toner, satellite
BSB <- get_map(c(lon=CenterOfMap$lon, lat=CenterOfMap$lat),zoom = 12, maptype = "satellite", source = "google")
BSB <- ggmap(BSB)
BSB 
#Abre a malha
library(rgdal)
library(rgeos)
library(ggplot2)
library(plyr)
sfn <- readOGR(".","BRASILIA_area_de_ponderacao") 
#Bounding box 
b <- bbox(sfn)
#Junta o mapa com os dados de previsão
sfn@data$id <- rownames(sfn@data)
sfn@data   <- join(sfn@data, geo, by="CD_APONDE")
#Cria a projeção
sfn <- spTransform(sfn, CRS("+proj=longlat +datum=WGS84"))
#Cria o objeto ggplot
sfn.df <- fortify(sfn)
sfn.df     <- join(sfn.df,sfn@data, by="id")
#Faz o mapa
BSB<-BSB + geom_polygon(data = sfn.df, aes(x = long, y = lat, group = group, fill = VAL_DESPESA), 
                        colour = 'grey',  alpha = .4, size = .1) +
  theme(legend.position = "left", title = element_blank())
BSB