Introdução
Indicadores de transações imobiliárias em Juiz de Fora/MG podem ser elaborados a partir de dados do ITBI (Imposto sobre Transmissão de Bens Imóveis) disponibilizados pela Prefeitura Municipal.
O acesso a essas estatísticas e indicadores pode auxiliar os agentes do mercado na tomada de decisões.
Atualmente, a base de dados é limitada, pois inclui apenas transações dos dois últimos exercícios fiscais encerrados, o que dificulta a produção de estimativas amplamente representativas.
Espera-se que a divulgação dessas informações seja mantida nos próximos anos, permitindo a criação de uma base de dados mais robusta.
Objetivo
Inspirados no projeto da FIPE, buscamos desenvolver indicadores imobiliários que possam contribuir para o fortalecimento do ambiente de negócios local.
Recursos
Os dados podem ser obtidos em:
https://pjf.mg.gov.br/transparencia/dados_abertos/itbi/index.php.
Último acesso em: 12/11/2024.
Disclaimer
Os dados são utilizados para fins educacionais; contudo, embora sejam abertos ao público, respeitamos os princípios de confidencialidade e privacidade, de modo que as matrículas foram omitidas ou anonimizadas, para evitar a identificação dos imóveis ou proprietários.
Bibliotecas
Carregamos as seguintes bibilotecas do R:
- rvest - biblioteca para extração de dados web;
- tidyverse - coleção de ferramentas para manipulação de dados;
- lubridate - biblioteca para manipular dados no formato data/hora;
- prettydoc - temas adicionais para documentos Rmarkdown;
- reshape2 - ferramenta para transformação de dados;
- scales - utilizada para personalizar legendas;
- DT - para incluir tabelas em relatórios Rmarkdown;
- treemapify - para representação de dados usando retângulos aninhados;
- readxl - pacote para manipulação de dados do Excel.
Coleta de dados
Criamos uma função para baixar os arquivos e extrair as tabelas:
# Definir o diretório de trabalho
setwd("/home/gf/Scripts/ITBI/")
# Função para baixar e ler o arquivo xls, verificando se já existe localmente
baixar_itbi_xls <- function(ano) {
# URL do arquivo xls com base no ano
url <- paste0(
"https://pjf.mg.gov.br/transparencia/dados_abertos/itbi/arquivos/xls/",
ano, ".xls")
# Nome do arquivo local
arquivo_xls <- file.path(getwd(), paste0("itbi_", ano, ".xls"))
# Verifica se o arquivo já existe no diretório
if (!file.exists(arquivo_xls)) {
# Se não existir, faz o download do arquivo
tryCatch(
{
download.file(url, destfile = arquivo_xls, mode = "wb")
},
error = function(e) {
message(paste("Erro ao baixar o arquivo para o ano", ano, ":", e$message))
return(NULL) # Retorna NULL em caso de erro para evitar continuar com leitura
}
)
} else {
message(paste("O arquivo", arquivo_xls, "já existe no diretório. Pulando download."))
}
# Verifica novamente se o arquivo foi baixado com sucesso
if (file.exists(arquivo_xls)) {
# Ler o arquivo xls usando readxl
dados <- read_excel(arquivo_xls)
# Adicionar uma coluna com o ano
dados$Ano <- ano
return(dados)
} else {
message("Arquivo não disponível para o ano ", ano)
return(NULL)
}
}Armazenamos os data frames em listas:
Iteramos para baixar os arquivos xls de 2022 e 2023:
## O arquivo /home/gf/Scripts/ITBI/itbi_2022.xls já existe no diretório. Pulando download.
## O arquivo /home/gf/Scripts/ITBI/itbi_2023.xls já existe no diretório. Pulando download.
Convertemos a coluna ‘DATA TRANSAÇÃO’ para o tipo Date:
Combinamos todas as tabelas em um único data frame:
Formatamos a coluna ‘DATA TRANSAÇÃO’:
Renomeamos as colunas:
df <- df %>%
rename(
INSCRIÇÃO = "INSCRIÇÃO REDUZIDA",
LOGRADOURO = `TIPO VIA`,
OPERAÇÃO = `NATUREZA DA OPERAÇÃO`,
VALOR = `VALOR DA TRANSAÇÃO`,
DATA = `DATA TRANSAÇÃO`,
SFH = `CONTRATO COM AGENTE DO SFH`
)Selecionamos as colunas desejadas:
Validação dos dados
Detectamos a existência de valores ausentes:
A função is.na() detecta valores ausentes e retorna o objeto booleano True, se positivo ou False, se negativo.
## [1] TRUE
Identificamos as colunas com valores ausentes:
A função apply() aplica a função any(is.na(x)) em todas as colunas do data frame, para retornar o objeto booleano indicativo da existência ou não de valores ausentes.
## INSCRIÇÃO OPERAÇÃO DATA SFH
## FALSE TRUE FALSE FALSE
Identificamos as colunas com valores zerados:
A função colSums() é usada para contar quantos valores iguais a zero existem em cada coluna do data frame.
## INSCRIÇÃO OPERAÇÃO DATA SFH
## 0 NA 0 0
Removemos as linhas com valores ausentes:
Visualizamos o data frame final:
Indicadores de transações imobiliárias
Quantidade acumulada de transações por tipo de operação
operações <- count(df, OPERAÇÃO, sort = TRUE)
library(treemapify)
ggplot(operações, aes(area = n, fill = OPERAÇÃO,
label = paste(OPERAÇÃO, scales::number(n,
decimal.mark = ",",
big.mark = "."),
sep = "\n"))) +
geom_treemap() +
geom_treemap_text(colour = "white",
place = "centre",
size = 15) +
theme(legend.position = "none") Evolução mensal de transações imobiliárias
transações <- df %>%
mutate(DATA = format(as.Date(DATA), "%Y-%m")) %>%
filter(DATA >= "2022-01") %>%
group_by(DATA) %>%
summarise(Total = n())
compra_e_venda <- df %>%
mutate(DATA = format(as.Date(DATA), "%Y-%m")) %>%
filter(DATA >= "2022-01",
OPERAÇÃO == "COMPRA E VENDA") %>%
group_by(DATA) %>%
summarise(Vendas = n())
series <- transações %>%
left_join(compra_e_venda, by = "DATA")
series <- series %>%
mutate(DATA = as.Date(paste0(DATA, "-01")))
ggplot(series, aes(x=DATA)) +
geom_line(aes(y = Total, color = "Todas as transações"), linewidth = 1) +
geom_line(aes(y = Vendas, color = "Compra e Venda"), linewidth = 1, linetype = "dashed") +
labs(
title = "Série temporal de operações imobiliárias",
x = "Data",
y = "Contagem") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(plot.title = element_text(lineheight=.8, face="bold", size = 12)) +
theme(text = element_text(size=10)) +
scale_color_manual(values = c("Todas as transações" = "blue", "Compra e Venda" = "red")) +
scale_x_date(limit=as.Date(c("2022-01-01","2023-10-01")), breaks="1 month", labels=date_format("%Y-%m"))Quantidade mensal de transações imobiliárias por ano
# Filtrar os dados para o ano de 2022
series_2022 <- series %>%
filter(format(DATA, "%Y") == "2022") %>%
pivot_longer(cols = c("Total", "Vendas"), names_to = "Tipo", values_to = "Contagem") %>%
mutate(Tipo = dplyr::recode(Tipo, "Total" = "Todas as transações", "Vendas" = "Compra e Venda")) # Renomeia as categorias# Criar o gráfico de barras com as barras lado a lado por DATA
ggplot(series_2022, aes(x = DATA, y = Contagem, fill = Tipo)) +
geom_bar(stat = "identity", position = "dodge") +
labs(
title = "Quantidade mensal de registros - 2022",
x = "DATA",
y = "Contagem",
fill = "Tipo"
) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(plot.title = element_text(lineheight=.8, face="bold", size = 12)) +
theme(text = element_text(size=10)) +
scale_x_date(limit=as.Date(c("2021-12-01","2023-01-01")), breaks="1 month", labels=date_format("%Y-%m")) # Filtrar os dados para o ano de 2023
series_2023 <- series %>%
filter(format(DATA, "%Y") == "2023") %>%
pivot_longer(cols = c("Total", "Vendas"), names_to = "Tipo", values_to = "Contagem") %>%
mutate(Tipo = dplyr::recode(Tipo, "Total" = "Todas as transações", "Vendas" = "Compra e Venda")) # Renomeia as categorias# Criar o gráfico de barras com as barras lado a lado por DATA
ggplot(series_2023, aes(x = DATA, y = Contagem, fill = Tipo)) +
geom_bar(stat = "identity", position = "dodge") +
labs(
title = "Quantidade mensal de registros - 2023",
x = "DATA",
y = "Contagem",
fill = "Tipo"
) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(plot.title = element_text(lineheight=.8, face="bold", size = 12)) +
theme(text = element_text(size=10)) +
scale_x_date(limit=as.Date(c("2022-12-01","2023-12-01")), breaks="1 month", labels=date_format("%Y-%m"))Quantidade anual de transações imobiliárias
# Agregar os dados por ano, somando o Total e Vendas
# Calcular a proporção de Vendas sobre Total e agregar dados
series_ano <- series %>%
mutate(Ano = lubridate::year(DATA)) %>%
group_by(Ano) %>%
summarise(
Total = sum(Total, na.rm = TRUE),
Vendas = sum(Vendas, na.rm = TRUE)
) %>%
mutate(Proporção = Vendas / Total) %>% # Adiciona a coluna de proporção
pivot_longer(cols = c("Total", "Vendas"), names_to = "Tipo", values_to = "Contagem") %>%
mutate(Tipo = dplyr::recode(Tipo, "Total" = "Todas as transações", "Vendas" = "Compra e Venda")) # Renomeia as categorias# Criar o gráfico de barras com as barras lado a lado por ano
# Criar o gráfico com labels
ggplot(series_ano, aes(x = as.factor(Ano), y = Contagem, fill = Tipo)) +
geom_bar(stat = "identity", position = "dodge") +
geom_text(aes(label = Contagem), position = position_dodge(width = 0.9), vjust = -0.3) + # Labels verticais
geom_text(
data = series_ano %>% filter(Tipo == "Todas as transações"), # Filtrar apenas uma vez por ano para a proporção
aes(label = scales::percent(Proporção, accuracy = 0.1), x = as.factor(Ano), y = max(Contagem) / 2),
position = position_dodge(width = 0.9),
vjust = 0.5,
color = "black"
) +
labs(
title = "Quantidade anual de registros",
x = "Ano",
y = "Contagem",
fill = "Tipo"
) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(plot.title = element_text(lineheight=.8, face="bold", size = 12)) +
theme(text = element_text(size=10)) Evolução mensal de consolidação de propriedade
consolidação <- df %>%
mutate(MÊS = format(as.Date(DATA), "%Y-%m")) %>%
filter(MÊS >= "2022-01",
OPERAÇÃO == "CONSOLIDACAO DE PROPRIEDADE") %>%
group_by(MÊS) %>%
summarise(Quantidade = n())
# Converte o MÊS para formato de data (primeiro dia de cada mês)
consolidação$MÊS <- as.Date(paste0(consolidação$MÊS, "-01"))
# Gerar o gráfico de linhas
ggplot(consolidação, aes(x = MÊS, y = Quantidade)) +
geom_line(color = "red", linewidth = 1) +
labs(
title = "Série temporal da consolidação de propriedade",
x = "Mês",
y = "Quantidade de registros"
) +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(plot.title = element_text(lineheight=.8, face="bold", size = 12)) +
theme(text = element_text(size=10)) +
scale_x_date(limit=as.Date(c("2022-01-01","2023-10-01")), breaks="1 month", labels=date_format("%Y-%m"))