--- title: "Supplementary Health Data with ANS" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Supplementary Health Data with ANS} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ``` ## Overview The **ANS (Agencia Nacional de Saude Suplementar)** is Brazil's regulatory agency for private/supplementary health insurance (planos de saude). Its open data portal provides data on beneficiaries, consumer complaints, and operator financial statements. | Feature | Details | |---------|---------| | Source | HTTP CSV/ZIP (dadosabertos.ans.gov.br) | | Data types | 3 (beneficiaries, complaints, financial) | | Beneficiaries | Monthly, per-UF (Apr 2019--present) | | Complaints | Annual, national (2011--present) | | Financial | Quarterly (2007--present) | | Operators | Snapshot registry (separate function) | ## Data types | Code | Name | Granularity | Availability | |------|------|-------------|--------------| | **beneficiaries** | Beneficiarios | Monthly, per-UF | Apr 2019--2025 | | **complaints** | Demandas NIP | Annual, national | 2011--2026 | | **financial** | Demonstracoes contabeis | Quarterly | 2007--2025 | ## Getting started ```{r setup} library(healthbR) library(dplyr) ``` ### Check available years ```{r} # beneficiaries (default) ans_years() # complaints ans_years(type = "complaints") # financial statements ans_years(type = "financial") ``` ### Module information ```{r} ans_info() ``` ## Beneficiaries Beneficiary data provides consolidated counts of health plan enrollees broken down by operator, municipality, sex, age group, plan type, and more. Each file covers one state (UF) and one month. ### Basic download ```{r} # Acre, December 2023 ac <- ans_data(year = 2023, month = 12, uf = "AC") ac ``` ### Multiple months and states ```{r} # first quarter 2024, two states ne <- ans_data(year = 2024, month = 1:3, uf = c("CE", "PE")) # full year (month = NULL downloads all 12 months) ac_2023 <- ans_data(year = 2023, uf = "AC") ``` ### Selecting variables ```{r} ans_data( year = 2023, month = 12, uf = "AC", vars = c("CD_OPERADORA", "SG_UF", "TP_SEXO", "DE_FAIXA_ETARIA", "QT_BENEFICIARIO_ATIVO") ) ``` ### Key variables | Variable | Description | |----------|-------------| | ID_CMPT_MOVEL | Reference period (YYYY-MM) | | CD_OPERADORA | Operator code at ANS | | NM_RAZAO_SOCIAL | Operator name | | SG_UF | State abbreviation | | CD_MUNICIPIO | Municipality (IBGE code) | | TP_SEXO | Sex (M/F) | | DE_FAIXA_ETARIA | Age group | | DE_CONTRATACAO_PLANO | Contract type (Individual, Coletivo Empresarial, etc.) | | DE_SEGMENTACAO_PLANO | Plan segment (Ambulatorial, Hospitalar, etc.) | | COBERTURA_ASSIST_PLAN | Coverage type (Medico-hospitalar, Odontologica) | | TIPO_VINCULO | Beneficiary link (Titular, Dependente) | | QT_BENEFICIARIO_ATIVO | Active beneficiary count | ## Consumer complaints (NIP) Consumer complaints data covers demands filed through ANS's NIP (Notificacao de Intermediacao Preliminar) system. Files are national (not per-UF) and annual. ```{r} # complaints filed in 2022 nip <- ans_data(year = 2022, type = "complaints") nip # multiple years nip_multi <- ans_data(year = 2020:2023, type = "complaints") ``` ### Key variables | Variable | Description | |----------|-------------| | NUMERO_DA_DEMANDA | Complaint number | | ABERTURA_DA_DEMANDA | Filing date | | ASSUNTO | Subject | | REGISTRO_OPERADORA | Operator registration | | NOME_OPERADORA | Operator name | | TIPO_DE_PLANO_CONTRATADO | Contract type | | SEXO | Sex (M/F) | | ESTADO_DO_BENEFICIARIO | Beneficiary state | | CLASSIFICACAO_DA_NIP | NIP classification | | NATUREZA_DA_NIP | NIP nature | | SITUACAO_DA_NIP | NIP status | ## Financial statements Quarterly financial statements (demonstracoes contabeis) for all health plan operators. ```{r} # Q1 2023 fin_q1 <- ans_data(year = 2023, type = "financial", quarter = 1) # all 4 quarters of 2023 fin_2023 <- ans_data(year = 2023, type = "financial") # specific quarters fin_q12 <- ans_data(year = 2023, type = "financial", quarter = 1:2) ``` ### Key variables | Variable | Description | |----------|-------------| | DATA | Reference date | | REG_ANS | Operator registration | | CD_CONTA_CONTABIL | Accounting code | | DESCRICAO | Account description | | VL_SALDO_INICIAL | Opening balance (R$) | | VL_SALDO_FINAL | Closing balance (R$) | ## Operator registry The operator registry is a separate snapshot (not time-series), so it uses its own function: ```{r} # active operators active <- ans_operators() # cancelled operators cancelled <- ans_operators(status = "cancelled") # both combined all_ops <- ans_operators(status = "all") ``` ### Key variables | Variable | Description | |----------|-------------| | REGISTRO_OPERADORA | ANS registration number | | CNPJ | Tax ID | | Razao_Social | Legal name | | Nome_Fantasia | Trade name | | Modalidade | Modality (Medicina de Grupo, Cooperativa, etc.) | | UF | State | | Data_Registro_ANS | ANS registration date | ## Exploring variables ```{r} # beneficiaries variables (default) ans_variables() # complaints variables ans_variables(type = "complaints") # financial variables ans_variables(type = "financial") # search across variables ans_variables(search = "operadora") ans_variables(search = "beneficiario") ``` ## Example: beneficiaries by state and plan type ```{r} # December 2023, all states ben <- ans_data(year = 2023, month = 12) # active beneficiaries by state and coverage type ben |> group_by(SG_UF, COBERTURA_ASSIST_PLAN) |> summarize( total = sum(as.integer(QT_BENEFICIARIO_ATIVO), na.rm = TRUE), .groups = "drop" ) |> arrange(desc(total)) ``` ## Example: complaints by subject and operator ```{r} nip <- ans_data(year = 2023, type = "complaints") # top complaint subjects nip |> count(ASSUNTO, sort = TRUE) |> head(10) # operators with most complaints nip |> count(NOME_OPERADORA, sort = TRUE) |> head(10) ``` ## Example: operator financial health ```{r} # Q4 2023 financial data fin <- ans_data(year = 2023, type = "financial", quarter = 4) # join with operator registry for names ops <- ans_operators() fin |> filter(grepl("^41", CD_CONTA_CONTABIL)) |> # revenue accounts group_by(REG_ANS) |> summarize( revenue = sum(as.numeric(VL_SALDO_FINAL), na.rm = TRUE), .groups = "drop" ) |> left_join( ops |> select(REGISTRO_OPERADORA, Razao_Social), by = c("REG_ANS" = "REGISTRO_OPERADORA") ) |> arrange(desc(revenue)) |> head(10) ``` ## Example: combining ANS with SUS data ANS beneficiary counts complement SUS data by showing private coverage: ```{r} # private coverage (ANS) ben <- ans_data(year = 2023, month = 12, vars = c("SG_UF", "QT_BENEFICIARIO_ATIVO")) private_by_uf <- ben |> group_by(SG_UF) |> summarize( private_beneficiaries = sum(as.integer(QT_BENEFICIARIO_ATIVO), na.rm = TRUE), .groups = "drop" ) # total population (Census 2022) pop <- censo_populacao(year = 2022, territorial_level = "state") # private coverage rate # private_by_uf |> # left_join(pop, by = ...) |> # mutate(coverage_pct = (private_beneficiaries / population) * 100) |> # arrange(desc(coverage_pct)) ``` ## Parameter routing `ans_data()` routes parameters based on the `type`: | Parameter | beneficiaries | complaints | financial | |-----------|:---:|:---:|:---:| | `year` | required | required | required | | `month` | optional (1--12) | ignored | ignored | | `uf` | optional (27 UFs + XX) | ignored | ignored | | `quarter` | ignored | ignored | optional (1--4) | | `vars` | optional | optional | optional | Unused parameters emit a warning but do not cause errors. ## Lazy evaluation With the `arrow` package installed, data is cached in Parquet format and can be queried lazily: ```{r} # lazy query (requires arrow) lazy_ben <- ans_data(year = 2023, uf = "AC", lazy = TRUE) lazy_ben |> filter(month == 12L, TP_SEXO == "F") |> select(CD_OPERADORA, DE_FAIXA_ETARIA, QT_BENEFICIARIO_ATIVO) |> collect() ``` ## Cache management Downloaded data is cached locally for faster future access: ```{r} # check cache status ans_cache_status() # clear cache if needed ans_clear_cache() ``` ## Differences from DATASUS modules | Feature | ANS | DATASUS modules | |---------|-----|-----------------| | Data source | HTTP CSV/ZIP | FTP .dbc/.DBF files | | Column names | MixedCase (from CSV) | UPPERCASE | | `parse` parameter | Not available | Available | | `dictionary()` | Not available | Available | | `quarter` parameter | Financial data | Not used | | Operator registry | `ans_operators()` | Not applicable | ## Additional resources - ANS open data portal (`dadosabertos.ans.gov.br`) - ANS official website (`www.gov.br/ans/pt-br`) - ANS Tabnet (`www.ans.gov.br/anstabnet`) - [Census vignette](censo-denominadores.html) for population denominators