---
title: "Questão Aplicada - Dashboard - OPCIONAL"
author: "Carlos Eduardo Corrêa"
output:
flexdashboard::flex_dashboard:
orientation: rows
vertical_layout: fill
#runtime: shiny
source_code: embed
---

```{r setup, include=FALSE}
library(flexdashboard)
library(knitr)
library(ckanr)
library(tidyverse)
library(plotly)
library(lubridate)
library(BrazilCrime)
library(shiny)
library(DT)
library(sf)
library(geobr)
library(dplyr)
library(leaflet)
library(rsconnect)
```
```{r base_dados}
#RECUPERANDO BASE DE DADOS
ds_Homicidio_Consumado <- read.csv("Homicdio.csv", sep=";")
ds_Lesao_Corporal <- read.csv("Lesao_Corporal_2025.csv", sep=";")
#FILTRANDO COLUNAS, REMOVER(Natureza, Cod..IBGE, RISP, RMBH )
ds_Homicidio_remove_coluna <- ds_Homicidio_Consumado %>% select(-Natureza, -Cod..IBGE, -RISP, -RMBH)
ds_Lesao_Corporal_coluna <- ds_Lesao_Corporal %>% select(-Natureza, -Cód..IBGE, -RISP, -RMBH)
#PERÍODO ENTRE: 10/2024 e 10/2025
ds_Homicidio_ano <- ds_Homicidio_remove_coluna %>% filter((Mês >= 10 & Ano >= 2024) | (Mês <= 10 & Ano == 2025))
ds_Lesao_Corporal_ano <- ds_Lesao_Corporal_coluna %>% filter((Mês >= 10 & Ano.Fato >= 2024) | (Mês <= 10 & Ano.Fato == 2025))
#ds_Lesao_Corporal_ano
#CONVERTENDO COLUNA DE INT PARA CHAR
ds_Homicidio_ano$Mês <- as.character(ds_Homicidio_ano$Mês)
ds_Lesao_Corporal_ano$Mês <- as.character(ds_Lesao_Corporal_ano$Mês)
#NOMEANDO MESES DO ANO
ds_Homicidio_mes <- ds_Homicidio_ano %>%
mutate(
Mês = fct_recode(Mês, #fct_recode(col,"novo"="antigo")->altera manualmente os valores
"janeiro"="1",
"fevereiro"="2",
"março"="3",
"abril"="4",
"maio"="5",
"junho"="6",
"julho"="7",
"agosto"="8",
"setembro"="9",
"outubro"="10",
"novembro"="11",
"dezembro"="12",)
)
ds_Lesao_Corporal_mes <- ds_Lesao_Corporal_ano %>%
mutate(
Mês = fct_recode(Mês, #fct_recode(col,"novo"="antigo")->altera manualmente os valores
"janeiro"="1",
"fevereiro"="2",
"março"="3",
"abril"="4",
"maio"="5",
"junho"="6",
"julho"="7",
"agosto"="8",
"setembro"="9",
"outubro"="10",
"novembro"="11",
"dezembro"="12",)
)
# ds_Lesao_Corporal_mes
```
# Tabela Inerativa / Sumarização Estatística
Column {data-width=450}
-----------------------------------------------------------------------
### Tabela Dinâmica - Lesão Corporal
```{r}
#Renderiza a tabela interativa usando DT
renderDataTable({
datatable(
ds_Lesao_Corporal_mes,
options = list(
pageLength = 10, # Define 10 linhas por página
scrollX = TRUE, # Permite rolagem horizontal se a tabela for larga
dom = 'lftipr', # Define os elementos de controle (l: length, f: filter, t: table, i: info, p: pagination, r: processing)
language = list(url = '//cdn.datatables.net/plug-ins/1.10.25/i18n/Portuguese-Brasil.json')
),
caption = "Lesão Corporal de outubro/2024 a outubro/2025",
rownames = FALSE
)
})
```
### Sumarização
```{r}
# seleção de variáveis numéricas
selectInput(
inputId = "lesao_corporal",
label = "Selecione a Variável:",
choices = names(ds_Lesao_Corporal_mes)[sapply(ds_Lesao_Corporal_mes, is.numeric)], # Apenas variáveis numéricas
selected = "Ano.Fato"
)
# 1. Função Reativa: Calcula as estatísticas
resumo_lesao <- reactive({
# Captura a variável selecionada pelo usuário
var <- input$lesao_corporal
# 2. Sumarização usando dplyr (cálculos)
ds_Lesao_Corporal_mes %>%
summarise(
Média = mean(!!sym(var), na.rm = TRUE),
Mediana = median(!!sym(var), na.rm = TRUE),
Desvio_Padrão = sd(!!sym(var), na.rm = TRUE),
Mínimo = min(!!sym(var), na.rm = TRUE),
Máximo = max(!!sym(var), na.rm = TRUE),
N_Observações = n()
) %>%
# Transpõe a tabela para melhor visualização (estatística como linha)
t() %>%
as.data.frame() %>%
tibble::rownames_to_column(var = "Estatística") %>%
rename("Valor" = V1)
})
# 3. Renderiza a tabela de sumarização usando DT para interatividade
renderDataTable({
datatable(
resumo_lesao(),
options = list(
dom = 't', # Apenas a tabela, sem busca/paginação
ordering = FALSE
),
rownames = FALSE
)
})
```
Column {data-width=450}
-----------------------------------------------------------------------
### Tabela Dinâmica - Homicídio Consumado
```{r}
#Renderiza a tabela interativa usando DT
renderDataTable({
datatable(
ds_Homicidio_mes,
options = list(
pageLength = 10, # Define 10 linhas por página
scrollX = TRUE, # Permite rolagem horizontal se a tabela for larga
dom = 'lftipr',
language = list(url = '//cdn.datatables.net/plug-ins/1.10.25/i18n/Portuguese-Brasil.json')
),
caption = "Homoicídio Consumado de outubro/2024 a outubro/2025",
rownames = FALSE
)
})
```
### Sumarização
```{r}
# seleção de variáveis numéricas
selectInput(
inputId = "homicidio_consumado",
label = "Selecione a Variável:",
choices = names(ds_Homicidio_mes)[sapply(ds_Homicidio_mes, is.numeric)], # Apenas variáveis numéricas
selected = "Registros"
)
# 1. Função Reativa: Calcula as estatísticas
resumo_reativo <- reactive({
# Captura a variável selecionada pelo usuário
var <- input$homicidio_consumado
# 2. Sumarização usando dplyr (cálculos)
ds_Homicidio_mes %>%
summarise(
Média = mean(!!sym(var), na.rm = TRUE),
Mediana = median(!!sym(var), na.rm = TRUE),
Desvio_Padrão = sd(!!sym(var), na.rm = TRUE),
Mínimo = min(!!sym(var), na.rm = TRUE),
Máximo = max(!!sym(var), na.rm = TRUE),
N_Observações = n()
) %>%
# Transpõe a tabela para melhor visualização (estatística como linha)
t() %>%
as.data.frame() %>%
tibble::rownames_to_column(var = "Estatística") %>%
rename("Valor" = V1)
})
# 3. Renderiza a tabela de sumarização usando DT para interatividade
renderDataTable({
datatable(
resumo_reativo(),
options = list(
dom = 't', # Apenas a tabela, sem busca/paginação
ordering = FALSE
),
rownames = FALSE
)
})
```
# Gráficos: Lesão Corporal - Homicídio
Column {data-width=450}
-----------------------------------------------------------------------
### Gráficos 1 - Lesão Corporal
```{r}
#ds_Lesao_Corporal_mes
ds_Lesao_Corporal_soma <- ds_Lesao_Corporal_mes %>%
# # Agrupa pela coluna do Município
group_by(Município) %>%
# # Calcula a soma total dos Registros para cada Município
summarise(
Total_Lesao = sum(Registros, na.rm = TRUE) # na.rm = TRUE lida com valores ausentes
) %>%
# ## Remove o agrupamento para futuras operações
ungroup()
#ds_Lesao_Corporal_soma
# Exibe os municípios com maior número de registros
ds_Lesao_Corporal_top_20 <- ds_Lesao_Corporal_soma %>%
arrange(desc(Total_Lesao)) %>%
head(20) # Mostra os 10 municípios com mais homicídios
#ds_Lesao_Corporal_top_20
```
```{r grafico_lesao, echo=FALSE}
# library(ggplot2)
l <- ggplot(ds_Lesao_Corporal_top_20 , aes(x = reorder(Município, Total_Lesao), # Ordena o eixo X pela soma
y = Total_Lesao)) + # ESSENCIAL: Mapear a altura da barra para a coluna somada
geom_bar(stat = "identity", fill = "skyblue") + # Adicionar stat="identity" e cores
geom_text(
aes(label = Total_Lesao), # Mapeia o rótulo para o valor de Total_Lesao
vjust = 1,
color = "black",
fontface = "bold"
) +
theme_minimal() +
labs(
title = "Lesão Corporal no Período",
subtitle = "outubro de 2024 a outubro de 2025",
x = "Município",
y = "Total de Registros") +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "none"
)
# Use renderPlotly e a função ggplotly
renderPlotly({ggplotly(l)})
```
### Gráficos 2 - Lesão Corporal
```{r}
ds_Lesao_serie_temporal <- ds_Lesao_Corporal_mes %>%
# Agrupar por Mês e Ano para obter o total mensal
group_by(Ano.Fato, Mês) %>%
summarise(Total_Registros = sum(Registros, na.rm = TRUE)) %>%
ungroup()
# Plotagem da Linha do Tempo
p_linha <- ggplot(ds_Lesao_serie_temporal,
aes(x = Mês, # Variável Categórica (Mês)
y = Total_Registros, # ESSENCIAL: O valor a ser plotado
group = factor(Ano.Fato), # Necessário para geom_line separar as linhas
color = factor(Ano.Fato))) + # Cor da linha por Ano
geom_line(linewidth = 1) +
geom_point() + # Adicionar pontos para melhor visualização
theme_minimal() +
labs(
title = "Tendência de Lesão Corporal por Mês",
x = "Mês",
y = "Total de Registros",
color = "Ano"
) +
#theme(axis.text.x = element_text(angle = 45, hjust = 1))
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1),
# legend.position = "none"
)
# Renderização do Plotly
renderPlotly({
ggplotly(p_linha)
})
```
Column {data-width=450}
-----------------------------------------------------------------------
### Gráficos 1 - Homicídio Consumado
```{r}
#ds_Lesao_Corporal_mes
ds_Homicidio_soma <- ds_Homicidio_mes %>%
# # 1. Agrupar pela coluna do Município
group_by(Município) %>%
# # 2. Calcular a soma total dos Registros para cada Município
summarise(
Total_Homicidio = sum(Registros, na.rm = TRUE) # na.rm = TRUE lida com valores ausentes
) %>%
# ## 3. Remover o agrupamento para futuras operações
ungroup()
#
#ds_Lesao_Corporal_soma
# Exibir os municípios com maior número de registros, se desejar
ds_Homicidio_top_20 <- ds_Homicidio_soma %>%
arrange(desc(Total_Homicidio)) %>%
head(20) # Mostra os 10 municípios com mais homicídios
#ds_Lesao_Corporal_top_20
```
```{r grafico_homicidio, echo=FALSE}
# library(ggplot2)
#
h <- ggplot(ds_Homicidio_top_20 , aes(x = reorder(Município, Total_Homicidio), # Ordena o eixo X pela soma
y = Total_Homicidio)) + # ESSENCIAL: Mapear a altura da barra para a coluna somada
geom_bar(stat = "identity", fill = "skyblue") + # Adicionar stat="identity" e cores
geom_text(
aes(label = Total_Homicidio), # Mapeia o rótulo para o valor de Total_Lesao
vjust = 1,
color = "black",
fontface = "bold"
) +
theme_minimal() +
labs(
title = "Homicídio Consumado no Período",
subtitle = "outubro de 2024 a outubro de 2025",
x = "Município",
y = "Total de Registros") +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "none"
)
# Use renderPlotly e a função ggplotly
renderPlotly({ggplotly(h)})
```
### Gráficos 2 - Homicídio Consumado
```{r}
ds_Homicidio_serie_temporal <- ds_Homicidio_mes %>%
# Agrupar por Mês e Ano para obter o total mensal
group_by(Ano, Mês) %>%
summarise(Total_Registros = sum(Registros, na.rm = TRUE)) %>%
ungroup()
# Plotagem da Linha do Tempo
h_linha <- ggplot(ds_Homicidio_serie_temporal,
aes(x = Mês, # Variável Categórica (Mês)
y = Total_Registros, # ESSENCIAL: O valor a ser plotado
group = factor(Ano), # Necessário para geom_line separar as linhas
color = factor(Ano))) + # Cor da linha por Ano
geom_line(linewidth = 1) +
geom_point() + # Adicionar pontos para melhor visualização
theme_minimal() +
labs(
title = "Tendência de Homicídios por Mês",
x = "Mês",
y = "Total de Registros",
color = "Ano"
) +
#theme(axis.text.x = element_text(angle = 45, hjust = 1))
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
axis.text.x = element_text(angle = 45, hjust = 1),
#legend.position = "none"
)
# Renderização do Plotly
renderPlotly({
ggplotly(h_linha)
})
```
# Mapas Temáticos
### Mapa RPM
```{r sumarizacao_municipios}
#ds_Homicidio_mes
# 1. Agrupar os dados detalhados por Município
ds_Homicidio_por_municipio <- ds_Homicidio_mes %>%
group_by(Município) %>%
# 2. Sumarizar os registros
summarise(
Total_Homicidios = sum(Registros, na.rm = TRUE)
) %>%
ungroup()
# ds_Lesao_por_municipio (Também pode ser criado aqui)
ds_Lesao_por_municipio <- ds_Lesao_Corporal_mes %>%
group_by(Município) %>%
summarise(Total_Lesao = sum(Registros, na.rm = TRUE)) %>%
ungroup()
#ds_Homicidio_por_municipio
```
```{r mapa_contagem_homicidios, echo=FALSE, out.width='100%', out.height='100%'}
# 1. Obter as fronteiras municipais de Minas Gerais (MG)
sf_municipios_mg <- read_municipality(
code_muni = 31,
year = 2020
)
# 1.1 Definir os municípios da "Região de Contagem" (Foco)
municipios_foco <- c(
"CONTAGEM",
"SÃO JOAQUIM DE BICAS",
"BETIM",
"RIBEIRÃO DAS NEVES",
"SARZEDO",
"MÁRIO CAMPOS",
"IBIRITÉ",
"BRUMADINHO",
"ESMERALDAS"
)
# --- INÍCIO DA CORREÇÃO ---
# 2. Filtrar e Padronizar o Shapefile (geometria)
sf_contagem_regiao_join <- sf_municipios_mg %>%
# Cria a coluna de união em MAIÚSCULAS
mutate(municipio_join = toupper(name_muni)) %>%
filter(municipio_join %in% municipios_foco) # <--- Linha que estava causando o erro, agora unida.
# 3. Filtrar e Padronizar os Dados de Homicídio (Totais)
ds_homicidio_contagem_regiao_join <- ds_Homicidio_por_municipio %>%
# Cria a coluna de união em MAIÚSCULAS
mutate(municipio_join = toupper(Município)) %>%
filter(municipio_join %in% municipios_foco)
# 4. Fazer o join (união) pela coluna padronizada 'municipio_join'
ds_mapa_rpm <- sf_contagem_regiao_join %>%
left_join(ds_homicidio_contagem_regiao_join, by = "municipio_join") %>%
# Trata os NAs
mutate(Total_Homicidios = ifelse(is.na(Total_Homicidios), 0, Total_Homicidios))
# --- FIM DA CORREÇÃO ---
# 5. Criar a Paleta de Cores e Rótulos (O restante do código permanece o mesmo)
paleta_contagem <- colorNumeric(
palette = "Reds",
domain = ds_mapa_rpm$Total_Homicidios
)
labels_contagem <- paste(
"<strong>Município:</strong> ", ds_mapa_rpm$name_muni, "</strong><br/>",
"<strong>Total de Homicídios:</strong> ", ds_mapa_rpm$Total_Homicidios
) %>% lapply(htmltools::HTML)
# 6. Construção do Mapa Leaflet
ds_mapa_rpm %>%
leaflet() %>%
addTiles() %>%
# Adiciona as Poligonais
addPolygons(
fillColor = ~paleta_contagem(Total_Homicidios),
weight = 1,
opacity = 1,
color = "black",
fillOpacity = 0.8,
highlightOptions = highlightOptions(
weight = 3,
color = "#444",
fillOpacity = 1,
bringToFront = TRUE
),
label = labels_contagem,
labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "3px 8px"),
textsize = "14px",
direction = "auto"
)
) %>%
# Adiciona a Legenda
addLegend(
pal = paleta_contagem,
values = ~Total_Homicidios,
opacity = 0.8,
title = "Homicídios (Out/24 - Out/25)",
position = "bottomright"
) %>%
# Centraliza o mapa na região de Contagem (Aproximadamente)
setView(lng = -44.05, lat = -19.9, zoom = 9)
```
### Mapa Contagem
```{r mapa_Contagem_Homicidios_Final, echo=FALSE, out.width='100%', out.height='100%'}
# Este chunk irá gerar o mapa do município de CONTAGEM, preenchido com seu total de homicídios.
# 1. Obter as fronteiras municipais de Minas Gerais (MG)
sf_municipios_mg <- read_municipality(
code_muni = 31,
year = 2020
)
# 1.1 Definir o município de Foco
municipios_foco <- c(
"CONTAGEM"
)
# 2. Filtrar e Padronizar o Shapefile (geometria)
sf_contagem_regiao_join <- sf_municipios_mg %>%
# Cria a coluna de união em MAIÚSCULAS
mutate(municipio_join = toupper(name_muni)) %>%
filter(municipio_join %in% municipios_foco)
# 3. Filtrar e Padronizar os Dados de Homicídio (Totais)
ds_homicidio_contagem_regiao_join <- ds_Homicidio_por_municipio %>%
# Cria a coluna de união em MAIÚSCULAS
mutate(municipio_join = toupper(Município)) %>%
filter(municipio_join %in% municipios_foco)
# 4. Fazer o join (união) pela coluna padronizada 'municipio_join'
ds_mapa_contagem <- sf_contagem_regiao_join %>%
left_join(ds_homicidio_contagem_regiao_join, by = "municipio_join") %>%
# Trata os NAs, garantindo que Total_Homicidios seja um número (0 se o join falhou)
mutate(Total_Homicidios = ifelse(is.na(Total_Homicidios), 0, Total_Homicidios))
# 5. Criar a Paleta de Cores e Rótulos
paleta_contagem <- colorNumeric(
palette = "Reds",
domain = ds_mapa_contagem$Total_Homicidios
)
labels_contagem <- paste(
"<strong>Município:</strong> ", ds_mapa_contagem$name_muni, "</strong><br/>",
"<strong>Total de Homicídios:</strong> ", ds_mapa_contagem$Total_Homicidios
) %>% lapply(htmltools::HTML)
# 6. Construção do Mapa Leaflet
ds_mapa_contagem %>%
leaflet() %>%
addTiles() %>%
# Adiciona as Poligonais
addPolygons(
fillColor = ~paleta_contagem(Total_Homicidios),
weight = 1,
opacity = 1,
color = "black",
fillOpacity = 0.8,
highlightOptions = highlightOptions(
weight = 3,
color = "#444",
fillOpacity = 1,
bringToFront = TRUE
),
label = labels_contagem,
labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "3px 8px"),
textsize = "14px",
direction = "auto"
)
) %>%
# Adiciona a Legenda
addLegend(
pal = paleta_contagem,
values = ~Total_Homicidios,
opacity = 0.8,
title = "Homicídios (Out/24 - Out/25)",
position = "bottomright"
) %>%
# Centraliza o mapa em Contagem e ajusta o zoom
setView(lng = -44.05, lat = -19.93, zoom = 11) # Ajustei o zoom para Contagem