#BAIXANDO E INSTALANDO PACOTES
packages <- c(
"remotes", "dplyr", "stringr", "purrr", "readr", "ggplot2",
"lubridate", "tibble", "broom", "forcats", "patchwork",
"scales", "knitr", "tidyr"
)
missing_packages <- setdiff(packages, rownames(installed.packages()))
if (length(missing_packages) > 0) {
install.packages(missing_packages)
}
if (!requireNamespace("microdatasus", quietly = TRUE)) {
remotes::install_github("rfsaldanha/microdatasus")
}
library(microdatasus)
library(dplyr)
##
## Anexando pacote: 'dplyr'
## Os seguintes objetos são mascarados por 'package:stats':
##
## filter, lag
## Os seguintes objetos são mascarados por 'package:base':
##
## intersect, setdiff, setequal, union
library(stringr)
library(purrr)
library(readr)
library(ggplot2)
library(lubridate)
##
## Anexando pacote: 'lubridate'
## Os seguintes objetos são mascarados por 'package:base':
##
## date, intersect, setdiff, union
library(tibble)
library(broom)
library(forcats)
library(patchwork)
## Warning: pacote 'patchwork' foi compilado no R versão 4.5.3
library(scales)
##
## Anexando pacote: 'scales'
## O seguinte objeto é mascarado por 'package:readr':
##
## col_factor
## O seguinte objeto é mascarado por 'package:purrr':
##
## discard
library(knitr)
## Warning: pacote 'knitr' foi compilado no R versão 4.5.3
library(tidyr)
#DEFININDO UF E INTERVALO TEMPORAL
uf <- "MT"
ano_inicio <- 2014
ano_fim <- 2023
#DEFININDO CIDS
cid_fungal_pulm <- c(
"B371" = "Candidíase pulmonar",
"B380" = "Coccidioidomicose pulmonar aguda",
"B381" = "Coccidioidomicose pulmonar crônica",
"B382" = "Coccidioidomicose pulmonar não especificada",
"B390" = "Histoplasmose pulmonar aguda por Histoplasma capsulatum",
"B391" = "Histoplasmose pulmonar crônica por Histoplasma capsulatum",
"B392" = "Histoplasmose pulmonar por Histoplasma capsulatum não especificada",
"B400" = "Blastomicose pulmonar aguda",
"B401" = "Blastomicose pulmonar crônica",
"B410" = "Paracoccidioidomicose pulmonar",
"B420" = "Esporotricose pulmonar",
"B440" = "Aspergilose pulmonar invasiva",
"B441" = "Outra aspergilose pulmonar",
"B450" = "Criptococose pulmonar",
"B460" = "Mucormicose pulmonar",
"B590" = "Pneumocistose",
"J172" = "Pneumonia em micoses"
)
cid_codes <- names(cid_fungal_pulm)
cid_labels <- tibble(
cid = names(cid_fungal_pulm),
descricao = unname(cid_fungal_pulm)
)
cid_labels
## # A tibble: 17 × 2
## cid descricao
## <chr> <chr>
## 1 B371 Candidíase pulmonar
## 2 B380 Coccidioidomicose pulmonar aguda
## 3 B381 Coccidioidomicose pulmonar crônica
## 4 B382 Coccidioidomicose pulmonar não especificada
## 5 B390 Histoplasmose pulmonar aguda por Histoplasma capsulatum
## 6 B391 Histoplasmose pulmonar crônica por Histoplasma capsulatum
## 7 B392 Histoplasmose pulmonar por Histoplasma capsulatum não especificada
## 8 B400 Blastomicose pulmonar aguda
## 9 B401 Blastomicose pulmonar crônica
## 10 B410 Paracoccidioidomicose pulmonar
## 11 B420 Esporotricose pulmonar
## 12 B440 Aspergilose pulmonar invasiva
## 13 B441 Outra aspergilose pulmonar
## 14 B450 Criptococose pulmonar
## 15 B460 Mucormicose pulmonar
## 16 B590 Pneumocistose
## 17 J172 Pneumonia em micoses
#DEFININDO BASE DE DADOS E PROCESSANDO OS DADOS
sim_raw <- fetch_datasus(
year_start = ano_inicio,
year_end = ano_fim,
uf = uf,
information_system = "SIM-DO"
)
## ℹ Your local Internet connection seems to be ok.
## ℹ DataSUS FTP server seems to be up and reachable.
## ℹ Starting download...
sim <- process_sim(sim_raw)
glimpse(sim)
## Rows: 201,395
## Columns: 101
## $ CONTADOR <chr> "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", …
## $ ORIGEM <chr> "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1…
## $ TIPOBITO <chr> "Não Fetal", "Não Fetal", "Não Fetal", "Não Fetal", "Não …
## $ DTOBITO <chr> "2014-01-01", "2014-01-01", "2014-01-01", "2014-01-01", "…
## $ HORAOBITO <chr> "1700", "1710", "0825", "2025", "0212", "0900", "2200", "…
## $ CODMUNNATU <chr> "500515", "231270", "352430", "210830", NA, "510760", "50…
## $ DTNASC <chr> "1973-12-12", "1969-07-10", "1938-10-19", "1986-12-31", N…
## $ IDADE <chr> "440", "444", "475", "427", NA, "423", "476", "453", "485…
## $ SEXO <chr> "Feminino", "Masculino", "Feminino", "Feminino", "Masculi…
## $ RACACOR <chr> "Parda", "Parda", "Branca", "Preta", "Parda", "Parda", "B…
## $ ESTCIV <chr> "Solteiro", "Casado", "Viúvo", "União consensual", NA, "U…
## $ ESC <chr> "4 a 7 anos", "1 a 3 anos", "4 a 7 anos", "1 a 3 anos", N…
## $ ESC2010 <chr> "2", "1", "2", "1", "9", "2", "1", "1", "2", "1", "0", NA…
## $ SERIESCFAL <chr> NA, "2", NA, NA, NA, NA, "4", NA, "5", NA, NA, NA, NA, NA…
## $ CODMUNRES <chr> "510340", "510794", "510340", "510454", "510560", "510760…
## $ LOCOCOR <chr> "Hospital", "Hospital", "Hospital", "Hospital", "Domicíli…
## $ CODESTAB <chr> "2311682", "2392801", "2604388", "2795655", NA, NA, "2390…
## $ ESTABDESCR <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ CODMUNOCOR <chr> "510340", "510794", "510340", "510792", "510560", "510760…
## $ IDADEMAE <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ ESCMAE <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ ESCMAE2010 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ SERIESCMAE <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ QTDFILVIVO <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ QTDFILMORT <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ GRAVIDEZ <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ SEMAGESTAC <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ GESTACAO <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ PARTO <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ OBITOPARTO <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ PESO <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ TPMORTEOCO <chr> "8", NA, NA, "4", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ OBITOGRAV <chr> "Não", NA, NA, "Não", NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ OBITOPUERP <chr> "Não", NA, NA, "De 0 a 42 dias", NA, NA, NA, NA, NA, NA, …
## $ ASSISTMED <chr> "Sim", "Sim", "Sim", "Sim", NA, "Não", "Sim", "Sim", "Sim…
## $ EXAME <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ CIRURGIA <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ NECROPSIA <chr> "Não", "Não", "Não", "Sim", "Não", "Sim", "Não", "Não", N…
## $ LINHAA <chr> "*R578", "*R092", "*R578", "*R092", "*R960", "*T794", "*R…
## $ LINHAB <chr> "*J960", "*B199", "*I500", "*O882", NA, NA, "*I219", "*E1…
## $ LINHAC <chr> "*B24X", "*J960", "*J189", NA, NA, "*X994", "*I251", NA, …
## $ LINHAD <chr> NA, "*C349", "*J440*J449", NA, NA, NA, NA, NA, NA, NA, NA…
## $ LINHAII <chr> NA, NA, "*E039*I10X*E149", "*D571*F172", NA, NA, NA, NA, …
## $ CAUSABAS <chr> "B24", "B199", "J440", "O882", "R960", "X994", "I219", "E…
## $ CB_PRE <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ CRM <chr> "4463", "5404", "4463", "1368", "3886", "1607", "4289", "…
## $ COMUNSVOIM <chr> NA, NA, NA, "510792", NA, "510760", NA, NA, NA, NA, NA, N…
## $ DTATESTADO <chr> "2014-01-01", "2014-01-01", "2014-01-01", "2014-01-02", "…
## $ CIRCOBITO <chr> NA, NA, NA, NA, NA, "Homicídio", NA, NA, NA, NA, NA, NA, …
## $ ACIDTRAB <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ FONTE <chr> NA, "Hospital", NA, NA, NA, "Outro", NA, NA, NA, NA, NA, …
## $ NUMEROLOTE <chr> "20140019", "20140001", "20140001", "20150006", "20140002…
## $ TPPOS <chr> "Investigado", NA, NA, "Investigado", "Investigado", "Não…
## $ DTINVESTIG <chr> "2014-05-20", NA, NA, "2014-01-03", "2014-01-10", NA, NA,…
## $ CAUSABAS_O <chr> "B24", "B199", "J440", "R99", "R960", "X994", "I219", "E1…
## $ DTCADASTRO <chr> "2014-01-23", "2014-01-07", "2014-01-23", "2014-01-09", "…
## $ ATESTANTE <chr> "Substituto", "Outro", "Substituto", "IML", "Outro", "IML…
## $ STCODIFICA <chr> "S", "N", "S", "S", "N", "S", "S", "S", "S", "S", "S", "S…
## $ CODIFICADO <chr> "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S", "S…
## $ VERSAOSIST <chr> "3.2.00", "3.2.00", "3.2.00", "3.2.00", "3.2.00", "3.2.00…
## $ VERSAOSCB <chr> "3.2", NA, "3.2", "3.2", NA, "3.2", "3.2", "3.2", "3.2", …
## $ FONTEINV <chr> "Estabelecimento de saúde / Prontuário", NA, NA, "Múltipl…
## $ DTRECEBIM <chr> "2014-06-27", "2014-01-08", "2014-01-23", "2015-02-13", "…
## $ ATESTADO <chr> "R578/J960/B24", "R092/B199/J960/C349", "R578/I500/J189/J…
## $ DTRECORIGA <chr> "2014-01-23", "2014-01-08", "2014-01-23", "2014-01-10", "…
## $ CAUSAMAT <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ ESCMAEAGR1 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ ESCFALAGR1 <chr> "11", "01", "11", "10", "09", "11", "02", "10", "03", "10…
## $ STDOEPIDEM <chr> "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0…
## $ STDONOVA <chr> "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0…
## $ DIFDATA <chr> "0177", "0007", "0022", "0408", "0020", "0023", "0006", "…
## $ NUDIASOBCO <chr> "0139", NA, NA, "0041", NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ NUDIASOBIN <chr> "0154", NA, NA, "0041", NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ DTCADINV <chr> "04062014", NA, NA, "11022014", NA, NA, NA, NA, NA, NA, N…
## $ TPOBITOCOR <chr> "9", NA, NA, "5", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DTCONINV <chr> "20052014", NA, NA, "11022014", NA, NA, NA, NA, NA, NA, N…
## $ FONTES <chr> "XXSXXX", NA, NA, "SSSXSX", NA, NA, NA, NA, NA, NA, NA, N…
## $ TPRESGINFO <chr> NA, NA, NA, "1", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ TPNIVELINV <chr> "E", NA, NA, "M", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ NUDIASINF <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ DTCADINF <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ MORTEPARTO <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ DTCONCASO <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ FONTESINF <chr> "XXXXXXX", "XXXXXXX", "XXXXXXX", "XXXXXXX", "XXXXXXX", "X…
## $ ALTCAUSA <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ NATURAL <chr> "MATO GROSSO DO SUL", "CEARA", "SAO PAULO", "MARANHAO", N…
## $ IDADEminutos <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ IDADEhoras <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ IDADEdias <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ IDADEmeses <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ IDADEanos <chr> "40", "44", "75", "27", NA, "23", "76", "53", "85", "71",…
## $ OCUP <chr> NA, "Pedreiro", NA, NA, NA, "Empregado domestico nos serv…
## $ munResStatus <chr> "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "AT…
## $ munResTipo <chr> "MUNIC", "MUNIC", "MUNIC", "MUNIC", "MUNIC", "MUNIC", "MU…
## $ munResNome <chr> "Cuiabá", "Tabaporã", "Cuiabá", "Itanhangá", "Matupá", "R…
## $ munResUf <chr> "Mato Grosso", "Mato Grosso", "Mato Grosso", "Mato Grosso…
## $ munResLat <chr> "-15.56999", "-11.30751", "-15.56999", "-12.23477", "-10.…
## $ munResLon <chr> "-56.07325", "-56.82483", "-56.07325", "-56.64934", "-54.…
## $ munResAlt <chr> "243", "335", "243", "351", "284", "232", "465", "232", "…
## $ munResArea <chr> "3291.812", "8317.428", "3291.812", "2898.075", "5239.67"…
## $ OCUPMAE <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
normalize_cid <- function(x) {
x <- as.character(x)
x <- str_to_upper(x)
str_replace_all(x, "[^A-Z0-9]", "")
}
get_year_sim <- function(x) {
if (inherits(x, c("Date", "POSIXct", "POSIXt"))) {
return(lubridate::year(x))
}
x_chr <- as.character(x)
out <- rep(NA_integer_, length(x_chr))
idx_ddmmaaaa <- str_detect(x_chr, "^\\d{8}$")
out[idx_ddmmaaaa] <- suppressWarnings(
as.integer(substr(x_chr[idx_ddmmaaaa], 5, 8))
)
idx_iso <- is.na(out) & str_detect(x_chr, "^\\d{4}-\\d{2}-\\d{2}")
out[idx_iso] <- suppressWarnings(
as.integer(substr(x_chr[idx_iso], 1, 4))
)
idx_brasil <- is.na(out) & str_detect(x_chr, "^\\d{2}/\\d{2}/\\d{4}")
out[idx_brasil] <- suppressWarnings(
as.integer(substr(x_chr[idx_brasil], 7, 10))
)
out
}
normalize_cbo <- function(x) {
x <- as.character(x)
x <- str_replace_all(x, "[^0-9]", "")
x <- if_else(x == "", NA_character_, x)
x
}
clean_txt <- function(x) {
x <- as.character(x)
x <- iconv(x, from = "", to = "ASCII//TRANSLIT")
x <- str_to_lower(x)
x <- str_squish(x)
x
}
decode_idade_sim_anos <- function(x) {
x <- str_pad(as.character(x), width = 3, side = "left", pad = "0")
unidade <- substr(x, 1, 1)
valor <- suppressWarnings(as.numeric(substr(x, 2, 3)))
case_when(
unidade %in% c("0", "1", "2", "3") ~ 0,
unidade == "4" ~ valor,
unidade == "5" ~ 100 + valor,
TRUE ~ NA_real_
)
}
sim_filtrado <- sim %>%
mutate(
ano_obito = get_year_sim(DTOBITO),
cid_basica = normalize_cid(CAUSABAS),
fungal_pulm_basica = cid_basica %in% cid_codes
)
casos_basica <- sim_filtrado %>%
filter(fungal_pulm_basica) %>%
left_join(cid_labels, by = c("cid_basica" = "cid"))
nrow(casos_basica)
## [1] 50
head(casos_basica)
## # A tibble: 6 × 105
## CONTADOR ORIGEM TIPOBITO DTOBITO HORAOBITO CODMUNNATU DTNASC IDADE SEXO
## <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 9208 1 Não Fetal 2014-07-18 1300 510780 1938-10… 475 Masc…
## 2 11005 1 Não Fetal 2014-08-25 2120 354140 1956-03… 458 Masc…
## 3 13168 1 Não Fetal 2014-10-09 1410 412770 1963-02… 451 Masc…
## 4 1849 1 Não Fetal 2015-02-25 1240 411150 1976-12… 438 Masc…
## 5 5793 1 Não Fetal 2015-06-09 1300 411342 1970-02… 445 Masc…
## 6 5825 1 Não Fetal 2015-07-12 1130 292200 1968-06… 447 Masc…
## # ℹ 96 more variables: RACACOR <chr>, ESTCIV <chr>, ESC <chr>, ESC2010 <chr>,
## # SERIESCFAL <chr>, CODMUNRES <chr>, LOCOCOR <chr>, CODESTAB <chr>,
## # ESTABDESCR <chr>, CODMUNOCOR <chr>, IDADEMAE <chr>, ESCMAE <chr>,
## # ESCMAE2010 <chr>, SERIESCMAE <chr>, QTDFILVIVO <chr>, QTDFILMORT <chr>,
## # GRAVIDEZ <chr>, SEMAGESTAC <chr>, GESTACAO <chr>, PARTO <chr>,
## # OBITOPARTO <chr>, PESO <chr>, TPMORTEOCO <chr>, OBITOGRAV <chr>,
## # OBITOPUERP <chr>, ASSISTMED <chr>, EXAME <chr>, CIRURGIA <chr>, …
resumo_ano <- casos_basica %>%
count(ano_obito, name = "obitos") %>%
arrange(ano_obito)
resumo_cid <- casos_basica %>%
count(cid_basica, descricao, name = "obitos") %>%
arrange(desc(obitos))
resumo_ano
## # A tibble: 10 × 2
## ano_obito obitos
## <int> <int>
## 1 2014 3
## 2 2015 10
## 3 2016 3
## 4 2017 3
## 5 2018 4
## 6 2019 4
## 7 2020 4
## 8 2021 8
## 9 2022 6
## 10 2023 5
resumo_cid
## # A tibble: 8 × 3
## cid_basica descricao obitos
## <chr> <chr> <int>
## 1 B410 Paracoccidioidomicose pulmonar 25
## 2 B400 Blastomicose pulmonar aguda 6
## 3 B450 Criptococose pulmonar 5
## 4 B401 Blastomicose pulmonar crônica 4
## 5 B440 Aspergilose pulmonar invasiva 4
## 6 B441 Outra aspergilose pulmonar 3
## 7 B371 Candidíase pulmonar 2
## 8 B460 Mucormicose pulmonar 1
p_obitos_ano <- ggplot(resumo_ano, aes(x = ano_obito, y = obitos)) +
geom_line(color = "#001437", linewidth = 1) +
geom_point(color = "#001437", size = 2.5) +
# NOVA CAMADA: Adiciona os números em cima dos pontos
geom_text(
aes(label = obitos),
vjust = -1.0, # Empurra o texto ligeiramente para CIMA do ponto
size = 3.8, # Tamanho da fonte do número
fontface = "bold", # Deixa o número em negrito
color = "#001437" # Mantém o padrão azul marinho
) +
labs(
x = "Ano do óbito",
y = "Óbitos",
caption = "Fonte: MS/SVSA/CGIAE - Sistema de Informações sobre Mortalidade (SIM)"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
panel.grid.minor = element_blank(),
# Como os números já estão nos pontos, podemos opcionalmente limpar a grade horizontal
panel.grid.major.y = element_line(color = "gray95")
) +
# Expande o topo do gráfico para o número do pico não cortar na borda
scale_y_continuous(expand = expansion(mult = c(0.1, 0.15)))
p_obitos_ano

sim_agro <- sim_filtrado %>%
mutate(
ocup_cbo = if (
exists("sim_raw") &&
"OCUP" %in% names(sim_raw) &&
nrow(sim_raw) == nrow(sim_filtrado)
) {
normalize_cbo(sim_raw$OCUP)
} else {
NA_character_
},
ocup_nome = if ("OCUP" %in% names(sim_filtrado)) {
as.character(OCUP)
} else {
NA_character_
},
ocup_nome_limpa = clean_txt(ocup_nome)
)
padrao_agro_texto <- paste(
c(
"agric", "agropec", "pecuar", "lavour", "lavrador",
"produtor rural", "trabalhador rural", "fazend", "horticult",
"fruticult", "tratorista", "vaqueir", "boiadeir",
"ordenhador", "granjeir", "avicult", "suinicult"
),
collapse = "|"
)
sim_agro <- sim_agro %>%
mutate(
ocup_missing = is.na(ocup_cbo) &
(
is.na(ocup_nome_limpa) |
ocup_nome_limpa == "" |
str_detect(ocup_nome_limpa, "ignorado|nao informado|sem informacao")
),
agro_por_cbo = !is.na(ocup_cbo) & str_detect(ocup_cbo, "^6"),
agro_por_texto = !is.na(ocup_nome_limpa) &
str_detect(ocup_nome_limpa, padrao_agro_texto),
trabalho_agro = case_when(
ocup_missing ~ NA,
agro_por_cbo | agro_por_texto ~ TRUE,
TRUE ~ FALSE
)
)
qualidade_ocupacao <- sim_agro %>%
summarise(
total_obitos = n(),
ocupacao_ausente = sum(is.na(trabalho_agro)),
pct_ocupacao_ausente = 100 * mean(is.na(trabalho_agro)),
trabalho_agro = sum(trabalho_agro == TRUE, na.rm = TRUE),
pct_trabalho_agro = 100 * mean(trabalho_agro == TRUE, na.rm = TRUE)
)
qualidade_ocupacao
## # A tibble: 1 × 5
## total_obitos ocupacao_ausente pct_ocupacao_ausente trabalho_agro
## <int> <int> <dbl> <int>
## 1 201395 24445 12.1 17989
## # ℹ 1 more variable: pct_trabalho_agro <dbl>
sim_agro %>%
filter(trabalho_agro == TRUE) %>%
count(ocup_cbo, ocup_nome, sort = TRUE) %>%
head(50)
## # A tibble: 50 × 3
## ocup_cbo ocup_nome n
## <chr> <chr> <int>
## 1 622020 Trabalhador volante da agricultura 5508
## 2 621005 Trabalhador agropecuario em geral 4237
## 3 622005 Caseiro (agricultura) 2100
## 4 612005 Produtor agricola polivalente 1960
## 5 611005 Produtor agropecuario, em geral 950
## 6 641010 Operador de maquinas de beneficiamento de produtos agricolas 449
## 7 641015 Tratorista agricola 349
## 8 622010 Jardineiro 256
## 9 631210 Pescador profissional 252
## 10 631105 Pescador artesanal de agua doce 243
## # ℹ 40 more rows
fungicos_agro <- sim_agro %>%
filter(fungal_pulm_basica == TRUE) %>%
count(trabalho_agro, name = "obitos") %>%
mutate(
proporcao = obitos / sum(obitos),
pct = 100 * proporcao
)
fungicos_agro
## # A tibble: 3 × 4
## trabalho_agro obitos proporcao pct
## <lgl> <int> <dbl> <dbl>
## 1 FALSE 30 0.6 60
## 2 TRUE 12 0.24 24
## 3 NA 8 0.16 16
fungicos_agro_ano <- sim_agro %>%
filter(fungal_pulm_basica == TRUE) %>%
count(ano_obito, trabalho_agro, name = "obitos") %>%
group_by(ano_obito) %>%
mutate(
pct_no_ano = 100 * obitos / sum(obitos)
) %>%
ungroup()
p_agro_ano <- ggplot(
fungicos_agro_ano %>% filter(!is.na(trabalho_agro)),
aes(x = ano_obito, y = obitos, color = trabalho_agro)
) +
geom_line(linewidth = 1) +
geom_point(size = 2.5) +
# Contagens de óbitos flutuando sobre cada linha
geom_text(
aes(label = obitos),
vjust = -1.2, # Empurra o número um pouco para cima do ponto
size = 3.5, # Tamanho adequado para não poluir
fontface = "bold", # Deixa os números em negrito
show.legend = FALSE # Impede que a letra "a" apareça dentro da legenda lateral
) +
scale_color_manual(
values = c("FALSE" = "#f8cc27", "TRUE" = "#001437"),
labels = c("FALSE" = "Não Agropecuário", "TRUE" = "Agropecuário")
) +
labs(
title = "Óbitos por pneumopatias fúngicas segundo ocupação",
subtitle = "SIM - causa básica",
x = "Ano do óbito",
y = "Óbitos",
color = "Trabalho agropecuário",
caption = "Fonte: MS/SVSA/CGIAE - Sistema de Informações sobre Mortalidade (SIM)"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
panel.grid.minor = element_blank()
) +
# Garante um respiro no topo do gráfico para os números mais altos não cortarem
scale_y_continuous(expand = expansion(mult = c(0.1, 0.2)))
p_agro_ano

analise_assoc <- sim_agro %>%
filter(
!is.na(trabalho_agro),
!is.na(fungal_pulm_basica)
) %>%
mutate(
idade_anos = decode_idade_sim_anos(IDADE),
faixa_etaria = cut(
idade_anos,
breaks = c(0, 20, 40, 60, 80, Inf),
right = FALSE,
labels = c("0-19", "20-39", "40-59", "60-79", "80+")
)
)
analise_assoc %>%
summarise(
n = n(),
obitos_fungicos = sum(fungal_pulm_basica),
pct_obitos_fungicos = 100 * mean(fungal_pulm_basica),
pct_trabalho_agro = 100 * mean(trabalho_agro)
)
## # A tibble: 1 × 4
## n obitos_fungicos pct_obitos_fungicos pct_trabalho_agro
## <int> <int> <dbl> <dbl>
## 1 176950 42 0.0237 10.2
sexo_por_desfecho <- analise_assoc %>%
filter(
!is.na(SEXO),
SEXO %in% c("Masculino", "Feminino"),
!is.na(fungal_pulm_basica)
) %>%
mutate(
grupo = if_else(
fungal_pulm_basica == TRUE,
"Pneumopatia fúngica",
"Demais causas"
)
) %>%
count(grupo, SEXO) %>%
group_by(grupo) %>%
mutate(
pct = 100 * n / sum(n),
pct_formatado = sprintf("%.1f%%", pct)
) %>%
ungroup()
sexo_por_desfecho
## # A tibble: 4 × 5
## grupo SEXO n pct pct_formatado
## <chr> <chr> <int> <dbl> <chr>
## 1 Demais causas Feminino 68349 38.6 38.6%
## 2 Demais causas Masculino 108541 61.4 61.4%
## 3 Pneumopatia fúngica Feminino 4 9.52 9.5%
## 4 Pneumopatia fúngica Masculino 38 90.5 90.5%
tabela_faixa_etaria_pct <- analise_assoc %>%
filter(!is.na(faixa_etaria)) %>%
count(faixa_etaria) %>%
mutate(
Porcentagem = 100 * (n / sum(n)),
Porcentagem = sprintf("%.2f%%", Porcentagem)
) %>%
select(faixa_etaria, Porcentagem) %>%
rename(`Faixa Etária` = faixa_etaria)
kable(
tabela_faixa_etaria_pct,
caption = "Distribuição percentual dos óbitos segundo faixa etária",
align = c("l", "c")
)
Distribuição percentual dos óbitos segundo faixa
etária
| 0-19 |
2.33% |
| 20-39 |
11.72% |
| 40-59 |
23.25% |
| 60-79 |
39.66% |
| 80+ |
23.05% |
tabela_faixa_etaria_pct
## # A tibble: 5 × 2
## `Faixa Etária` Porcentagem
## <fct> <chr>
## 1 0-19 2.33%
## 2 20-39 11.72%
## 3 40-59 23.25%
## 4 60-79 39.66%
## 5 80+ 23.05%
tabela_assoc <- table(
Trabalho_agro = analise_assoc$trabalho_agro,
Pneumopatia_fungica = analise_assoc$fungal_pulm_basica
)
tabela_assoc
## Pneumopatia_fungica
## Trabalho_agro FALSE TRUE
## FALSE 158931 30
## TRUE 17977 12
prop.table(tabela_assoc, margin = 1) * 100
## Pneumopatia_fungica
## Trabalho_agro FALSE TRUE
## FALSE 99.98112745 0.01887255
## TRUE 99.93329257 0.06670743
teste_fisher <- fisher.test(tabela_assoc)
teste_fisher
##
## Fisher's Exact Test for Count Data
##
## data: tabela_assoc
## p-value = 0.000722
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
## 1.648604 7.114097
## sample estimates:
## odds ratio
## 3.536274
phi_coef <- cor(
as.integer(analise_assoc$trabalho_agro),
as.integer(analise_assoc$fungal_pulm_basica),
use = "complete.obs"
)
tab_descritiva <- analise_assoc %>%
filter(!is.na(trabalho_agro), !is.na(fungal_pulm_basica)) %>%
mutate(
grupo = if_else(
trabalho_agro,
"Trabalho agropecuário",
"Demais ocupações"
)
) %>%
group_by(grupo) %>%
summarise(
total_obitos = n(),
obitos_pneumopatia_fungica = sum(fungal_pulm_basica),
percentual = 100 * obitos_pneumopatia_fungica / total_obitos,
.groups = "drop"
) %>%
mutate(
percentual = sprintf("%.4f%%", percentual)
)
tab_resumo_bruto <- tibble(
Medida = c(
"Odds ratio bruto - Fisher",
"IC95% inferior",
"IC95% superior",
"p-valor",
"Coeficiente phi"
),
Valor = c(
sprintf("%.2f", unname(teste_fisher$estimate)),
sprintf("%.2f", teste_fisher$conf.int[1]),
sprintf("%.2f", teste_fisher$conf.int[2]),
formatC(teste_fisher$p.value, format = "e", digits = 3),
sprintf("%.4f", phi_coef)
)
)
kable(tab_descritiva, caption = "Proporção de óbitos por pneumopatias fúngicas segundo ocupação")
Proporção de óbitos por pneumopatias fúngicas segundo
ocupação
| Demais ocupações |
158961 |
30 |
0.0189% |
| Trabalho agropecuário |
17989 |
12 |
0.0667% |
kable(tab_resumo_bruto, caption = "Medidas brutas de associação")
Medidas brutas de associação
| Odds ratio bruto - Fisher |
3.54 |
| IC95% inferior |
1.65 |
| IC95% superior |
7.11 |
| p-valor |
7.220e-04 |
| Coeficiente phi |
0.0094 |
analise_assoc <- analise_assoc %>%
mutate(
ano_centrado = ano_obito - min(ano_obito, na.rm = TRUE)
)
modelo_agro_ajustado <- glm(
fungal_pulm_basica ~ trabalho_agro + faixa_etaria + SEXO + ano_centrado,
data = analise_assoc,
family = binomial()
)
summary(modelo_agro_ajustado)
##
## Call:
## glm(formula = fungal_pulm_basica ~ trabalho_agro + faixa_etaria +
## SEXO + ano_centrado, family = binomial(), data = analise_assoc)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -9.56487 1.13755 -8.408 < 2e-16 ***
## trabalho_agroTRUE 0.94933 0.34736 2.733 0.00628 **
## faixa_etaria20-39 -0.11897 1.09685 -0.108 0.91362
## faixa_etaria40-59 0.47192 1.03234 0.457 0.64757
## faixa_etaria60-79 -0.12078 1.03625 -0.117 0.90721
## faixa_etaria80+ -0.78547 1.12222 -0.700 0.48397
## SEXOMasculino 1.54743 0.53369 2.899 0.00374 **
## ano_centrado -0.02812 0.05376 -0.523 0.60099
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 785.02 on 176882 degrees of freedom
## Residual deviance: 752.98 on 176875 degrees of freedom
## (67 observations deleted due to missingness)
## AIC: 768.98
##
## Number of Fisher Scoring iterations: 12
or_modelo_ajustado <- broom::tidy(modelo_agro_ajustado) %>%
mutate(
OR = exp(estimate),
conf.low = exp(estimate - 1.96 * std.error),
conf.high = exp(estimate + 1.96 * std.error),
OR_IC95 = sprintf("%.2f (%.2f–%.2f)", OR, conf.low, conf.high),
p_valor = case_when(
p.value < 0.001 ~ "<0,001",
TRUE ~ gsub("\\.", ",", sprintf("%.3f", p.value))
)
)
or_modelo_ajustado %>%
select(term, OR_IC95, p_valor)
## # A tibble: 8 × 3
## term OR_IC95 p_valor
## <chr> <chr> <chr>
## 1 (Intercept) 0.00 (0.00–0.00) <0,001
## 2 trabalho_agroTRUE 2.58 (1.31–5.10) 0,006
## 3 faixa_etaria20-39 0.89 (0.10–7.62) 0,914
## 4 faixa_etaria40-59 1.60 (0.21–12.13) 0,648
## 5 faixa_etaria60-79 0.89 (0.12–6.75) 0,907
## 6 faixa_etaria80+ 0.46 (0.05–4.11) 0,484
## 7 SEXOMasculino 4.70 (1.65–13.38) 0,004
## 8 ano_centrado 0.97 (0.88–1.08) 0,601
forest_data <- broom::tidy(modelo_agro_ajustado) %>%
filter(
term != "(Intercept)",
!term %in% c("ano_obito", "ano_centrado")
) %>%
mutate(
OR = exp(estimate),
conf.low = exp(estimate - 1.96 * std.error),
conf.high = exp(estimate + 1.96 * std.error),
variavel = case_when(
term == "trabalho_agroTRUE" ~ "Trabalho agropecuário/rural",
term == "SEXOMasculino" ~ "Sexo masculino",
term == "faixa_etaria20-39" ~ "Idade 20–39 anos",
term == "faixa_etaria40-59" ~ "Idade 40–59 anos",
term == "faixa_etaria60-79" ~ "Idade 60–79 anos",
term == "faixa_etaria80+" ~ "Idade ≥80 anos",
TRUE ~ term
),
ordem = case_when(
variavel == "Trabalho agropecuário/rural" ~ 1,
variavel == "Sexo masculino" ~ 2,
variavel == "Idade 20–39 anos" ~ 3,
variavel == "Idade 40–59 anos" ~ 4,
variavel == "Idade 60–79 anos" ~ 5,
variavel == "Idade ≥80 anos" ~ 6,
TRUE ~ 99
),
significativo = conf.low > 1 | conf.high < 1,
ic_label = sprintf("%.2f (%.2f–%.2f)", OR, conf.low, conf.high),
p_label = case_when(
p.value < 0.001 ~ "<0,001",
TRUE ~ gsub("\\.", ",", sprintf("%.3f", p.value))
)
) %>%
arrange(ordem) %>%
mutate(
variavel = factor(variavel, levels = rev(variavel))
)
x_min <- min(forest_data$conf.low, na.rm = TRUE) * 0.8
x_max <- max(forest_data$conf.high, na.rm = TRUE) * 1.15
p_left <- ggplot(forest_data, aes(x = OR, y = variavel)) +
geom_vline(xintercept = 1, linetype = "dashed", color = "#aeb6c1", linewidth = 0.7) +
geom_errorbarh(
aes(xmin = conf.low, xmax = conf.high, color = significativo),
height = 0.18,
linewidth = 0.9
) +
geom_point(
aes(color = significativo),
size = 3.5
) +
scale_color_manual(
values = c(`TRUE` = "#001437", `FALSE` = "#68707e"),
guide = "none"
) +
scale_x_log10(
limits = c(x_min, x_max),
breaks = c(0.05, 0.1, 0.5, 1, 2, 5, 10, 20),
labels = c("0,05", "0,1", "0,5", "1", "2", "5", "10", "20")
) +
labs(
x = "Odds ratio ajustado",
y = NULL
) +
theme_minimal(base_size = 14) +
theme(
panel.grid.minor = element_blank(),
panel.grid.major.y = element_blank(),
axis.text.y = element_text(size = 13),
axis.text.x = element_text(size = 12),
axis.title.x = element_text(size = 15),
plot.margin = margin(10, 10, 10, 10)
)
p_right <- ggplot(forest_data, aes(y = variavel)) +
geom_text(
aes(
x = 1.0,
label = ic_label,
fontface = ifelse(significativo, "bold", "plain"),
color = significativo
),
hjust = 0,
size = 5
) +
geom_text(
aes(
x = 3.4,
label = p_label,
fontface = ifelse(significativo, "bold", "plain"),
color = significativo
),
hjust = 0,
size = 5
) +
scale_color_manual(
values = c(`TRUE` = "#001437", `FALSE` = "#68707e"),
guide = "none"
) +
annotate(
"text",
x = 1.0,
y = length(levels(forest_data$variavel)) + 0.55,
label = "OR ajustado (IC95%)",
hjust = 0,
fontface = "bold",
size = 5.2,
color = "black"
) +
annotate(
"text",
x = 3.4,
y = length(levels(forest_data$variavel)) + 0.55,
label = "p-valor",
hjust = 0,
fontface = "bold",
size = 5.2,
color = "black"
) +
coord_cartesian(xlim = c(0.9, 4.4), clip = "off") +
theme_void(base_size = 14) +
theme(
plot.margin = margin(10, 35, 10, 0)
)
# 3. Juntando os painéis e colorindo os títulos gerais
p_forest_report <- p_left + p_right +
plot_layout(widths = c(2.35, 1.45)) +
plot_annotation(
title = "Fatores associados a óbitos por pneumopatias fúngicas",
subtitle = "Regressão logística ajustada",
caption = "IC95% = intervalo de confiança de 95%."
) &
theme(
plot.title = element_text(face = "bold", size = 20, hjust = 0, color = "black"),
plot.subtitle = element_text(size = 15, hjust = 0, color = "#68707e"),
plot.caption = element_text(size = 11, hjust = 1, color = "#68707e"),
plot.margin = margin(10, 10, 10, 10)
)
p_forest_report

dados_corr <- analise_assoc %>%
transmute(
pneumopatia_fungica = as.integer(fungal_pulm_basica),
trabalho_agro = as.integer(trabalho_agro),
sexo_masculino = as.integer(SEXO == "Masculino"),
idade_20_39 = as.integer(faixa_etaria == "20-39"),
idade_40_59 = as.integer(faixa_etaria == "40-59"),
idade_60_79 = as.integer(faixa_etaria == "60-79"),
idade_80mais = as.integer(faixa_etaria == "80+")
)
corr_outcome <- dados_corr %>%
summarise(
trabalho_agro = cor(pneumopatia_fungica, trabalho_agro, use = "complete.obs"),
sexo_masculino = cor(pneumopatia_fungica, sexo_masculino, use = "complete.obs"),
idade_20_39 = cor(pneumopatia_fungica, idade_20_39, use = "complete.obs"),
idade_40_59 = cor(pneumopatia_fungica, idade_40_59, use = "complete.obs"),
idade_60_79 = cor(pneumopatia_fungica, idade_60_79, use = "complete.obs"),
idade_80mais = cor(pneumopatia_fungica, idade_80mais, use = "complete.obs")
) %>%
pivot_longer(
cols = everything(),
names_to = "variavel",
values_to = "phi"
) %>%
mutate(
variavel = case_when(
variavel == "trabalho_agro" ~ "Trabalho agropecuário",
variavel == "sexo_masculino" ~ "Sexo masculino",
variavel == "idade_20_39" ~ "Idade 20–39 anos",
variavel == "idade_40_59" ~ "Idade 40–59 anos",
variavel == "idade_60_79" ~ "Idade 60–79 anos",
variavel == "idade_80mais" ~ "Idade ≥80 anos",
TRUE ~ variavel
)
)
p_phi <- ggplot(corr_outcome, aes(x = phi, y = fct_reorder(variavel, phi))) +
geom_vline(xintercept = 0, linetype = "dashed") +
geom_col(fill = "#001437", width = 0.7) +
geom_text(
aes(label = sprintf("%.4f", phi)),
hjust = ifelse(corr_outcome$phi >= 0, -0.1, 1.1),
size = 3.8,
fontface = "bold",
color = "gray10"
) +
labs(
title = "Correlação phi com Pneumopatias Fúngicas",
x = "Coeficiente phi",
y = NULL
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(hjust = 0.5, face = "bold"),
panel.grid.minor = element_blank()
)
p_phi

# Altere para o nome da pasta predefinida do seu projeto
resultados <- "C:/Users/nicol/Searches/Pneumopatias fúngicas/SIM"
write_csv(
casos_basica,
file.path(resultados, paste0("casos_pneumopatias_fungicas_", uf, "_", ano_inicio, "_", ano_fim, ".csv"))
)
write_csv(
resumo_ano,
file.path(resultados, paste0("resumo_ano_pneumopatias_fungicas_", uf, "_", ano_inicio, "_", ano_fim, ".csv"))
)
write_csv(
resumo_cid,
file.path(resultados, paste0("resumo_cid_pneumopatias_fungicas_", uf, "_", ano_inicio, "_", ano_fim, ".csv"))
)
write_csv(
tab_descritiva,
file.path(resultados, paste0("tabela_descritiva_ocupacao_", uf, "_", ano_inicio, "_", ano_fim, ".csv"))
)
write_csv(
tab_resumo_bruto,
file.path(resultados, paste0("resumo_associacao_bruta_", uf, "_", ano_inicio, "_", ano_fim, ".csv"))
)
write_csv(
or_modelo_ajustado,
file.path(resultados, paste0("modelo_logistico_ajustado_", uf, "_", ano_inicio, "_", ano_fim, ".csv"))
)
ggsave(
file.path(resultados, "forest_plot_relatorio.png"),
p_forest_report,
width = 16,
height = 6,
dpi = 320,
bg = "white"
)
ggsave(
file.path(resultados, "phi_correlation.png"),
p_phi,
width = 16,
height = 5,
dpi = 320,
bg = "white"
)