O presente relatório automatizado tem como objetivo reportar os resultados de análises de duplicidades e inconsistências dos dados do Sistema de Informação sobre Mortalidade (SIM). Estas análises representam uma importante etapa de trabalho com dados, denominada checagem de dados. A etapa de checagem de dados visa principalmente a identificação de erros de mensuração (erros de preenchimento/digitação; e dados inconsistentes/aberrantes), assim como de dados ausentes, em branco ou ignorados. Depois de analisar cuidadosamente estas situações, busca-se corrigir os problemas identificados em sua origem ou retificar os problemas encontrados nos bancos de dados, tendo em vista possibilitar a execução de etapas posteriores de processamento e análise de dados.
Um conjunto de 30 críticas de qualidade, organizadas em 7 blocos, foi aplicado aos dados preliminares sobre óbitos fetais e não fetais do SIM (2023). Os blocos de avaliação da qualidade dos dados do SIM incluem: (i) críticas gerais sobre município de ocorrência/residência do falecido, local de ocorrência do óbito, estabelecimentos de saúde e duplicidades de registros; (ii) críticas preliminares sobre o preenchimento da causa básica de morte; (iii) críticas gerais sobre a validade da causa básica e das causas associadas ao óbito; (iv) críticas específicas sobre os óbitos fetais; (v) críticas específicas sobre os óbitos não fetais e a variável idade; (vi) críticas específicas sobre os óbitos não fetais e a variável sexo; e, (vii) críticas específicas relativas às condições maternas. O usuário pode acessar facilmente os resultados das análises de qualidade por meio a tabela de conteúdo, apresentada à esquerda deste relatório.
Esta mesma rotina pode ser aplicada a qualquer conjunto de dados do SIM, sendo necessário simplesmente informar os arquivos de dados de interesse na fase de importação de microdados. Espera-se que este produto contribua para o aperfeiçoamento da qualidade das informações do SIM, assim como para a agilidade das atividades regulares de produção e disseminação de informações relevantes sobre a mortalidade no Brasil.
Para executar a rotina de checagem de dados, será necessário
instalar/carregar os pacotes tidyverse, rio,
openxlsx e hablar. O pacote
tidyverse reúne uma série de ferramentas de ciência de
dados, bastante úteis para realizar tarefas corriqueiras com dados
tabulares. O pacote rio contém as funções
import() e export(), capazes de realizar a
importação e a exportação de dados em variadas extensões. O pacote
openxlsx permite operações sofisticadas de importação e
exportação de arquivos em formato Excel, sendo usado especialmente na
construção de um arquivo de auditoria dos dados SIM. O pacote
hablar oferece recursos seguros para operações aritméticas
com variáveis que tenham dados faltantes, indefinições matemáticas ou
valores infinitos. Adicionalmente, o pacote pacman foi
usado para o carregamento dos pacotes supracitados (isto porque, caso
algum pacote não esteja instalado localmente, o mesmo será instalado
automaticamente).
t0 <- Sys.time()
pacman::p_load(tidyverse, rio, openxlsx, hablar)
Esta rotina de checagem de dados começou em 2024-05-24 14:29:49.014656.
Esta seção apresenta os códigos de importação dos microdados do SIM
(2023). Foram selecionadas 36 variáveis (ls_vars) para a
checagem de dados. Os dados de óbitos fetais foram importados
diretamente do arquivo bruto em formato *.dbf. Os dados de
óbitos não fetais passaram por uma etapa anterior de ingestão de
arquivos em formato *.dbc. Aqui, ambos os conjuntos de
dados são importados e combinados no objeto sim_crude.
ls_vars <- c("NUMERODO", "NUMERODV", "CODINST", "TIPOBITO", "DTNASC", "DTOBITO", "SEXO", "IDADE", "CODMUNRES", "CODMUNOCOR", "LOCOCOR", "CODESTAB", "IDADEMAE", "ESCMAE", "ESCMAE2010", "SERIESCMAE", "OCUPMAE", "QTDFILVIVO", "QTDFILMORT", "GESTACAO", "SEMAGESTAC", "GRAVIDEZ", "PARTO", "OBITOPARTO", "PESO", "NUMERODN", "OBITOGRAV", "OBITOPUERP", "TPMORTEOCO", "CAUSABAS", "LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII", "ATESTADO")
sim_crude <-
bind_rows(
import("./sim_data_treated/sim_crude_data_2023_temp.csv", colClasses = "character", select = ls_vars),
import("./sim_data_raw/DOFET23/DOFET23.dbf", colClasses = "character") %>% select(any_of(ls_vars)))
Um resumo da estrutura e do conteúdo do objeto sim_crude
é apresentado abaixo:
glimpse(sim_crude)
## Rows: 1,485,653
## Columns: 36
## $ NUMERODO <chr> "32971990", "33648744", "31408707", "32970175", "27406350",…
## $ NUMERODV <chr> "4", "4", "9", "4", "6", "8", "6", "3", "9", "1", "4", "1",…
## $ CODINST <chr> "MAC1200100001", "MAC1200200002", "MAC1200300001", "MRO1100…
## $ TIPOBITO <chr> "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2",…
## $ DTNASC <chr> "26011941", "20081966", "15061968", "14111965", "12021958",…
## $ DTOBITO <chr> "01012023", "01012023", "01012023", "01012023", "01012023",…
## $ SEXO <chr> "1", "2", "2", "1", "2", "1", "1", "1", "1", "1", "1", "2",…
## $ IDADE <chr> "481", "456", "454", "457", "464", "431", "423", "462", "44…
## $ CODMUNRES <chr> "120070", "120020", "120030", "120040", "120035", "120043",…
## $ CODMUNOCOR <chr> "120010", "120020", "120030", "110010", "120035", "120040",…
## $ LOCOCOR <chr> "1", "3", "1", "1", "1", "1", "5", "1", "3", "5", "4", "1",…
## $ CODESTAB <chr> "2001500", "", "2000636", "2497468", "2001594", "2001578", …
## $ IDADEMAE <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "23", "…
## $ ESCMAE <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "3", ""…
## $ ESCMAE2010 <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "2", ""…
## $ SERIESCMAE <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",…
## $ OCUPMAE <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "999992…
## $ QTDFILVIVO <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "03", "…
## $ QTDFILMORT <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "00", "…
## $ GESTACAO <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "5", ""…
## $ SEMAGESTAC <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "38", "…
## $ GRAVIDEZ <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "1", ""…
## $ PARTO <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "2", ""…
## $ OBITOPARTO <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "3", ""…
## $ PESO <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "2334",…
## $ NUMERODN <chr> "", "", "", "", "", "", "", "", "", "", "", "", "", "889992…
## $ OBITOGRAV <chr> "", "2", "", "", "9", "", "", "", "", "", "", "", "", "", "…
## $ OBITOPUERP <chr> "", "3", "", "", "9", "", "", "", "", "", "", "", "", "", "…
## $ TPMORTEOCO <chr> "", "8", "", "", "9", "", "", "", "", "", "", "", "", "", "…
## $ CAUSABAS <chr> "C349", "J159", "I219", "C169", "B342", "J189", "X935", "B5…
## $ LINHAA <chr> "*N189", "", "*I219", "*C787*C788", "*J960", "*A419", "*R57…
## $ LINHAB <chr> "*D649", "*J159*U049", "*I249", "*C169", "*J159", "*A418", …
## $ LINHAC <chr> "", "", "", "", "*B342*U071", "*J189", "*X935", "*B57X", ""…
## $ LINHAD <chr> "", "", "", "", "", "*J969", "", "", "", "", "", "", "", ""…
## $ LINHAII <chr> "*I11X*C349", "*I10X", "*F10X", "", "*I10X*I500", "", "", "…
## $ ATESTADO <chr> "N189/D649*I11 C349", "/J159 U049*I10", "I219/I249*F10", "C…
Esta seção apresenta os códigos de importação de dados auxiliares, ou
seja, material de apoio à checagem de dados. O objeto
aux_data contém uma lista de tabelas de referência para
análises de inconsistências dos campos relacionados às causas de morte.
Estas tabelas foram elaboradas pela equipe técnica da CGIAE/SVSA/MS. O
objeto tb_munic contém informações gerais sobre os
municípios brasileiros, especialmente seus códigos IBGE. O objeto
tb_sim_cnes contém informações básicas sobre os
estabelecimentos de saúde registrados no conjunto de dados de interesse
(sim_crude), inclusive informando se os códigos numéricos
dos estabelecimentos de saúde são válidos no CNES. As informações sobre
os estabelecimentos de saúde foram recuperadas em uma fase anterior de
checagem de dados.
aux_data <- import_list("../../auxiliary/TabAux_10_CID_10_v2021_RFSA.xlsx")
tb_munic <- import("../../auxiliary/aux_tables.xlsx", sheet = 1) %>% filter(SCOPE %in% 7:8)
tb_sim_cnes <- import("./sim_data_results/tb_cnes_sim_data_2023_temp/df_search_cnes_api.csv", colClasses = "character")
Este bloco é composto por três críticas gerais sobre os dados do SIM, incluindo duplicidades de registros, inconsistências dos campos município de ocorrência e município de residência do falecido e inconsistências entre as variáveis local de ocorrência do óbito e código do estabelecimento de saúde.
Inicialmente, verificou-se a quantidade de caracteres dos números das DO. Todos os registros tiveram 8 caracteres no número da DO.
sim_crude %>% count(str_count(NUMERODO))
Posteriormente, verificou-se a presença de registros com o mesmo
número de DO. Esta crítica retorna os casos notificados em duplicidade,
por terem sido informados em duas instalações distintas. Um total de 20
registros apresentou repetição de número de DO. Os resultados foram
armazenados no objeto tb_c29.
tb_c29 <- janitor::get_dupes(sim_crude, "NUMERODO", "NUMERODV")
tb_c29
Também, foram identificados 4 registros com o mesmo número de DO e com as mesmas informações de data de nascimento e sexo.
janitor::get_dupes(sim_crude, "NUMERODO", "NUMERODV", "DTNASC", "SEXO") # NOME
Definição: Pesquisam-se os registros em que os campos munícipio de residência e município de ocorrência estejam em branco. Caso não seja possível recuperar o código exato do município, a regra é usar o código da UF e “0000”, por exemplo, “530000” ou “330000”.
sort(setdiff(unique(c(sim_crude$CODMUNRES, sim_crude$CODMUNOCOR)), tb_munic$LOCAL_CODE))
## [1] "110000" "120000" "130000" "150000" "170000" "210000" "220000" "230000"
## [9] "240000" "250000" "260000" "280000" "290000" "310000" "320000" "330000"
## [17] "350000" "410000" "420000" "430000" "500000" "510000" "520000"
sim_crude %>% count(is.na(CODMUNRES), is.na(CODMUNOCOR))
sim_crude %>% count(CODMUNRES == "", CODMUNOCOR == "")
Não foram identificados códigos inválidos ou em branco para os
municípios de residência e ocorrência. Os resultados foram armazenados
no objeto tb_c26
tb_c26 <- sim_crude %>% filter(CODMUNRES == "" | CODMUNOCOR == "")
tb_c26
Definição: Pesquisam-se os registros onde o local de ocorrência é: (i) Hospital ou outros estabelecimentos de saúde (LOCOCOR = 1 ou 2) e o código de estabelecimento esteja em branco; (ii) Domicílio, via pública, outros e ignorado (LOCOCOR = 3, 4, 5 ou 9) e o código de estabelecimento de saúde esteja preenchido.
sim_crude %>% count(LOCOCOR)
sim_crude %>% count(CODESTAB == "")
sim_crude %>% filter(LOCOCOR %in% 1:2, CODESTAB == "") %>% count()
sim_crude %>% filter(!LOCOCOR %in% 1:2, CODESTAB != "") %>% count()
Não foram identificadas inconsistências para esta regra. Isto é,
houve preenchimento da variável CODESTAB para os óbitos
ocorridos em hospitais e outros estabelecimentos de saúde, assim como
não houve preenchimento desta variável para os óbitos ocorridos em
domicílios, vias públicas e outros locais. Entretanto, foram
identificados 337 códigos inválidos de CNES no total de 11.572 códigos,
o que corresponde a 405.590 óbitos.
tb_sim_cnes %>% count(fl_status)
sim_crude %>%
filter(CODESTAB %in% tb_sim_cnes$codigo_cnes[tb_sim_cnes$fl_status == "status error"]) %>%
count()
Os resultados foram armazenados no objeto tb_c28.
tb_c28 <-
sim_crude %>%
filter(LOCOCOR %in% 1:2, CODESTAB %in% tb_sim_cnes$codigo_cnes[tb_sim_cnes$fl_status == "status error"])
tb_c28
Este bloco apresenta resultados preliminares sobre o preenchimento da causa básica de morte, incluindo a verificação de causas não codificadas e de códigos que não começam com letra e/ou não terminam com número ou “X”.
sim_crude %>% count(str_count(CAUSABAS))
sim_crude %>% count(str_detect(CAUSABAS, "^[:alpha:]"), str_detect(CAUSABAS, "[:digit:]$"))
Os resultados foram armazenados no objeto tb_c00.
tb_c00 <- sim_crude %>% filter(!str_detect(CAUSABAS, "^[:alpha:]") | !str_detect(CAUSABAS, "[:digit:]$"))
tb_c00
Este bloco é composto por dez críticas gerais sobre o preenchimento da causa básica e das causas associadas ao óbito, conforme apresentado a seguir.
Definição: Nesta consulta devemos procurar os registros onde a causa básica de morte, linhas A, B, C, D e parte II do atestado médico estejam em branco.
sim_crude %>%
mutate(across(c("CAUSABAS", "LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII", "ATESTADO"), ~str_remove_all(., "[^[:alnum:]]"))) %>%
mutate(across(c("CAUSABAS", "LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII", "ATESTADO"), ~str_to_upper(.))) %>%
mutate(across(c("CAUSABAS", "LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII", "ATESTADO"), ~dplyr::na_if(., ""))) %>%
summarise(NA_CAUSABAS = sum_(is.na(CAUSABAS)),
NA_LINHAA = sum_(is.na(LINHAA)),
NA_LINHAB = sum_(is.na(LINHAB)),
NA_LINHAC = sum_(is.na(LINHAC)),
NA_LINHAD = sum_(is.na(LINHAD)),
NA_LINHAII = sum_(is.na(LINHAII)),
NA_ATESTADO = sum_(is.na(ATESTADO)))
Não foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c01.
tb_c01 <-
sim_crude %>%
mutate(across(c("CAUSABAS", "LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII", "ATESTADO"), ~str_remove_all(., "[^[:alnum:]]"))) %>%
mutate(across(c("CAUSABAS", "LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII", "ATESTADO"), ~str_to_upper(.))) %>%
mutate(across(c("CAUSABAS", "LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII", "ATESTADO"), ~dplyr::na_if(., ""))) %>%
filter(is.na(LINHAA), is.na(LINHAB), is.na(LINHAC), is.na(LINHAD), is.na(LINHAII))
tb_c01
Definição: Nesta consulta são apresentados os casos com CID que não existem na tabela CID10, ou que apresentam falta de um caracter.
icd10_codes <- aux_data$TabAux_10_CID_10_v2021$SUBCAT4c # 12.481 codigos
sim_crude %>% count(C02_CAUSABAS = !CAUSABAS %in% icd10_codes) # OK!
Não foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c02.
tb_c02 <- sim_crude %>% filter(!CAUSABAS %in% icd10_codes)
tb_c02
Definição: Pesquisam-se os registros com CID excluído na última publicação da CID-10. Estes códigos continuam na versão 3.2 do SCB/SIM, mas só devem ser usados para óbitos ocorridos até 2009.
icd10_codes <- c("C141", "M723", "M725", "Q314", "Q350", "Q352", "Q354", "Q356", "R500", "R501", "X591", "X592", "X593", "X594", "X595", "X596", "X597", "X598") # 18 codigos excluidos
sim_crude %>% count(C12_CAUSABAS = CAUSABAS %in% icd10_codes) # PROBLEMA!
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c12.
tb_c12 <- sim_crude %>% filter(CAUSABAS %in% icd10_codes)
tb_c12
Definição: Estes CIDs são definidos como aqueles que não podem ser usados como causa básica de morte.
#icd10_codes <- aux_data$TabAux_02_CIDs_que_nao_podem_se %>% mutate(REGEX = `CID Inicial` == `CID Final`)
icd10_codes <- c("B9[5-7]|E89|F0[1-9]|F1[0-9]0|F7[0-9]|G8[1-3]|G97|H54[0-7]|H59|H9[0-1,5]|I15[8-9]|I23|I240|I252|I5[0-2]|I6[5-6]|I97|J95|K91|M9[6-7,9]|N46|O08|O30|O8[0-4]|P0[7-8]|P70[3-9]|P71|P720|P72[2-9]|P7[3-4]|R69|Y9|[S,T,Z]")
sim_crude %>% count(C23_CAUSABAS = str_detect(CAUSABAS, icd10_codes)) # PROBLEMA!
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c23.
tb_c23 <- sim_crude %>% filter(str_detect(CAUSABAS, icd10_codes))
tb_c23
Definição: As causas asterisco não podem ser causa básica de morte e devem ser substituídas por uma causa cruz.
icd10_codes <- aux_data$TabAux_01_Causas_asterisco$CO_CATEG_SUBCATEG_SP # 370 codigos
sim_crude %>% count(C14_CAUSABAS = CAUSABAS %in% icd10_codes) # PROBLEMA!
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c14.
tb_c14 <- sim_crude %>% filter(CAUSABAS %in% icd10_codes)
tb_c14
Definição: Pesquisam-se os registros com CID de causa básica definida como trivial.
icd10_codes <- aux_data$TabAux_05_CID_10_v2008_triviais$SUBCAT4c # 1.142 codigos
sim_crude %>% count(C13_CAUSABAS = CAUSABAS %in% icd10_codes) # PROBLEMA!
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c13.
tb_c13 <- sim_crude %>% filter(CAUSABAS %in% icd10_codes)
tb_c13
Definição: Pesquisam-se os registros onde a causa básica de morte não tenha plausibilidade epidemiológica de ocorrer no Brasil ou na UF de ocorrência, ou ainda tenham códigos mais adequados para representa-las.
icd10_codes <- c("W00|X3[4-5]|Z|Y36|R4[1-2,5-6]|I460|I469")
sim_crude %>% count(C22_CAUSABAS = str_detect(CAUSABAS, icd10_codes)) # PROBLEMA!
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c22.
tb_c22 <- sim_crude %>% filter(str_detect(CAUSABAS, icd10_codes))
tb_c22
Definição: Pesquisam-se os registros com CID de causa básica de morte que constam na lista de afecções improváveis da CID10, volume 2.
icd10_codes <- aux_data$TabAux_06_CID_10_v2008_Improváv$SUBCAT4c # 78 codigos
sim_crude %>% count(C27_CAUSABAS = CAUSABAS %in% icd10_codes) # PROBLEMA!
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c27.
tb_c27 <- sim_crude %>% filter(CAUSABAS %in% icd10_codes)
tb_c27
Definição: Pesquisam-se os registros em que a causa de óbito é uma doença erradicada ou controlada, as causas U que indicam o aparecimento de novas doenças ainda sem códigos específicos definidos na CID10, ou o código de resultado de exame (R75).
icd10_codes <- c("A00|A20|A80|A82|B03|B05|R75|U")
sim_crude %>% count(C16_CAUSABAS = str_detect(CAUSABAS, icd10_codes)) # PROBLEMA! 1 ocorrência
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c16.
tb_c16 <- sim_crude %>% filter(str_detect(CAUSABAS, icd10_codes))
tb_c16
Definição: A listagem de óbitos com causas incluídas, nesta pesquisa, tem como objetivo estimular as atitudes de vigilância ativa, com fins a contribuir com o SINAN e a vigilância epidemiológica em geral.
icd10_codes <- aux_data$`Lista de Afecções de interesse `$COD_CID # 268 codigos
sim_crude %>% count(C15_CAUSABAS = CAUSABAS %in% icd10_codes)
Foram encontrados registros de interesse para esta regra. Os
resultados foram armazenados no objeto tb_c15.
tb_c15 <- sim_crude %>% filter(CAUSABAS %in% icd10_codes)
tb_c15
Inicialmente, apresentam-se as contagens e as proporções de óbitos fetais e não fetais.
sim_crude %>% count(TIPOBITO) %>% mutate(prop = round((n/sum_(n))*100,2))
Este bloco é composto por seis críticas específicas sobre o preenchimento da causa básica, conforme apresentado a seguir.
Definição: Pesquisam-se os registros onde o tipo de óbito seja não fetal (TIPOBITO = 2) ou nulo (em branco) e o nome do falecido contenha a palavra “natimorto” ou “morto” em qualquer parte do nome, ou começar com as palavras “feto”, “nm”, “fm” ou “nati”. Esta pesquisa baseia-se no conceito que natimorto acontece somente em óbitos fetais (TIPOBITO = 1).
Embora a variável “NOME” não esteja disponível, apresentam-se os códigos que podem ser usados nesta análise.
sim_crude %>%
filter(!TIPOBITO %in% 1) %>%
mutate(NOME = str_to_lower(NOME)) %>%
count(C03_NOME = str_detect(NOME, "natimorto|morto|feto|nm|fm|nati"))
Definição: Pesquisam-se os registros onde o tipo de óbito seja fetal (TIPOBITO = 1) ou nulo (em branco) e o nome do falecido comece com “RN” (recém-nascido). Esta pesquisa baseia-se no conceito que recém-nascido acontece somente em óbitos não fetais (TIPOBITO = 2).
Embora a variável “NOME” não esteja disponível, apresentam-se os códigos que podem ser usados nesta análise.
sim_crude %>%
filter(!TIPOBITO %in% 2) %>%
mutate(NOME = str_to_lower(NOME)) %>%
count(C03_NOME = str_detect(NOME, "^rn"))
Definição: Pesquisam-se os registros de óbitos fetais (TIPOBITO = 1) com idade ou data de nascimento preenchida.
sim_crude %>%
filter(TIPOBITO %in% 1) %>%
count(IDADE, DTNASC)
Não foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c05.
tb_c05 <-
sim_crude %>%
filter(TIPOBITO %in% 1) %>%
filter(!is.na(IDADE) | !is.na(DTNASC))
tb_c05
Definição: Esta listagem busca óbitos do tipo fetal onde a causa básica de morte não coincide com os CID de causas de óbitos fetais.
icd10_codes <- aux_data$TabAux_07_CID_10_v2008_Fetal$CO_CATEG_SUBCATEG_SP # 895 codigos
sim_crude %>%
filter(TIPOBITO %in% 1) %>%
count(C19_CAUSABAS = !CAUSABAS %in% icd10_codes) #
Não foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c19.
tb_c19 <- sim_crude %>% filter(TIPOBITO %in% 1, !CAUSABAS %in% icd10_codes)
tb_c19
Definição: Pesquisam-se os óbitos não fetais onde a causa básica de morte esteja preenchido com o CID P95 que só pode ser usado para causa exclusivamente fetal.
icd10_codes <- c("P560|P569|P95")
sim_crude %>%
filter(TIPOBITO %in% 2) %>%
count(C25_CAUSABAS = str_detect(CAUSABAS, icd10_codes)) # PROBLEMA!
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c25.
tb_c25 <- sim_crude %>% filter(TIPOBITO %in% 2, str_detect(CAUSABAS, icd10_codes))
tb_c25
Definição: Pesquisam-se os registros onde um ou mais campos do bloco de informações sobre menores de 1 ano ou óbitos fetais estejam preenchidos em falecidos maiores de 1 ano. Trata-se do bloco V do modelo antigo da DO, ou bloco IV do modelo novo da DO.
sim_crude %>%
filter(str_detect(IDADE, "40[1-9]|^4[1-9]|^5")) %>%
count(IDADEMAE, ESCMAE, ESCMAE2010, SERIESCMAE, OCUPMAE, QTDFILVIVO, QTDFILMORT, GESTACAO, SEMAGESTAC,
GRAVIDEZ, PARTO, OBITOPARTO, PESO, NUMERODN) # OK!
Não foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c24.
tb_c24 <-
sim_crude %>%
filter(str_detect(IDADE, "40[1-9]|^4[1-9]|^5")) %>%
mutate(across(c("IDADEMAE", "ESCMAE", "ESCMAE2010", "SERIESCMAE", "OCUPMAE", "QTDFILVIVO", "QTDFILMORT",
"GESTACAO", "SEMAGESTAC", "GRAVIDEZ", "PARTO", "OBITOPARTO", "PESO",
"NUMERODN"), ~dplyr::na_if(., ""))) %>%
filter(!is.na(IDADEMAE), !is.na(ESCMAE), !is.na(ESCMAE2010), !is.na(SERIESCMAE), !is.na(OCUPMAE),
!is.na(QTDFILVIVO), !is.na(QTDFILMORT), !is.na(GESTACAO), !is.na(SEMAGESTAC), !is.na(GRAVIDEZ),
!is.na(PARTO), !is.na(OBITOPARTO), !is.na(PESO), !is.na(NUMERODN))
tb_c24
Este bloco é composto por cinco críticas específicas sobre o preenchimento da causa básica, conforme apresentado a seguir.
Definição: Pesquisam-se os registros onde o tipo de óbito seja não fetal (TIPOBITO = 2) e idade não está preenchida.
sim_crude %>%
filter(TIPOBITO %in% 2) %>%
mutate(across(c("IDADE", "DTNASC"), ~str_remove_all(., "[^[:digit:]]"))) %>%
count(IDADE == "", DTNASC == "") # OK!
Não foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c07.
tb_c07 <-
sim_crude %>%
mutate(across(c("IDADE", "DTNASC"), ~str_remove_all(., "[^[:digit:]]"))) %>%
filter(TIPOBITO %in% 2) %>%
filter(IDADE == "")
tb_c07
Definição: Pesquisam-se os registros de óbitos com idade maior que 125 anos, ou seja, uma idade pouco provável.
sim_crude %>% filter(TIPOBITO %in% 2, str_detect(IDADE, "52[5-9]|^5[3-9]")) %>% count()
Não foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c06.
tb_c06 <- sim_crude %>% filter(TIPOBITO %in% 2, str_detect(IDADE, "52[5-9]|^5[3-9]"))
tb_c06
Definição: Pesquisam-se os registros, com valores inválidos para
idade. Assim, se o óbito for não fetal, considerar as seguintes idades
inconsistentes e os respectivos valores corretos esperados:
- idade 0, 00 ou 000 quando o correto deveria ser 999;
- Idade 061 quando o correto deveria ser 101;
- Idade de 062 a 098 quando o correto deveria ser 099;
- Idade 124 quando o correto deveria ser 201;
- Idade de125 a 199 quando o correto deveria ser 100;
- Idade 230 quando o correto deveria ser 301;
- Idade de 231 a 300 quando o correto deveria ser 200;
- Idade de 312 quando o correto deveria ser 401;
- Idade de 313 a 399 quando o correto deveria ser 300.
sim_crude %>%
filter(TIPOBITO %in% 2, IDADE == "0"|IDADE == "00"|IDADE == "000"|IDADE == "061"|IDADE == "124"|IDADE == "230"|IDADE == "312"|str_detect(IDADE, "06[2-9]|^0[7-8]|09[0-8]")|str_detect(IDADE, "12[5-9]|^1[3-9]")|str_detect(IDADE, "23[1-9]|^2[4-9]|300")|str_detect(IDADE, "31[3-9]^3[2-9]")) %>%
count()
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c11.
tb_c11 <-
sim_crude %>%
filter(TIPOBITO %in% 2, IDADE == "0"|IDADE == "00"|IDADE == "000"|IDADE == "061"|IDADE == "124"|IDADE == "230"|IDADE == "312"|str_detect(IDADE, "06[2-9]|^0[7-8]|09[0-8]")|str_detect(IDADE, "12[5-9]|^1[3-9]")|str_detect(IDADE, "23[1-9]|^2[4-9]|300")|str_detect(IDADE, "31[3-9]^3[2-9]"))
tb_c11
Definição: Buscam-se os registros em que a causa básica de morte não pode ocorrer em determinada faixa etária.
Importante destacar, um algoritmo
(icd10_critica_idade.R) foi desenvolvido para analisar as
críticas C20 e C21.
source("../../functions/icd10_criticas/icd10_critica_idade.R")
sim_crude <- icd10_critica_idade(sim_crude, sim_crude$CAUSABAS, sim_crude$IDADE)
sim_crude %>% count(str_sub(FLAG, end = 2)) # PROBLEMA!
sim_crude %>% count(FLAG) %>% arrange(desc(n))
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c20.
tb_c20 <- sim_crude %>% filter(str_detect(FLAG, "^M5"))
tb_c20
Definição: Buscam-se os registros em que a causa básica de morte é pouco provável ocorrer em determinada faixa etária.
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c21.
tb_c21 <- sim_crude %>% filter(str_detect(FLAG, "^M6"))
tb_c21
Este bloco é composto por duas críticas específicas sobre o preenchimento da causa básica, conforme apresentado a seguir.
Definição: Nesta consulta são selecionados os óbitos masculinos que foram atribuídos causas básicas exclusivamente femininas.
icd10_codes <- aux_data$TabAux_03_Cid_p_Sexo_Fem$CID_4c # 894 codigos
sim_crude %>% filter(TIPOBITO %in% 2, SEXO == 1, CAUSABAS %in% icd10_codes) %>% count()
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c09.
tb_c09 <- sim_crude %>% filter(TIPOBITO %in% 2, SEXO == 1, CAUSABAS %in% icd10_codes)
tb_c09
Definição: Nesta consulta são selecionados os óbitos femininos que foram atribuídos causas básicas exclusivamente masculinas.
icd10_codes <- aux_data$TabAux_04_Cid_p_Sexo_Masc$CID_4c # 147 codigos
sim_crude %>% filter(TIPOBITO %in% 2, SEXO == 2, CAUSABAS %in% icd10_codes) %>% count() # OK!
Não foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c10.
tb_c10 <- sim_crude %>% filter(TIPOBITO %in% 2, SEXO == 2, CAUSABAS %in% icd10_codes)
tb_c10
Este bloco é composto por três críticas específicas sobre o preenchimento da causa básica e das causas associadas de óbito, conforme apresentado a seguir.
Definição: A partir da definição do algoritmo das causas de
óbitos materno declaradas, pesquisam-se os possíveis registros
incoerentes com a definição. Recomenda-se dar prioridade, nesta
correção, devido à importância do indicador. Buscam-se os registros em
que:
- Causa básica está entre “O000” e “O998” e sexo for diferente de
feminino;
- Causa básica está entre “O00” e “O95” ou entre “O98” e “O99” e idade
menor de 410, ou idade maior de 450 ou idade em branco ou idade iniciada
com 9;
- Causa básica igual M830, A34 e F32 e óbito no puerpério diferente de
“Sim até 42 dias”.
sim_crude %>%
filter(TIPOBITO == 2, !SEXO %in% 2, str_detect(CAUSABAS, "^O")) %>%
count(SEXO) # PROBLEMA!
sim_crude %>%
mutate(IDADE = str_remove_all(IDADE, "[^[:digit:]]")) %>%
filter(TIPOBITO == 2, str_detect(CAUSABAS, "^O[0-8]|O9[0-5,8-9]")) %>%
filter(str_detect(IDADE, "^40|410|^4[5-9]|^9") | IDADE == "") %>%
count(IDADE) # PROBLEMA!
sim_crude %>%
filter(TIPOBITO == 2, str_detect(CAUSABAS, "M830|^A34|^F32")) %>%
filter(!OBITOPUERP %in% 1) %>%
count() # PROBLEMA!
tb_c08a <- sim_crude %>% filter(TIPOBITO == 2, !SEXO %in% 2, str_detect(CAUSABAS, "^O"))
tb_c08a
tb_c08b <- sim_crude %>%
mutate(IDADE = str_remove_all(IDADE, "[^[:digit:]]")) %>%
filter(TIPOBITO == 2, str_detect(CAUSABAS, "^O[0-8]|O9[0-5,8-9]")) %>%
filter(str_detect(IDADE, "^40|410|^4[5-9]|^9") | IDADE == "")
tb_c08b
tb_c08c <- sim_crude %>%
filter(TIPOBITO == 2, str_detect(CAUSABAS, "M830|^A34|^F32")) %>%
filter(!OBITOPUERP %in% 1)
tb_c08c
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c08.
tb_c08 <- bind_rows(tb_c08a, tb_c08b, tb_c08c) %>% distinct()
tb_c08
Definição: Pesquisam-se os registros que contenham nos campos do atestado médico (LINHAA, LINHAB, LINHAC, LINHAD e PARTEII) CID que sejam do Capítulo XV - Gravidez, parto e puerpério (O00-O99), menos O96 e O97, e que tenha causa básica de morte fora do intervalo entre O00-O99.
sim_crude %>%
filter(TIPOBITO == 2) %>%
mutate(across(c("LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII"), ~replace_na(., ""))) %>% # "ATESTADO"
mutate(ALL_CAUSE = str_c(LINHAA, LINHAB, LINHAC, LINHAD, LINHAII, sep = "")) %>%
filter(str_detect(ALL_CAUSE, "O[0-8]|O9[0-5,8-9]")) %>%
filter(!str_detect(CAUSABAS, "^O")) %>%
count() # PROBLEMA!
Foram encontradas inconsistências para esta regra. Os resultados
foram armazenados no objeto tb_c18.
tb_c18 <- sim_crude %>%
filter(TIPOBITO == 2) %>%
mutate(across(c("LINHAA", "LINHAB", "LINHAC", "LINHAD", "LINHAII"), ~replace_na(., ""))) %>% # "ATESTADO"
mutate(ALL_CAUSE = str_c(LINHAA, LINHAB, LINHAC, LINHAD, LINHAII, sep = "")) %>%
filter(str_detect(ALL_CAUSE, "O[0-8]|O9[0-5,8-9]")) %>%
filter(!str_detect(CAUSABAS, "^O"))
tb_c18
Definição: Esta listagem visa melhorar o preenchimento dos campos óbito no parto (OBITOGRAV) e óbito no puerpério (OBITOPUERP) no modelo de DO antiga e, no modelo de DO nova, o campo óbito em mulher em idade fértil (TPMORTEOCO) em duas situações: (i) Óbitos em mulheres de idade fértil (MIF), entre 10 e 49 anos; (ii) Óbitos em mulheres onde a causa básica de morte está contida no capítulo 15 da CID 10 “Gravidez, parto e puerpério” (O00-O99).
sim_crude %>%
filter(TIPOBITO %in% 2, SEXO %in% 2) %>%
filter(str_detect(IDADE, "^4[1-4]") | str_detect(CAUSABAS, "^O")) %>%
summarise(NA_TPMORTEOCO = sum_(TPMORTEOCO == ""), # ATENCAO: var de obito MIF
#NA_OBITOPARTO = sum_(OBITOPARTO == ""), # ATENCAO: var de obito fetal ou infantil
NA_OBITOGRAV = sum_(OBITOGRAV == ""), # ATENCAO: var de obito MIF
NA_OBITOPUERP = sum_(OBITOPUERP == "")) # ATENCAO: var de obito MIF
tb_c17 <-
sim_crude %>%
filter(TIPOBITO %in% 2, SEXO %in% 2) %>%
filter(str_detect(IDADE, "^4[1-4]") | str_detect(CAUSABAS, "^O")) %>%
filter(TPMORTEOCO == "", OBITOGRAV == "", OBITOPUERP == "")
tb_c17
tb_check_sim <-
list(tb_info = aux_data$tb_criticas %>% select(id, bloco, codigo, descricao),
tb_c29 = tb_c29, tb_c26 = tb_c26, tb_c28 = tb_c28, tb_c01 = tb_c01, tb_c02 = tb_c02, tb_c12 = tb_c12, tb_c23 = tb_c23, tb_c14 = tb_c14, tb_c13 = tb_c13, tb_c22 = tb_c22, tb_c27 = tb_c27, tb_c16 = tb_c16, tb_c15 = tb_c15, tb_c05 = tb_c05, tb_c19 = tb_c19, tb_c25 = tb_c25, tb_c24 = tb_c24, tb_c07 = tb_c07, tb_c06 = tb_c06, tb_c11 = tb_c11, tb_c20 = tb_c20, tb_c21 = tb_c21, tb_c09 = tb_c09, tb_c10 = tb_c10, tb_c08 = tb_c08, tb_c18 = tb_c18, tb_c17 = tb_c17) # tb_c03, tb_c04
wb <- createWorkbook()
for(i in seq_along(tb_check_sim)){
addWorksheet(wb, sheetName = names(tb_check_sim[i]))
modifyBaseFont(wb, fontSize = 10, fontName = "Arial Narrow")
writeDataTable(wb, sheet = names(tb_check_sim[i]), x = tb_check_sim[[i]])
}
saveWorkbook(wb, "./sim_data_results/tb2_check_sim_criticas.xlsx", overwrite = T)
# ls()[str_detect(ls(), "tb_")]
tb1_check_sim_criticas <-
sim_crude %>%
mutate(C29_duplicidade = case_when(NUMERODO %in% tb_c29$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C26_municipio = case_when(NUMERODO %in% tb_c26$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C28_lococor_estab = case_when(NUMERODO %in% tb_c28$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C00_preliminares = case_when(NUMERODO %in% tb_c00$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C01_cb_branco = case_when(NUMERODO %in% tb_c01$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C02_cb_incorreto = case_when(NUMERODO %in% tb_c02$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C12_cb_excluido = case_when(NUMERODO %in% tb_c12$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C23_cb_naopode = case_when(NUMERODO %in% tb_c23$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C14_cb_asterisco = case_when(NUMERODO %in% tb_c14$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C13_cb_trivial = case_when(NUMERODO %in% tb_c13$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C22_cb_plausibilidade = case_when(NUMERODO %in% tb_c22$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C27_cb_improvavel = case_when(NUMERODO %in% tb_c27$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C16_cb_erradicada = case_when(NUMERODO %in% tb_c16$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C15_cb_interesse = case_when(NUMERODO %in% tb_c15$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
#mutate(C03_naofetal_nome = case_when(NUMERODO %in% tb_c03$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
#mutate(C04_fetal_nome = case_when(NUMERODO %in% tb_c04$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C05_fetal_idade = case_when(NUMERODO %in% tb_c05$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C19_fetal_cb_naofetal = case_when(NUMERODO %in% tb_c19$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C25_naofetal_cb_fetal = case_when(NUMERODO %in% tb_c25$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C24_maior1ano = case_when(NUMERODO %in% tb_c24$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C07_naofetal_idade = case_when(NUMERODO %in% tb_c07$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C06_maior125anos = case_when(NUMERODO %in% tb_c06$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C11_idade_invalida = case_when(NUMERODO %in% tb_c11$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C20_cb_idade_naopode = case_when(NUMERODO %in% tb_c20$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C21_cb_idade_improvavel = case_when(NUMERODO %in% tb_c21$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C09_cb_masc_fem = case_when(NUMERODO %in% tb_c09$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C10_cb_fem_masc = case_when(NUMERODO %in% tb_c10$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C08_materno_inconsistente = case_when(NUMERODO %in% tb_c08$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C18_materno_podeser = case_when(NUMERODO %in% tb_c18$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(C17_materno_qualifica = case_when(NUMERODO %in% tb_c17$NUMERODO ~ 1L, TRUE ~ 0L)) %>%
mutate(TOTAL_CRITICAS = C29_duplicidade + C26_municipio + C28_lococor_estab + C00_preliminares + C01_cb_branco + C02_cb_incorreto + C12_cb_excluido + C23_cb_naopode + C14_cb_asterisco + C13_cb_trivial + C22_cb_plausibilidade + C27_cb_improvavel + C16_cb_erradicada + C15_cb_interesse + C05_fetal_idade + C19_fetal_cb_naofetal + C25_naofetal_cb_fetal + C24_maior1ano + C07_naofetal_idade + C06_maior125anos + C11_idade_invalida + C20_cb_idade_naopode + C21_cb_idade_improvavel + C09_cb_masc_fem + C10_cb_fem_masc + C08_materno_inconsistente + C18_materno_podeser + C17_materno_qualifica) %>%
filter(TOTAL_CRITICAS > 0)
wb <- createWorkbook()
addWorksheet(wb, sheetName = "tb_info")
addWorksheet(wb, sheetName = "tb_revisao")
modifyBaseFont(wb, fontSize = 10, fontName = "Arial Narrow")
writeDataTable(wb, sheet = "tb_info", x = aux_data$tb_criticas %>% select(id, bloco, codigo, nome_abrev, descricao))
writeDataTable(wb, sheet = "tb_revisao", x = tb1_check_sim_criticas)
saveWorkbook(wb, "./sim_data_results/tb1_check_sim_criticas.xlsx", overwrite = T)
Um resumo dos resultados das análises de duplicidades e inconsistências é apresentado na tabela abaixo. Observou-se um total de 105.720 ‘alertas’ de duplicidades/inconsistências em dados (preliminares) de 1.485.653 óbitos fetais e não fetais ocorridos no Brasil em 2023. Isto corresponde a 7,2% dos registros. As três maiores ocorrências foram nas críticas C23 (Registros com CID que não podem ser usados como causa básica de morte), c15 (Registros com causas de interesse epidemiológico), C17 (Consulta para qualificação dos campos “OBITOPARTO”, “OBITOPUERP” e “TPMORTEOCO”). Adicionalmente, estes resultados podem ser explorados segundo características de lugar e tempo para melhor compreender seu padrão de ocorrência.
tb1_check_sim_criticas %>%
select(38:66) %>%
summarise(across(everything(), sum_)) %>%
pivot_longer(everything(.), names_to = "CRITICAS", values_to = "NÚMERO DE REGISTROS") %>%
arrange(desc(`NÚMERO DE REGISTROS`)) %>%
mutate(`% no total de críticas` = round((`NÚMERO DE REGISTROS`/105720)*100, 2)) %>%
mutate(`% no total de óbitos` = round((`NÚMERO DE REGISTROS`/1459167)*100, 2))
Esta rotina de checagem de dados terminou em 2024-05-24 14:40:12.607127.
Sys.time() - t0
## Time difference of 10.4331 mins