---
title: "Large files, raw microdata and provenance"
author: "Renato Prado Siqueira"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Large files, raw microdata and provenance}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, collapse = TRUE, comment = "#>")
library(datasus)
```

## Overview

Record-level health data can be much larger than TABNET aggregates. The
package provides two complementary workflows:

- DBC/DBF microdata from the traditional DATASUS file servers;
- CSV and JSON resources published through OpenDataSUS.

Both workflows support discovery, local caching, selected columns,
standardized schemas and provenance.

## Traditional DBC/DBF microdata

The raw microdata catalog covers SIM, SINASC and SIH/SUS:

```{r raw-catalog, eval=FALSE}
microdados_catalogo()

microdados_arquivos(
  sistema = "sih",
  ano = 2024,
  mes = 1,
  uf = "AC"
)
```

Select only the columns required by the analysis and start with a small
number of records:

```{r raw-read, eval=FALSE}
admissions <- sih_microdados(
  ano = 2024,
  mes = 1,
  uf = "AC",
  colunas = c(
    "MUNIC_RES", "DT_INTER", "DIAG_PRINC", "VAL_TOT"
  ),
  n_max = 1000,
  normalizar = TRUE
)

deaths <- sim_microdados(
  ano = 2023,
  uf = "RR",
  colunas = c("CODMUNRES", "DTOBITO", "CAUSABAS"),
  n_max = 1000,
  normalizar = TRUE
)

births <- sinasc_microdados(
  ano = 2023,
  uf = "RR",
  colunas = c("CODMUNRES", "DTNASC", "SEXO", "PESO"),
  n_max = 1000,
  normalizar = TRUE
)
```

DBC files are decoded directly and read through the same public interface as
DBF files.

## Inspect schemas before reading

```{r raw-dictionary}
head(datasus_dicionario("sih"), 10)
```

After a read, validate the critical analysis fields:

```{r raw-validation, eval=FALSE}
datasus_validar_esquema(
  admissions,
  sistema = "sih",
  campos = c(
    "codigo_municipio_residencia",
    "data_internacao",
    "diagnostico_principal_cid10",
    "valor_total"
  ),
  estrito = TRUE
)
```

## Selected OpenDataSUS columns

For ordinary files, `opendatasus_ler()` can select columns while parsing:

```{r generic-open-read, eval=FALSE}
resources <- opendatasus_recursos("arboviroses-dengue")
csv_id <- resources$id[resources$formato == "CSV"][1]

sample <- opendatasus_ler(
  "arboviroses-dengue",
  recurso = csv_id,
  colunas = c("DT_NOTIFIC", "SG_UF", "ID_MUNICIP"),
  n_max = 1000
)
```

Convenience wrappers should be preferred when available because they encode
the dataset's partition rules and curated schema.

## Process CSV files in bounded memory

`opendatasus_processar()` calls a function for each block instead of retaining
the entire dataset:

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

processed <- opendatasus_processar(
  "notificacoes-de-sindrome-gripal-leve-2020",
  recurso = ms_id,
  ano = NULL,
  colunas = c("municipioIBGE", "resultadoTeste"),
  tamanho_bloco = 50000,
  sistema = "sindrome_gripal",
  FUN = function(dados, posicao, arquivo) {
    data.frame(
      arquivo = arquivo,
      bloco_inicial = posicao,
      registros = nrow(dados),
      positivos = sum(
        dados$resultado_teste == "Positivo",
        na.rm = TRUE
      )
    )
  }
)

processed$linhas
processed$blocos
processed$resultados
```

The callback receives the standardized block when `sistema` is supplied.
Physical parts are processed in catalog order and are listed in
`processed$arquivos`.

## Cache and provenance

Downloads are written atomically. Cached files are reused unless
`atualizar = TRUE` is requested:

```{r cache, eval=FALSE}
first <- ocupacao_hospitalar(
  ano = 2022,
  n_max = 1000,
  cache = TRUE
)

source <- datasus_proveniencia(first)
str(source)
```

The provenance record identifies the official URL, resource, portal update
time, local path, download time and MD5 checksum. Multipart reads retain a
record for each physical file.

## Practical strategy

For large resources:

1. inspect resource metadata and partitions;
2. select the smallest useful year, month and state;
3. provide `colunas` before increasing `n_max`;
4. use `opendatasus_processar()` for reductions that do not need all rows in
   memory;
5. validate critical fields with `datasus_validar_esquema()`;
6. retain provenance with the analytical output.

`n_max` limits parsed rows, but a remote file may still need to be downloaded
in full before parsing. Cache reuse prevents that transfer from being
repeated.
