Compreender como os registros de atuação da Defesa Civil se distribuem no tempo e no território pode apoiar discussões sobre a organização dos serviços e o acompanhamento das ações realizadas. Além do volume de registros, é necessário conhecer os tipos de ação e as condições de preenchimento da base, pois essas características influenciam as comparações entre períodos e locais.
Este projeto procura responder à seguinte pergunta: como os registros de atuação da Defesa Civil do Recife se distribuem entre meses, dias da semana, regionais e bairros em 2024, e como o perfil das ações varia entre esses recortes? Também se investiga em que medida as informações ausentes e as possíveis repetições limitam a interpretação dos resultados.
Para responder à pergunta, utiliza-se o arquivo de atendimentos de 2024 disponível no Portal de Dados Abertos do Recife. A abordagem consiste em uma análise exploratória em R, com importação, diagnóstico, padronização de textos, conversão de datas e números e seleção das ações com data em 2024. A partir da base preparada, calculam-se frequências, proporções, médias por dia de calendário e cruzamentos entre localização, período e tipo de ação. Tabelas e gráficos apresentam os resultados, acompanhados de interpretações.
A análise considera o preenchimento dos campos de tipo de ação e grau de risco e compara os resultados com um cenário que mantém apenas a primeira ocorrência de cada linha originalmente idêntica. Esses procedimentos permitem caracterizar a atuação registrada e avaliar a influência de algumas limitações da base.
Os resultados podem interessar a equipes de gestão e planejamento da Defesa Civil, pesquisadores e cidadãos que acompanham os serviços municipais. A identificação dos períodos com maior volume pode subsidiar discussões sobre a distribuição de recursos; a comparação das ações pode caracterizar o perfil registrado em cada regional; e a avaliação do preenchimento pode apontar necessidades de revisão dos registros. Como o estudo utiliza contagens administrativas, essas informações precisam ser interpretadas junto com suas limitações de cobertura e preenchimento.
O pacote readr importa arquivos CSV; dplyr
permite manipular e resumir os dados; stringr padroniza
textos; ggplot2 constrói os gráficos; e knitr
apresenta as tabelas no relatório. Instale-os uma vez no Console antes
de compilar o relatório.
# install.packages(c("readr", "dplyr", "stringr", "ggplot2", "knitr"))
library(readr)
library(dplyr)
library(stringr)
library(ggplot2)
library(knitr)
Os dados foram obtidos no conjunto Registro de Atendimentos da Defesa Civil, disponibilizado gratuitamente no Portal de Dados Abertos da Prefeitura do Recife e vinculado à Secretaria Executiva de Defesa Civil. Segundo a descrição do portal, o conjunto reúne informações sobre solicitações de atendimento, áreas de risco, vistorias e execução de serviços de colocação de lona. O recurso “Atendimentos 2024” é apresentado como um registro das ações de monitoramento e atuação da Defesa Civil naquele ano. Sua natureza é administrativa: os dados documentam a atuação do serviço municipal, e este projeto os utiliza para análise exploratória.
O arquivo utilizado, atendimentos_2024.csv, foi baixado
em 05/11/2026 e preservado em sua versão original. Ele
contém 80.173 registros e 16 variáveis, em formato CSV,
com ponto e vírgula como separador e codificação UTF-8. O ano de
referência do recurso é 2024; a data de download indica
quando a cópia foi obtida, sem representar a data de coleta de todos os
registros. A documentação consultada não detalha o momento de inserção
de cada linha no sistema.
As 16 colunas originais podem ser organizadas nos seguintes grupos:
| Grupo | Colunas originais | Conteúdo identificado pelos campos |
|---|---|---|
| Referência temporal | Ano, Mês, Data,
Data_da_Acao |
Ano, mês e duas informações de data disponíveis para conferência e definição do recorte temporal. |
| Localização | Regional, Endereco,
Bairro, Localidade |
Identificação territorial e endereço associados ao registro. |
| Ocorrência, solicitação e ação | Ocorrencia, Solicitacao,
Tipo_da_Acao |
Informações sobre a ocorrência, a solicitação e a ação registrada. |
| Classificação de risco | Grau_de_Risco |
Código de risco, quando preenchido. |
| Quantidades e medidas | Quantidade, Altura,
Largura, Area_m |
Campos quantitativos cuja interpretação depende do serviço e das regras de preenchimento. |
O dicionário de dados consultado no portal lista os nomes e tipos dos campos, mas não esclarece suficientemente a unidade representada por cada linha nem as regras de classificação de risco e de preenchimento das medidas. Por isso, as contagens deste relatório representam registros do arquivo. Elas não são tratadas como quantidades de pessoas, imóveis ou solicitações únicas. As duas colunas de data também não são usadas para estimar tempo de resposta.
O arquivo combina textos, datas e valores de natureza numérica. Na importação, todas as colunas são lidas como texto para preservar sua representação antes das conversões explícitas. As datas observadas usam a ordem ano-mês-dia, e os campos numéricos podem apresentar ponto como separador decimal. Há campos vazios, diferenças de espaçamento e de maiúsculas e minúsculas e rótulos como “Nao Informado” e “Bairro Nao Cadastrado”, que indicam ausência de identificação do bairro. Esses rótulos exigem tratamento específico além do reconhecimento dos campos vazios.
Também são identificadas linhas originalmente idênticas e datas
ausentes ou fora de 2024. A preparação sinaliza essas situações,
preserva os valores originais e define o recorte pela coluna
Data_da_Acao, posteriormente renomeada para
data_acao. Zeros em campos quantitativos não são
convertidos automaticamente em ausência, pois seu significado não foi
confirmado. Essas particularidades orientam os tratamentos e os cuidados
de interpretação apresentados nas seções seguintes.
Coloque atendimentos_2024.csv e este documento na mesma
pasta. O CSV usa ponto e vírgula como separador. A leitura inicial
utiliza texto para permitir conversões explícitas. A prévia limita a
impressão a seis linhas.
arquivo <- "atendimentos_2024.csv"
if (!file.exists(arquivo)) {
stop("CSV nao encontrado. Coloque-o na pasta do projeto ou ajuste 'arquivo'.")
}
# Ler como texto permite inspecionar os valores. Os numeros e as datas serao
# convertidos explicitamente, depois da inspecao.
dados_originais <- read_delim(
arquivo,
delim = ";",
col_types = cols(.default = col_character()),
locale = locale(encoding = "UTF-8"),
na = c("", "NA"),
trim_ws = FALSE,
show_col_types = FALSE
)
dimensoes <- data.frame(
registros = nrow(dados_originais),
variaveis = ncol(dados_originais)
)
print(dimensoes)
## registros variaveis
## 1 80173 16
print(head(dados_originais, 6))
## # A tibble: 6 × 16
## Regional Ano Mês Data Ocorrencia Solicitacao Endereco Bairro Localidade
## <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 Oeste 2024 Abril 2024-0… <NA> <NA> Rua Cap… Varzea Barreiras
## 2 Nordeste 2024 Abril 2024-0… <NA> Vistoria Rua Cru… Guabi… Alto da G…
## 3 Nordeste 2024 Abril 2024-0… <NA> Colocação … Subida … Nova … Alto da B…
## 4 Nordeste 2024 Abril 2024-0… <NA> Colocação … Subida … Nova … Alto da B…
## 5 Nordeste 2024 Abril 2024-0… <NA> Monitorame… Rua Alt… Nova … Alto da B…
## 6 Nordeste 2024 Abril 2024-0… <NA> Monitorame… Rua Alt… Nova … Alto da B…
## # ℹ 7 more variables: Grau_de_Risco <chr>, Data_da_Acao <chr>,
## # Tipo_da_Acao <chr>, Quantidade <chr>, Altura <chr>, Largura <chr>,
## # Area_m <chr>
A tabela abaixo informa os campos ausentes da base original, antes dos tratamentos. A marcação de repetições compara as colunas originais e preserva os registros para investigação.
diagnostico_ausencias <- data.frame(
variavel = names(dados_originais),
ausentes = colSums(is.na(dados_originais))
) %>%
mutate(percentual = round(100 * ausentes / nrow(dados_originais), 2)) %>%
arrange(desc(ausentes))
print(diagnostico_ausencias)
## variavel ausentes percentual
## Ocorrencia Ocorrencia 77811 97.05
## Largura Largura 70491 87.92
## Altura Altura 70469 87.90
## Quantidade Quantidade 68778 85.79
## Grau_de_Risco Grau_de_Risco 48812 60.88
## Solicitacao Solicitacao 27536 34.35
## Tipo_da_Acao Tipo_da_Acao 18918 23.60
## Bairro Bairro 57 0.07
## Data_da_Acao Data_da_Acao 8 0.01
## Data Data 1 0.00
## Regional Regional 0 0.00
## Ano Ano 0 0.00
## Mês Mês 0 0.00
## Endereco Endereco 0 0.00
## Localidade Localidade 0 0.00
## Area_m Area_m 0 0.00
repeticao_original <- duplicated(dados_originais)
print(data.frame(repeticoes_a_investigar = sum(repeticao_original)))
## repeticoes_a_investigar
## 1 5931
A cópia de trabalho recebe nomes de colunas padronizados. O
identificador id é criado com o número da linha e serve
para localizar registros no arquivo, sem identificar solicitações
únicas. Espaços extras e variações de maiúsculas são normalizados.
Valores originais permanecem em dados_originais. As
categorias de serviços com significados diferentes continuam separadas.
Os rótulos de bairros não identificados são convertidos para
NA.
dados <- dados_originais %>%
rename(
regional = Regional, ano_informado = Ano,
mes_informado = `Mês`, data_registro = Data,
ocorrencia = Ocorrencia, solicitacao = Solicitacao,
endereco = Endereco, bairro = Bairro, localidade = Localidade,
grau_risco = Grau_de_Risco, data_acao = Data_da_Acao,
tipo_acao = Tipo_da_Acao, quantidade = Quantidade,
altura = Altura, largura = Largura, area_m = Area_m
) %>%
mutate(
# Identificador criado para localizar cada linha do arquivo.
id = row_number(),
across(where(is.character), ~ na_if(str_squish(.x), "")),
across(c(regional, bairro, localidade),
~ str_to_title(.x, locale = "pt")),
across(c(ocorrencia, solicitacao, tipo_acao, mes_informado),
~ str_to_lower(.x, locale = "pt")),
grau_risco = str_to_upper(grau_risco, locale = "pt"),
possivel_repeticao_original = repeticao_original
)
rotulos_sem_bairro <- c(
"Nao Informado", "Não Informado", "Bairro Nao Cadastrado",
"Bairro Não Cadastrado"
)
dados <- dados %>%
mutate(bairro = if_else(bairro %in% rotulos_sem_bairro, NA_character_, bairro))
Datas e números recebem os tipos adequados. Datas ausentes, inválidas, fora do período e ações anteriores à outra data são sinalizadas. Os anos não são alterados automaticamente.
dados <- dados %>%
mutate(
across(c(ano_informado, quantidade, altura, largura, area_m),
~ parse_double(.x, locale = locale(decimal_mark = "."))),
data_registro_original = data_registro,
data_acao_original = data_acao,
data_registro = as.Date(substr(data_registro_original, 1, 10),
format = "%Y-%m-%d"),
data_acao = as.Date(substr(data_acao_original, 1, 10),
format = "%Y-%m-%d"),
data_registro_invalida = !is.na(data_registro_original) & is.na(data_registro),
data_acao_invalida = !is.na(data_acao_original) & is.na(data_acao),
data_registro_fora_2024 = !is.na(data_registro) &
format(data_registro, "%Y") != "2024",
data_acao_fora_2024 = !is.na(data_acao) &
format(data_acao, "%Y") != "2024",
acao_antes_registro = !is.na(data_registro) & !is.na(data_acao) &
data_acao < data_registro,
risco_informado = !is.na(grau_risco)
)
# Nao corrigir os anos automaticamente nem interpretar a diferenca entre
# as datas como tempo de resposta sem confirmar suas definicoes na fonte.
diagnostico_datas <- dados %>%
summarise(
registro_sem_data = sum(is.na(data_registro)),
acao_sem_data = sum(is.na(data_acao)),
registro_invalido = sum(data_registro_invalida),
acao_invalida = sum(data_acao_invalida),
registro_fora_2024 = sum(data_registro_fora_2024),
acao_fora_2024 = sum(data_acao_fora_2024),
acao_anterior_ao_registro = sum(acao_antes_registro)
)
print(diagnostico_datas)
## # A tibble: 1 × 7
## registro_sem_data acao_sem_data registro_invalido acao_invalida
## <int> <int> <int> <int>
## 1 1 8 0 0
## # ℹ 3 more variables: registro_fora_2024 <int>, acao_fora_2024 <int>,
## # acao_anterior_ao_registro <int>
Para a análise temporal, adota-se a data da ação como referência. Criam-se mês, trimestre, dia da semana e indicador de fim de semana. O subconjunto temporal inclui somente ações com data em 2024, enquanto a base preparada preserva todas as linhas. A tabela explicita o tamanho de cada conjunto.
meses <- c("Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho",
"Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro")
dias <- c("Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira",
"Quinta-feira", "Sexta-feira", "Sábado")
dados <- dados %>%
mutate(
mes_numero = as.integer(format(data_acao, "%m")),
mes_acao = factor(meses[mes_numero], levels = meses, ordered = TRUE),
trimestre = (mes_numero - 1L) %/% 3L + 1L,
dia_numero = as.integer(format(data_acao, "%w")),
dia_semana = factor(dias[dia_numero + 1L], levels = dias, ordered = TRUE),
fim_de_semana = if_else(is.na(dia_numero), NA,
dia_numero %in% c(0L, 6L))
)
# Filtrar somente para as analises que usam a data da acao em 2024.
# A base 'dados' continua contendo todas as linhas, inclusive as sinalizadas.
dados_2024 <- dados %>%
filter(!is.na(data_acao), format(data_acao, "%Y") == "2024")
print(data.frame(
registros_originais = nrow(dados_originais),
registros_preparados = nrow(dados),
registros_com_acao_em_2024 = nrow(dados_2024),
fora_do_recorte_temporal = nrow(dados) - nrow(dados_2024)
))
## registros_originais registros_preparados registros_com_acao_em_2024
## 1 80173 80173 80163
## fora_do_recorte_temporal
## 1 10
knitr::kable(
dados_2024 %>%
select(id, data_acao, regional, bairro, tipo_acao, grau_risco) %>%
head(6),
col.names = c("Linha", "Data da ação", "Regional", "Bairro", "Tipo de ação", "Risco"),
caption = "Amostra dos registros após os tratamentos."
)
| Linha | Data da ação | Regional | Bairro | Tipo de ação | Risco |
|---|---|---|---|---|---|
| 1 | 2024-04-03 | Oeste | Varzea | atendimento social | NA |
| 2 | 2024-04-16 | Nordeste | Guabiraba | atendimento social | R3 |
| 3 | 2024-04-16 | Nordeste | Nova Descoberta | NA | NA |
| 4 | 2024-04-16 | Nordeste | Nova Descoberta | NA | NA |
| 5 | 2024-04-16 | Nordeste | Nova Descoberta | acoes de porta-porta | R2 |
| 6 | 2024-04-16 | Nordeste | Nova Descoberta | acoes de porta-porta | R2 |
A síntese abaixo descreve as principais variáveis do subconjunto
dados_2024, após a padronização e o recorte pela data da
ação. Os tipos apresentados são os utilizados no R. As variáveis de
localização e ação permitem comparar grupos; as temporais organizam a
distribuição ao longo do ano; e os indicadores de qualidade apoiam a
interpretação e a comparação entre cenários.
| Variável | Tipo após o tratamento | Significado e uso na análise |
|---|---|---|
data_acao |
Data (Date) |
Data da ação informada na fonte; define o recorte de 2024 e origina as variáveis temporais. |
regional |
Texto (character) |
Regional informada; permite comparar volume, composição das ações e preenchimento dos campos. |
bairro |
Texto (character) |
Rótulo do bairro após a padronização; utilizado na análise de concentração territorial. |
tipo_acao |
Texto (character) |
Categoria da ação registrada; utilizada nos rankings e nas comparações entre regionais e meses. |
grau_risco |
Texto (character) |
Código de risco; sua distribuição é calculada entre os registros com o campo preenchido. |
mes_acao |
Fator ordenado (ordered factor) |
Mês derivado de data_acao, ordenado de
janeiro a dezembro; organiza tabelas e gráficos mensais. |
dia_semana |
Fator ordenado (ordered factor) |
Dia da semana derivado de data_acao, com
níveis de domingo a sábado; permite a comparação ajustada ao
calendário. |
risco_informado |
Lógico (logical) |
Indica se grau_risco está preenchido;
utilizado na avaliação da cobertura desse campo. |
possivel_repeticao_original |
Lógico (logical) |
Marca ocorrências posteriores de linhas originalmente idênticas; utilizado no cenário de sensibilidade às repetições. |
A tabela seguinte consolida a diversidade dos valores e o
preenchimento das sete variáveis que descrevem diretamente o período, a
localização, a ação e o risco. Todos os percentuais de ausência usam o
total de linhas de dados_2024. Os valores distintos contam
somente os valores observados e não ausentes; níveis de fatores sem
registros não aumentam essa contagem.
variaveis_interesse <- c(
"data_acao", "regional", "bairro", "tipo_acao", "grau_risco",
"mes_acao", "dia_semana"
)
sintese_variaveis <- data.frame(
variavel = variaveis_interesse,
valores_distintos = vapply(
dados_2024[variaveis_interesse],
function(x) n_distinct(x, na.rm = TRUE), integer(1)
),
ausentes = vapply(
dados_2024[variaveis_interesse],
function(x) sum(is.na(x)), integer(1)
),
row.names = NULL
) %>%
mutate(percentual_ausente = 100 * ausentes / nrow(dados_2024))
knitr::kable(
sintese_variaveis, digits = 1,
col.names = c("Variável", "Valores distintos observados", "Ausentes", "% ausente"),
caption = "Síntese das principais variáveis após o tratamento e o recorte temporal."
)
| Variável | Valores distintos observados | Ausentes | % ausente |
|---|---|---|---|
| data_acao | 273 | 0 | 0.0 |
| regional | 6 | 0 | 0.0 |
| bairro | 103 | 1352 | 1.7 |
| tipo_acao | 35 | 18918 | 23.6 |
| grau_risco | 4 | 48804 | 60.9 |
| mes_acao | 12 | 0 | 0.0 |
| dia_semana | 6 | 0 | 0.0 |
No recorte, as datas de ação vão de 02/01/2024 a 30/12/2024. Há 6
rótulos de regional e 103 rótulos de bairro preenchidos. Essas
quantidades descrevem as categorias presentes no arquivo; a grafia dos
bairros ainda não foi validada contra um cadastro oficial. A ausência em
tipo_acao e grau_risco permanece identificada,
sem imputação de categorias. Os códigos de risco são tratados como
categorias, sem conversão em uma escala numérica de gravidade.
As contagens usam o mesmo recorte temporal. A ausência do tipo de ação aparece como uma categoria própria, sem eliminar o registro. As contagens incluem os registros sinalizados como possíveis repetições.
resumo_mensal <- dados_2024 %>%
count(mes_acao, name = "registros", .drop = FALSE)
resumo_regional <- dados_2024 %>%
mutate(regional = coalesce(regional, "Não informada")) %>%
count(regional, name = "registros", sort = TRUE) %>%
mutate(percentual = round(100 * registros / sum(registros), 2))
resumo_acoes <- dados_2024 %>%
mutate(tipo_acao = coalesce(tipo_acao, "não informado")) %>%
count(tipo_acao, name = "registros", sort = TRUE)
print(resumo_mensal)
## # A tibble: 12 × 2
## mes_acao registros
## <ord> <int>
## 1 Janeiro 7313
## 2 Fevereiro 6463
## 3 Março 10559
## 4 Abril 12070
## 5 Maio 8790
## 6 Junho 7555
## 7 Julho 7628
## 8 Agosto 5764
## 9 Setembro 4116
## 10 Outubro 3873
## 11 Novembro 3072
## 12 Dezembro 2960
print(resumo_regional)
## # A tibble: 6 × 3
## regional registros percentual
## <chr> <int> <dbl>
## 1 Norte 20537 25.6
## 2 Noroeste 16075 20.0
## 3 Sul 14280 17.8
## 4 Oeste 12950 16.2
## 5 Nordeste 9110 11.4
## 6 Planície 7211 9
print(head(resumo_acoes, 10))
## # A tibble: 10 × 2
## tipo_acao registros
## <chr> <int>
## 1 atendimento social 30080
## 2 não informado 18918
## 3 acoes de porta-porta 15383
## 4 analise visual estrutural 7698
## 5 mapeamento de area de risco 2487
## 6 rocagem 1954
## 7 encaminhamentos aos parceiros 848
## 8 distribuicao de cestas basicas 543
## 9 acoes educativas 322
## 10 corte de arvores 295
Os gráficos mostram o volume mensal e a distribuição por regional das ações datadas em 2024. Eles devem ser interpretados como contagens de registros. Concentração de registros não equivale, por si só, a maior risco, maior população atendida ou maior eficiência do serviço.
grafico_mensal <- ggplot(resumo_mensal, aes(x = mes_acao, y = registros)) +
geom_col(fill = "#28668A", width = 0.75) +
labs(
title = "Registros por mês da ação em 2024",
x = "Mês", y = "Número de registros",
caption = "Fonte: Defesa Civil do Recife. Possíveis repetições mantidas."
) +
theme_minimal(base_size = 12) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
grafico_regional <- ggplot(
resumo_regional, aes(x = reorder(regional, registros), y = registros)
) +
geom_col(fill = "#287A62", width = 0.75) +
coord_flip() +
labs(
title = "Registros por regional: ações datadas em 2024",
x = "Regional", y = "Número de registros",
caption = "Fonte: Defesa Civil do Recife. Possíveis repetições mantidas."
) +
theme_minimal(base_size = 12)
print(grafico_mensal)
print(grafico_regional)
O recorte contém 80.163 registros, após deixar fora da análise temporal 10 linhas sem uma data de ação pertencente a 2024. As possíveis repetições permanecem no recorte. A comparação mensal considera o volume e a duração de cada mês. A média por dia de calendário inclui como zero os dias sem linhas no arquivo. Ela mede registros observados e não comprova ausência de atendimento nas datas sem linhas.
calendario_2024 <- data.frame(
data_acao = seq(as.Date("2024-01-01"), as.Date("2024-12-31"), by = "day")
) %>%
mutate(
mes_numero = as.integer(format(data_acao, "%m")),
dia_numero = as.integer(format(data_acao, "%w"))
)
dias_por_mes <- calendario_2024 %>% count(mes_numero, name = "dias_calendario")
observado_por_mes <- dados_2024 %>%
group_by(mes_numero) %>%
summarise(registros = n(), dias_com_registro = n_distinct(data_acao),
.groups = "drop")
atividade_mensal <- dias_por_mes %>%
left_join(observado_por_mes, by = "mes_numero") %>%
mutate(
registros = coalesce(registros, 0L),
dias_com_registro = coalesce(dias_com_registro, 0L),
mes = factor(meses[mes_numero], levels = meses, ordered = TRUE),
registros_por_dia = registros / dias_calendario
)
knitr::kable(
atividade_mensal %>%
select(mes, registros, dias_calendario, dias_com_registro, registros_por_dia),
digits = 1,
col.names = c("Mês", "Registros", "Dias do mês", "Dias com registros",
"Registros por dia de calendário"),
caption = "Volume mensal e cobertura do calendário em 2024."
)
| Mês | Registros | Dias do mês | Dias com registros | Registros por dia de calendário |
|---|---|---|---|---|
| Janeiro | 7313 | 31 | 23 | 235.9 |
| Fevereiro | 6463 | 29 | 20 | 222.9 |
| Março | 10559 | 31 | 23 | 340.6 |
| Abril | 12070 | 30 | 26 | 402.3 |
| Maio | 8790 | 31 | 25 | 283.5 |
| Junho | 7555 | 30 | 23 | 251.8 |
| Julho | 7628 | 31 | 25 | 246.1 |
| Agosto | 5764 | 31 | 25 | 185.9 |
| Setembro | 4116 | 30 | 23 | 137.2 |
| Outubro | 3873 | 31 | 22 | 124.9 |
| Novembro | 3072 | 30 | 19 | 102.4 |
| Dezembro | 2960 | 31 | 19 | 95.5 |
pico_mensal <- atividade_mensal %>% slice_max(registros, n = 1, with_ties = FALSE)
menor_mes <- atividade_mensal %>% slice_min(registros, n = 1, with_ties = FALSE)
pico_media_diaria <- atividade_mensal %>%
slice_max(registros_por_dia, n = 1, with_ties = FALSE)
percentual_primeiro_semestre <- 100 *
sum(atividade_mensal$registros[atividade_mensal$mes_numero <= 6]) / total_analise
Abril concentra o maior volume, com 12.070 registros. O menor volume aparece em Dezembro, com 2.960. O primeiro semestre reúne 65,8% dos registros. O pico da média por dia de calendário também ocorre em Abril, com 402,3 registros por dia. Assim, a diferença de duração entre os meses não explica sozinha o pico.
A redução de volume ao longo do ano pode envolver mudanças na atuação ou no preenchimento da base. Sem dados de chuva e outros anos, não é possível atribuir os picos à precipitação nem confirmar sazonalidade que se repete anualmente.
Para comparar os dias da semana, divide-se o total de registros pela quantidade de ocorrências daquele dia no calendário. Alguns dias aparecem 53 vezes em 2024 e outros, 52 vezes. Datas sem linhas contribuem com zero registros observados.
dias_por_semana <- calendario_2024 %>% count(dia_numero, name = "dias_calendario")
observado_por_semana <- dados_2024 %>% count(dia_numero, name = "registros")
atividade_semanal <- dias_por_semana %>%
left_join(observado_por_semana, by = "dia_numero") %>%
mutate(
registros = coalesce(registros, 0L),
dia_semana = factor(dias[dia_numero + 1L], levels = dias, ordered = TRUE),
registros_por_dia = registros / dias_calendario
)
knitr::kable(
atividade_semanal %>% select(dia_semana, registros, dias_calendario, registros_por_dia),
digits = 1,
col.names = c("Dia da semana", "Registros", "Dias no calendário", "Registros por dia")
)
| Dia da semana | Registros | Dias no calendário | Registros por dia |
|---|---|---|---|
| Domingo | 0 | 52 | 0.0 |
| Segunda-feira | 14221 | 53 | 268.3 |
| Terça-feira | 13651 | 53 | 257.6 |
| Quarta-feira | 13203 | 52 | 253.9 |
| Quinta-feira | 16373 | 52 | 314.9 |
| Sexta-feira | 10724 | 52 | 206.2 |
| Sábado | 11991 | 52 | 230.6 |
ggplot(atividade_semanal, aes(x = dia_semana, y = registros_por_dia)) +
geom_col(fill = "#28668A", width = 0.75) +
labs(title = "Registros por dia da semana, ajustados ao calendário",
x = "Dia da semana", y = "Registros por dia de calendário",
caption = "Médias sobre todos os dias de 2024, com ou sem linhas na base.") +
theme_minimal(base_size = 12) +
theme(axis.text.x = element_text(angle = 35, hjust = 1))
pico_semanal <- atividade_semanal %>%
slice_max(registros_por_dia, n = 1, with_ties = FALSE)
nomes_sem_registro <- as.character(
atividade_semanal$dia_semana[atividade_semanal$registros == 0]
)
Quinta-feira apresenta a maior média, com 314,9 registros por dia de calendário. Os dias da semana sem registros no recorte são: Domingo. Essa ausência é uma característica do arquivo e não permite concluir que a Defesa Civil deixou de funcionar nesses dias. Há registros em 273 das 366 datas do ano.
A análise utiliza os rótulos de bairro após a padronização dos textos. Registros sem identificação do bairro são apresentados separadamente. Os percentuais usam como denominador todos os registros do recorte, inclusive aqueles com bairro ausente.
registros_sem_bairro <- sum(is.na(dados_2024$bairro))
ranking_bairros <- dados_2024 %>%
filter(!is.na(bairro)) %>%
count(bairro, name = "registros", sort = TRUE) %>%
mutate(percentual_total = 100 * registros / total_analise,
percentual_acumulado = cumsum(percentual_total))
top_bairros <- ranking_bairros %>% slice_head(n = 10)
participacao_top5 <- sum(head(ranking_bairros$registros, 5)) / total_analise * 100
knitr::kable(
top_bairros, digits = 1,
col.names = c("Bairro informado", "Registros", "% do total", "% acumulado"),
caption = "Dez rótulos de bairro com maior volume de registros."
)
| Bairro informado | Registros | % do total | % acumulado |
|---|---|---|---|
| Cohab | 13269 | 16.6 | 16.6 |
| Dois Unidos | 10620 | 13.2 | 29.8 |
| Nova Descoberta | 7666 | 9.6 | 39.4 |
| Varzea | 5545 | 6.9 | 46.3 |
| Agua Fria | 3726 | 4.6 | 50.9 |
| Vasco Da Gama | 3458 | 4.3 | 55.2 |
| Linha Do Tiro | 3430 | 4.3 | 59.5 |
| Ibura | 3416 | 4.3 | 63.8 |
| Jordao | 2701 | 3.4 | 67.2 |
| Macaxeira | 2438 | 3.0 | 70.2 |
ggplot(top_bairros, aes(x = reorder(bairro, registros), y = registros)) +
geom_col(fill = "#287A62", width = 0.75) +
coord_flip() +
labs(title = "Bairros com maior volume de registros",
x = "Bairro informado", y = "Número de registros",
caption = "Dez maiores categorias com bairro preenchido. Repetições mantidas.") +
theme_minimal(base_size = 12)
Os três rótulos mais frequentes são Cohab, Dois Unidos, Nova Descoberta. Os cinco primeiros concentram 50,9% do total. Outros 1.352 registros (1,7%) não possuem bairro identificado após o tratamento dos rótulos de ausência.
Essa concentração localiza os bairros mais presentes na base. Comparações de risco exigiriam denominadores como população exposta ou imóveis acompanhados. Também podem permanecer variações de grafia: os rótulos não foram validados contra um cadastro oficial de bairros.
Para comparar regionais de tamanhos distintos, calcula-se a participação das ações dentro de cada regional. Destacam-se as quatro ações preenchidas mais frequentes no recorte. As demais são agrupadas apenas nos gráficos em “Outras ações”. O grupo “Não informado” permanece separado e a base detalhada preserva as categorias originais.
ranking_acoes <- dados_2024 %>%
filter(!is.na(tipo_acao)) %>%
count(tipo_acao, name = "registros", sort = TRUE) %>%
mutate(percentual_total = 100 * registros / total_analise)
knitr::kable(
head(ranking_acoes, 6), digits = 1,
col.names = c("Tipo de ação", "Registros", "% de todos os registros"),
caption = "Ações preenchidas mais frequentes; ausências fora desta tabela."
)
| Tipo de ação | Registros | % de todos os registros |
|---|---|---|
| atendimento social | 30080 | 37.5 |
| acoes de porta-porta | 15383 | 19.2 |
| analise visual estrutural | 7698 | 9.6 |
| mapeamento de area de risco | 2487 | 3.1 |
| rocagem | 1954 | 2.4 |
| encaminhamentos aos parceiros | 848 | 1.1 |
acoes_principais <- head(ranking_acoes$tipo_acao, 4)
grupos_acoes <- c(str_to_sentence(acoes_principais, locale = "pt"),
"Outras ações", "Não informado")
dados_com_grupos <- dados_2024 %>%
mutate(
grupo_acao = case_when(
is.na(tipo_acao) ~ "Não informado",
tipo_acao %in% acoes_principais ~ str_to_sentence(tipo_acao, locale = "pt"),
TRUE ~ "Outras ações"
),
grupo_acao = factor(grupo_acao, levels = grupos_acoes)
)
composicao_regional <- dados_com_grupos %>%
count(regional, grupo_acao, name = "registros", .drop = FALSE) %>%
group_by(regional) %>%
mutate(percentual = 100 * registros / sum(registros)) %>%
ungroup()
cobertura_acoes <- dados_2024 %>%
group_by(regional) %>%
summarise(total = n(), informados = sum(!is.na(tipo_acao)),
nao_informados = sum(is.na(tipo_acao)), .groups = "drop") %>%
mutate(percentual_informado = 100 * informados / total) %>%
arrange(desc(percentual_informado))
knitr::kable(
cobertura_acoes, digits = 1,
col.names = c("Regional", "Registros", "Ação informada", "Não informada",
"% com ação informada"),
caption = "Cobertura do preenchimento do tipo de ação por regional."
)
| Regional | Registros | Ação informada | Não informada | % com ação informada |
|---|---|---|---|---|
| Planície | 7211 | 7207 | 4 | 99.9 |
| Sul | 14280 | 14255 | 25 | 99.8 |
| Noroeste | 16075 | 14691 | 1384 | 91.4 |
| Nordeste | 9110 | 6743 | 2367 | 74.0 |
| Oeste | 12950 | 7933 | 5017 | 61.3 |
| Norte | 20537 | 10416 | 10121 | 50.7 |
cores_acoes <- setNames(
c("#28668A", "#287A62", "#C58D2F", "#8266A4", "#AABBC7", "#DDDDDD"),
grupos_acoes
)
ggplot(composicao_regional, aes(x = regional, y = percentual, fill = grupo_acao)) +
geom_col(width = 0.75) +
coord_flip() +
scale_fill_manual(values = cores_acoes,
labels = function(x) str_wrap(x, width = 25), drop = FALSE) +
scale_y_continuous(labels = function(x) paste0(x, "%")) +
labs(title = "Composição das ações registradas por regional",
x = "Regional", y = "Percentual dos registros da regional", fill = "Ação",
caption = "Denominador: todos os registros de cada regional, incluindo ausências.") +
guides(fill = guide_legend(nrow = 3, byrow = TRUE)) +
theme_minimal(base_size = 11) +
theme(legend.position = "bottom")
acao_predominante <- ranking_acoes %>% slice_head(n = 1)
maior_cobertura_acao <- cobertura_acoes %>% slice_head(n = 1)
menor_cobertura_acao <- cobertura_acoes %>% slice_tail(n = 1)
# O denominador dos contrastes inclui todos os registros de cada regional.
social_noroeste <- dados_2024 %>% filter(regional == "Noroeste") %>%
summarise(percentual = 100 * sum(tipo_acao == "atendimento social", na.rm = TRUE) / n())
estrutural_sul <- dados_2024 %>% filter(regional == "Sul") %>%
summarise(percentual = 100 * sum(tipo_acao == "analise visual estrutural", na.rm = TRUE) / n())
Entre as ações preenchidas, atendimento social é a mais frequente, com 30.080 registros e 37,5% de todos os registros. Atendimento social representa 63,3% dos registros da Noroeste. Na Sul, análise visual estrutural representa 39,3% do total regional.
A cobertura de preenchimento do tipo de ação varia de 50,7% em Norte a 99,9% em Planície. Diferenças na composição podem refletir tanto a atuação registrada quanto diferenças de preenchimento.
O mapa de calor usa os mesmos grupos de ação. Cada coluna soma 100% e representa a composição dos registros de um mês. As cores indicam percentuais, permitindo comparar a participação das ações mesmo quando o volume mensal é diferente.
composicao_mensal <- dados_com_grupos %>%
count(mes_acao, grupo_acao, name = "registros", .drop = FALSE) %>%
group_by(mes_acao) %>%
mutate(percentual = 100 * registros / sum(registros)) %>%
ungroup()
ggplot(composicao_mensal, aes(x = mes_acao, y = grupo_acao, fill = percentual)) +
geom_tile(color = "white", linewidth = 0.4) +
scale_fill_gradient(low = "#F2F6F8", high = "#155A7E", name = "% no mês") +
scale_y_discrete(limits = rev(grupos_acoes),
labels = function(x) str_wrap(x, width = 24)) +
labs(title = "Participação dos grupos de ação nos registros mensais",
x = "Mês da ação", y = NULL,
caption = "As participações incluem a categoria de ação não informada.") +
theme_minimal(base_size = 11) +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid = element_blank())
peso_social_mensal <- dados_2024 %>%
group_by(mes_numero) %>%
summarise(
percentual = 100 * sum(tipo_acao == "atendimento social", na.rm = TRUE) / n(),
.groups = "drop"
)
A participação do atendimento social passa de 26,0% em janeiro para 73,1% em dezembro. O aumento da participação não significa, por si só, aumento do número absoluto de atendimentos sociais: o total de registros e o preenchimento das outras ações também variam. O resultado descreve uma mudança no perfil relativo da base ao longo de 2024.
A distribuição dos códigos deve ser analisada junto com a cobertura do campo. Ausência de classificação não equivale a ausência de risco. Os códigos são apresentados como constam no arquivo, sem atribuir significados de gravidade que não foram validados na documentação.
total_risco_informado <- sum(dados_2024$risco_informado)
percentual_risco_informado <- 100 * total_risco_informado / total_analise
distribuicao_risco <- dados_2024 %>%
filter(risco_informado) %>%
count(grau_risco, name = "registros") %>%
mutate(percentual_informados = 100 * registros / sum(registros)) %>%
arrange(grau_risco)
cobertura_risco <- dados_2024 %>%
group_by(regional) %>%
summarise(total = n(), informados = sum(risco_informado),
nao_informados = sum(!risco_informado), .groups = "drop") %>%
mutate(percentual_informado = 100 * informados / total) %>%
arrange(desc(percentual_informado))
knitr::kable(
distribuicao_risco, digits = 1,
col.names = c("Código de risco", "Registros", "% dos riscos preenchidos"),
caption = "Distribuição restrita aos registros com grau de risco preenchido."
)
| Código de risco | Registros | % dos riscos preenchidos |
|---|---|---|
| R1 | 2829 | 9.0 |
| R2 | 10727 | 34.2 |
| R3 | 16467 | 52.5 |
| R4 | 1336 | 4.3 |
knitr::kable(
cobertura_risco, digits = 1,
col.names = c("Regional", "Registros", "Risco informado", "Não informado",
"% com risco informado"),
caption = "Cobertura do grau de risco por regional."
)
| Regional | Registros | Risco informado | Não informado | % com risco informado |
|---|---|---|---|---|
| Noroeste | 16075 | 10856 | 5219 | 67.5 |
| Nordeste | 9110 | 5324 | 3786 | 58.4 |
| Oeste | 12950 | 5498 | 7452 | 42.5 |
| Norte | 20537 | 5874 | 14663 | 28.6 |
| Sul | 14280 | 3095 | 11185 | 21.7 |
| Planície | 7211 | 712 | 6499 | 9.9 |
risco_frequente <- distribuicao_risco %>%
slice_max(registros, n = 1, with_ties = FALSE)
O grau de risco está preenchido em 31.359 registros, equivalentes a 39,1% do recorte. Entre esses registros, o código R3 é o mais frequente, com 52,5% das classificações preenchidas. A participação se refere ao subconjunto classificado e não pode ser generalizada automaticamente para os registros sem informação.
A cobertura varia entre regionais. Um menor número de classificações pode estar associado a menor preenchimento. A tabela não permite ordenar as regionais por risco real.
Compara-se a base principal a um cenário que mantém apenas a primeira ocorrência de cada combinação de valores originais. Esse cenário não comprova que todas as linhas repetidas sejam erros e não transforma registros em solicitações ou pessoas únicas. A finalidade é verificar se as repetições alteram os resultados.
dados_sem_repeticoes <- dados_2024 %>% filter(!possivel_repeticao_original)
comparacao_regionais <- dados_2024 %>%
group_by(regional) %>%
summarise(com_repeticoes = n(),
sem_repeticoes = sum(!possivel_repeticao_original), .groups = "drop") %>%
mutate(
percentual_com = 100 * com_repeticoes / sum(com_repeticoes),
percentual_sem = 100 * sem_repeticoes / sum(sem_repeticoes),
diferenca_pp = percentual_sem - percentual_com
) %>%
arrange(desc(com_repeticoes))
knitr::kable(
comparacao_regionais, digits = 1,
col.names = c("Regional", "Com repetições", "Sem repetições", "% com",
"% sem", "Diferença (p.p.)"),
caption = "Participação regional nos dois cenários; cada cenário tem seu total."
)
| Regional | Com repetições | Sem repetições | % com | % sem | Diferença (p.p.) |
|---|---|---|---|---|---|
| Norte | 20537 | 18131 | 25.6 | 24.4 | -1.2 |
| Noroeste | 16075 | 15683 | 20.1 | 21.1 | 1.1 |
| Sul | 14280 | 13106 | 17.8 | 17.7 | -0.2 |
| Oeste | 12950 | 12010 | 16.2 | 16.2 | 0.0 |
| Nordeste | 9110 | 8900 | 11.4 | 12.0 | 0.6 |
| Planície | 7211 | 6402 | 9.0 | 8.6 | -0.4 |
ranking_com <- comparacao_regionais %>% arrange(desc(com_repeticoes)) %>% pull(regional)
ranking_sem <- comparacao_regionais %>% arrange(desc(sem_repeticoes)) %>% pull(regional)
mes_pico_sem_repeticoes <- dados_sem_repeticoes %>%
count(mes_acao, name = "registros") %>%
slice_max(registros, n = 1, with_ties = FALSE)
repeticoes_no_recorte <- sum(dados_2024$possivel_repeticao_original)
O cenário alternativo contém 74.232 registros, uma redução de 5.931 linhas (7,4%). A ordem das regionais por volume permanece igual. O mês com maior volume no cenário alternativo é Abril, com 10.593 registros.
Essa comparação distingue conclusões mantidas nos dois cenários de valores absolutos que dependem da política de tratamento. A base principal continua preservando todas as linhas do recorte temporal.
A análise descreveu a distribuição dos registros de atuação da Defesa Civil do Recife datados em 2024. A preparação envolveu padronização de textos, conversão de tipos, tratamento dos rótulos de ausência e marcação de possíveis repetições e inconsistências de data. O recorte foi definido pela data da ação.
O primeiro semestre reúne 65,8% dos registros, e o pico ocorre em Abril. Os cinco rótulos de bairro mais frequentes concentram 50,9% do total. O perfil das ações varia entre regionais e meses, mas sua interpretação depende do preenchimento dos campos.
A classificação de risco cobre 39,1% dos registros, limitando a generalização dos resultados desse campo. O cenário sem repetições exatas mantém o pico mensal em Abril, e a ordem regional permanece igual.
Para as equipes de gestão, a concentração de registros no primeiro semestre e o pico em Abril oferecem uma referência histórica para comparar o volume de atuação registrado com as escalas de trabalho e a disponibilidade de materiais naquele período. Essa comparação pode subsidiar a revisão da preparação operacional. A definição de uma escala para anos seguintes exige verificar se o padrão se mantém em outros anos e considerar a capacidade do serviço e as condições locais.
No território, a concentração nos cinco rótulos de bairro mais frequentes pode orientar a seleção de locais para examinar com mais detalhe os tipos de ação realizados e a cobertura do registro. Antes de utilizar esse ranking para distribuir recursos, seria necessário validar os nomes dos bairros e relacionar os volumes à população exposta, aos imóveis acompanhados e a informações de risco. Essa etapa permitiria avaliar se a concentração decorre do tamanho da área atendida, do perfil da atuação ou de diferenças na forma de registrar.
O contraste entre atendimento social na Noroeste (63,3% dos registros da regional) e análise visual estrutural na Sul (39,3%) fornece um ponto de partida para discutir a composição das atividades em cada regional. As equipes podem confrontar esse perfil com suas atribuições e rotinas de trabalho, examinando necessidades de articulação entre atendimento social e atividades de vistoria. A comparação deve considerar as diferenças de preenchimento do tipo de ação antes de orientar mudanças na organização das equipes.
Na qualidade dos dados, a regional Norte apresenta a menor cobertura de preenchimento do tipo de ação (50,7%). Esse resultado indica um ponto para revisar o fluxo de lançamento e conferir os critérios de preenchimento com os responsáveis pelos registros. Como o grau de risco está informado em 39,1% do recorte, também é necessário distinguir os casos em que o campo não se aplica daqueles em que houve falha de preenchimento. A revisão pode incluir orientações por tipo de ação, motivos de ausência e padronização das categorias.
Por fim, a ausência de registros em certos dias da semana deve motivar uma conferência da cobertura do arquivo e da rotina de lançamento antes de qualquer avaliação sobre escalas de atendimento. As linhas originalmente idênticas também precisam ser confrontadas com o processo que gera os dados antes de uma decisão de exclusão. A comparação entre cenários mostra quais resultados se mantêm apesar dessas repetições.
O estudo não estima risco por habitante, produtividade ou número de pessoas atendidas. As limitações incluem ausências de preenchimento, possíveis repetições, rótulos territoriais ainda não validados e desconhecimento da cobertura do sistema de registro. Outros anos e dados territoriais e meteorológicos permitiriam investigar explicações para os padrões observados, sem atribuir causalidade às associações descritivas.