The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Modern surveillance data from OpenDataSUS

Renato Prado Siqueira

2026-08-24

Overview

OpenDataSUS publishes record-level surveillance files separately from TABNET. datasus provides a generic catalog client and convenience functions for frequently used datasets:

Dataset Function Standardization key
Serious adverse events following immunization esavi() "esavi"
Influenza-like illness notifications esus_sindrome_gripal() "sindrome_gripal"
Individual PNI doses pni_doses() "pni_doses"
COVID-19 hospital occupancy ocupacao_hospitalar() "ocupacao_hospitalar"

Search before downloading

Search the catalog and inspect its resources before requesting a large file:

opendatasus_catalogo("ESAVI")
opendatasus_catalogo("doses aplicadas PNI")

resources <- opendatasus_recursos("esavi")
resources[, c("id", "nome", "formato", "ano", "tamanho")]

"last" follows the latest partition found in the live catalog. Use an explicit year and month when the analysis must remain reproducible.

Start with selected columns

The convenience functions accept n_max for exploratory reads and colunas to avoid parsing fields that are not needed:

events <- esavi(
  n_max = 1000,
  colunas = c(
    "nu_notificacao", "dt_notificacao", "nu_idade", "ds_sexo"
  ),
  normalizar = TRUE
)

illness <- esus_sindrome_gripal(
  uf = "MS",
  ano = 2024,
  n_max = 1000,
  colunas = c(
    "dataNotificacao", "municipioIBGE", "idade", "sexo"
  ),
  normalizar = TRUE
)

doses <- pni_doses(
  ano = 2026,
  mes = 1,
  n_max = 1000,
  colunas = c(
    "co_paciente", "dt_vacina", "co_vacina",
    "co_municipio_paciente"
  ),
  normalizar = TRUE
)

occupancy <- ocupacao_hospitalar(
  ano = 2022,
  n_max = 1000,
  colunas = c(
    "dataNotificacao", "cnes", "ocupacaoHospitalarUti"
  ),
  normalizar = TRUE
)

Column names supplied to colunas are the names in the source file. With normalizar = TRUE, the returned names are the stable analysis names defined by the package dictionary.

Standardize an existing data frame

Standardization can also be applied after data have been imported elsewhere. This offline example uses fields from the ESAVI dictionary:

raw_events <- data.frame(
  nu_notificacao = c("A-001", "A-002"),
  dt_notificacao = c("2026-01-10", "2026-01-11"),
  nu_idade = c("34", "67"),
  ds_sexo = c("Feminino", "Masculino"),
  stringsAsFactors = FALSE
)

events <- datasus_padronizar(raw_events, sistema = "esavi")
str(events)
#> 'data.frame':    2 obs. of  4 variables:
#>  $ id_notificacao  : chr  "A-001" "A-002"
#>  $ data_notificacao: Date, format: "2026-01-10" "2026-01-11"
#>  $ idade           : num  34 67
#>  $ sexo            : chr  "Feminino" "Masculino"
#>  - attr(*, "datasus_dicionario")='data.frame':   4 obs. of  7 variables:
#>   ..$ sistema          : chr [1:4] "esavi" "esavi" "esavi" "esavi"
#>   ..$ tipo             : chr [1:4] "*" "*" "*" "*"
#>   ..$ campo            : chr [1:4] "nu_notificacao" "ds_sexo" "nu_idade" "dt_notificacao"
#>   ..$ campo_padronizado: chr [1:4] "id_notificacao" "sexo" "idade" "data_notificacao"
#>   ..$ descricao        : chr [1:4] "Identificador da notificacao" "Sexo" "Idade no evento" "Data da notificacao"
#>   ..$ classe           : chr [1:4] "character" "character" "numeric" "date"
#>   ..$ formato          : chr [1:4] "" "" "" "%d/%m/%Y|%Y-%m-%d"

The dictionary documents source names, standardized names, semantic labels and expected classes:

head(datasus_dicionario("esavi"), 8)
#>   sistema tipo                     campo      campo_padronizado
#> 1   esavi    *            nu_notificacao         id_notificacao
#> 2   esavi    *                   ds_sexo                   sexo
#> 3   esavi    *                  nu_idade                  idade
#> 4   esavi    * st_comunidade_tradicional comunidade_tradicional
#> 5   esavi    *          ds_not_mae_filho      exposicao_materna
#> 6   esavi    *           nu_mes_gestante           mes_gestacao
#> 7   esavi    *           ds_versao_medra          versao_meddra
#> 8   esavi    *     ds_mulher_amamentando            amamentando
#>                                descricao    classe formato
#> 1           Identificador da notificacao character        
#> 2                                   Sexo character        
#> 3                        Idade no evento   numeric        
#> 4      Pertence a comunidade tradicional   logical        
#> 5 Exposicao pela gestacao ou aleitamento   logical        
#> 6           Mes de gestacao na vacinacao   numeric        
#> 7          Versao da terminologia MedDRA character        
#> 8    Amamentando no momento da vacinacao   logical

Detect schema drift

datasus_validar_esquema() checks whether important fields are present and whether their classes agree with the curated schema:

validation <- datasus_validar_esquema(
  events,
  sistema = "esavi",
  campos = c(
    "id_notificacao", "data_notificacao", "idade", "sexo"
  )
)
validation
#>            campo campo_padronizado presente coluna_observada classe_observada
#> 1 nu_notificacao    id_notificacao     TRUE   id_notificacao        character
#> 2        ds_sexo              sexo     TRUE             sexo        character
#> 3       nu_idade             idade     TRUE            idade          numeric
#> 4 dt_notificacao  data_notificacao     TRUE data_notificacao             Date
#>   classe_esperada      status
#> 1       character padronizado
#> 2       character padronizado
#> 3         numeric padronizado
#> 4            date padronizado

Set estrito = TRUE in automated pipelines to stop when a required field is missing or has an incompatible class:

datasus_validar_esquema(
  events,
  sistema = "esavi",
  campos = c("id_notificacao", "data_notificacao"),
  estrito = TRUE
)

Resources split into multiple physical files

Some historical influenza-like illness resources publish their physical files as links in the resource description. Expand them before building a download plan:

resources <- opendatasus_recursos(
  "notificacoes-de-sindrome-gripal-leve-2020"
)
ms_id <- resources$id[
  resources$formato == "CSV" & grepl("^Dados MS", resources$nome)
][1]

files <- opendatasus_arquivos(
  "notificacoes-de-sindrome-gripal-leve-2020",
  recurso = ms_id,
  formato = "CSV"
)
files[, c("recurso", "ano", "parte", "url")]

esus_sindrome_gripal() reads all these parts transparently and applies n_max across the combined result, rather than independently to every file.

Provenance

Downloaded data retain the resource identifier, official URLs, update and download times, local cache paths and checksums:

provenance <- datasus_proveniencia(events)
str(provenance)

Use atualizar = TRUE to ignore a cached copy and obtain the current portal version.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.