Mortalidade infantil × cobertura SUS por município¶
Tempo estimado: 30 minutos (depende do recorte). Pacotes:
datasus-fetcher,sidra-fetcher,polars,pyreaddbc.
Taxa de mortalidade infantil é o indicador clássico de saúde pública. Vamos cruzá-la com a cobertura de estabelecimentos SUS por município usando três fontes oficiais — DATASUS (SIM e CNES) e IBGE (estimativas populacionais).
O que você vai produzir¶
Uma tabela municipal com:
- Óbitos infantis (< 1 ano) por município (SIM/DATASUS).
- Nascidos vivos por município (SINASC/DATASUS) — denominador.
- População total por município (IBGE).
- Estabelecimentos SUS por município (CNES/DATASUS).
- Taxa por 1000 nascidos vivos + densidade de equipamentos SUS por 10k habitantes.
Setup¶
uv add "datasus-fetcher" "sidra-fetcher @ git+https://github.com/Quantilica/sidra-fetcher.git" polars pyreaddbc
A receita¶
1. Baixar SIM, SINASC e CNES para um ano e região¶
# Óbitos
datasus-fetcher data --data-dir ./dados sim --start 2022 --end 2022 --regions sp
# Nascidos vivos
datasus-fetcher data --data-dir ./dados sinasc --start 2022 --end 2022 --regions sp
# Cadastro de estabelecimentos
datasus-fetcher data --data-dir ./dados cnes-st --start 2022-12 --end 2022-12 --regions sp
2. Baixar população do SIDRA¶
from pathlib import Path
import polars as pl
import pyreaddbc
from sidra_fetcher.fetcher import SidraClient
from sidra_fetcher.sidra import Parametro, Formato, Precisao
# Estimativas de população por município — agregado 6579, variável 9324
with SidraClient(timeout=60) as client:
param = Parametro(
agregado="6579",
territorios={"6": ["all"]}, # todos os municípios
variaveis=["9324"],
periodos=["2022"],
classificacoes={},
formato=Formato.A,
decimais={"": Precisao.M},
)
rows = client.get(param.url())
pop = pl.DataFrame(rows[1:]).select(
pl.col("D1C").alias("codigo_municipio"),
pl.col("V").cast(pl.Int64, strict=False).alias("populacao"),
).drop_nulls()
3. Ler os .dbc do DATASUS¶
def read_dbc_dir(dir_path: Path, columns: list[str]) -> pl.DataFrame:
frames = []
for dbc in sorted(dir_path.glob("*.dbc")):
df = pyreaddbc.read_dbc(str(dbc))
frames.append(pl.from_pandas(df).select(columns))
return pl.concat(frames)
sim = read_dbc_dir(Path("dados/sim"), ["IDADE", "CODMUNRES"])
sinasc = read_dbc_dir(Path("dados/sinasc"), ["CODMUNRES"])
cnes = read_dbc_dir(Path("dados/cnes-st"), ["CODUFMUN", "CO_CNES"])
4. Calcular o indicador¶
obitos_infantis = (
sim.filter(pl.col("IDADE").str.starts_with("4")) # IDADE em SIM: 4xx = 0..364 dias
.group_by("CODMUNRES")
.len()
.rename({"CODMUNRES": "codigo_municipio", "len": "obitos_infantis"})
)
nascidos = (
sinasc.group_by("CODMUNRES")
.len()
.rename({"CODMUNRES": "codigo_municipio", "len": "nascidos_vivos"})
)
estabelecimentos = (
cnes.group_by("CODUFMUN")
.len()
.rename({"CODUFMUN": "codigo_municipio", "len": "estabelecimentos_sus"})
)
painel = (
pop.join(obitos_infantis, on="codigo_municipio", how="left")
.join(nascidos, on="codigo_municipio", how="left")
.join(estabelecimentos, on="codigo_municipio", how="left")
.with_columns(
tmi_por_1000=pl.col("obitos_infantis") / pl.col("nascidos_vivos") * 1000,
sus_per_10k=pl.col("estabelecimentos_sus") / pl.col("populacao") * 10_000,
)
)
print(painel.sort("tmi_por_1000", descending=True).head(20))
O que está acontecendo¶
- SIM
IDADEcomeça com4para0–364 dias(401= 1 dia,464= 364 dias). Mortalidade infantil = óbitos comIDADEcomeçando em4. CODMUNRES(SIM/SINASC) eCODUFMUN(CNES) são o mesmo conceito — código IBGE de 6 dígitos. A nomenclatura DATASUS varia entre sistemas.- População do SIDRA usa o mesmo código IBGE — o join funciona naturalmente.
- O resultado já é uma tabela municipal pronta para mapa coroplético ou regressão.
Pegadinhas¶
- Códigos de município truncados. SIM/SINASC usam 6 dígitos; SIDRA usa 7 (com dígito verificador). Você pode truncar ou expandir — escolha um lado.
IDADEem SIM é codificada. Não é número direto. Consulte o dicionário (datasus-fetcher docs sim) antes de filtrar.- CNES é foto mensal. O dataset
cnes-stmostra o estabelecimento no mês específico. Para série, baixe vários meses e useMAX(competencia)por município. - Mortalidade infantil é volátil em municípios pequenos. Para municípios com <100 nascidos/ano, a taxa flutua absurdamente. Agregue por microrregião ou suavize com média móvel trianual.
Variações¶
- Razão de mortalidade materna — use óbitos
OBITOGRAVno SIM dividido por nascidos do SINASC. - Cobertura vacinal × incidência — junte com PNI (programa nacional de imunizações) via
datasus-fetcher. - Equidade regional — junte com o IDHM (atlas Brasil) e veja desigualdade.
Veja também¶
- datasus-fetcher
- Cientista de dados de saúde pública — atalhos para o seu perfil.
- Proveniência — fundamental para auditar quais versões dos
.dbcvocê usou.