
Tutorial 3: Filtering by Disease (ICD-10) and Demographics
climasus4r Team
17/10/2026
Source:vignettes/03-filtragem.Rmd
03-filtragem.RmdObjective
By the end of this tutorial you will be able to subset already-standardized health microdata along two complementary axes:
-
By disease (ICD-10) — with
sus_data_filter_cid(), selecting specific codes, ranges, entire chapters, or one of the package’s 50+ predefined disease groups; -
By demographic characteristics — with
sus_data_filter_demographics(), restricting by sex, race/color, age group, education, region, or municipality.
You will also get to know sus_data_cid_select(), an
interactive explorer that helps you discover
disease-group names without needing to memorize ICD-10 codes.
Filtering is the third stage of the pipeline
(import → clean → stand → **filter_cid → filter_demo** → derive → aggregate → …).
It requires that the data have already been standardized (stage
stand); functions therefore abort with a guiding message if
they receive data at an earlier stage.
Scientific context
Climate and health studies rarely analyze all deaths or hospitalizations at once: interest centers on climate-sensitive outcomes in vulnerable subpopulations. The literature is consistent in showing that thermal extremes disproportionately affect respiratory causes (ICD-10 chapter J, J00–J99) and cardiovascular causes (chapter I, I00–I99), especially among older adults (Gasparrini et al., 2015; Bhaskaran et al., 2013).
The International Classification of Diseases, 10th revision
(ICD-10) organizes causes into chapters identified by an
initial letter and into three- to four-character codes (WHO, 2016).
climasus4r translates this structure into a flexible
filtering syntax — single code, range ("J00-J99"), chapter
("J"), or named group ("respiratory") — and
automatically detects the appropriate cause-of-death column for each
DATASUS system (CAUSABAS/causa_basica in SIM,
DIAG_PRINC/diagnostico_principal in SIH).
Subsetting before aggregating is also good
reproducibility practice: the climasus_df object records in
its history exactly which codes and demographic criteria were applied,
making the study auditable.
Driving case study. We investigate temperature and health outcomes in older adults (60+) in the São Paulo Metropolitan Region, 2014–2019. In this tutorial, starting from the standardized base from Tutorial 2, we subset the respiratory causes (J00–J99) and cardiovascular causes (I00–I99) and restrict to the older population (60 years or more) residing in the RMSP (São Paulo Metropolitan Region). The filtered object feeds into Tutorial 4 (Variable Creation and Aggregation).
Data used
Input: vignettes-pt/dados/caso_padronizado.rds — the
standardized SIM-DO base produced in Tutorial 2
(canonical columns such as causa_basica,
age_years, sex,
residence_municipality_code). The script loads this
.rds file with a file.exists() guard; if it
does not yet exist (Tutorial 2 not run), it falls back to a
minimal synthetic example solely to produce the
didactic artifacts.
| Subset | Criterion | Function |
|---|---|---|
| Respiratory causes | ICD-10 J00–J99 (disease_group = "respiratory") |
sus_data_filter_cid() |
| Cardiovascular causes | ICD-10 I00–I99 (icd_codes = "I00-I99") |
sus_data_filter_cid() |
| Older adults | age_range = c(60, Inf) |
sus_data_filter_demographics() |
| RMSP | municipality_code = <IBGE codes> |
sus_data_filter_demographics() |
Full pipeline
The blocks below reproduce what the
scripts/tutorial_03_filtragem.R script executes. Start by
loading the package and the standardized base from the previous
tutorial:
library(climasus4r)
# Saída do Tutorial 2 (Encoding & Padronização):
caso_padronizado <- readRDS("vignettes-pt/dados/caso_padronizado.rds")
obitos_std <- caso_padronizado$obitos # SIM-DO padronizado (estágio "stand")Explore disease groups
sus_data_cid_select() helps you discover which
groups exist and which are climate-sensitive,
without opening the source code. In interactive mode
(output = "browser") it opens an HTML interface; in
"console" mode it invisibly returns a
data.frame with the groups:
# Interface interativa no navegador (padrão):
sus_data_cid_select(lang = "pt")
# Apenas os grupos sensíveis ao clima:
sus_data_cid_select(lang = "pt", filter_climate = TRUE)
# Sem abrir o navegador — devolve o data.frame de grupos:
grupos <- sus_data_cid_select(lang = "pt", output = "console", verbose = FALSE)Filter by ICD-10
There are two equivalent ways to subset the respiratory and
cardiovascular causes: by named group (more readable)
or by code range (more explicit). The cause-of-death
column (causa_basica, in SIM-DO) is automatically
detected from the climasus_df metadata.
# (a) Respiratório (J00-J99) por grupo de doença:
resp <- sus_data_filter_cid(
df = obitos_std,
disease_group = "respiratory", # equivale a icd_codes = "J00-J99"
match_type = "starts_with", # "J18" casa "J18", "J18.0", "J18.9"
backend = "tibble", # "arrow" (lazy) ou "tibble" (em memória)
lang = "pt"
)
# (b) Cardiovascular (I00-I99) por intervalo de códigos:
cardio <- sus_data_filter_cid(
df = obitos_std,
icd_codes = "I00-I99", # equivale a disease_group = "cardiovascular"
match_type = "starts_with",
backend = "tibble",
lang = "pt"
)Filter by demographics (older adults 60+ in the RMSP)
We chain the demographic subset on top of the respiratory subset. The
argument age_range = c(60, Inf) requires the
age_years column; the spatial subset uses IBGE
codes for the municipalities of the São Paulo Metropolitan
Region:
# Municípios da RMSP (códigos IBGE de 7 dígitos):
RMSP <- c("3550308", "3548708", "3509502", "3548500",
"3547809", "3530607", "3534401", "3505708")
resp_idosos <- sus_data_filter_demographics(
df = resp,
age_range = c(60, Inf), # idosos: 60 anos ou mais
municipality_code = RMSP, # recorte espacial: RMSP
drop_ignored = FALSE, # TRUE removeria sexo/raça "Ignorado"/NA
backend = "tibble",
use_cache = TRUE,
lang = "pt"
)
cardio_idosos <- sus_data_filter_demographics(
df = cardio,
age_range = c(60, Inf),
municipality_code = RMSP,
backend = "tibble",
lang = "pt"
)You can also filter by city name (tolerant of accents and typos), by sex/race/education, or by predefined region:
# Por nome de cidade (em vez de código) e por sexo:
mulheres_sp <- sus_data_filter_demographics(
df = resp,
sex = "Feminino",
city = "Sao Paulo", # aceita acento; faz correspondência aproximada
lang = "pt"
)
# Por macrorregião (atalho que resolve para um conjunto de UFs):
sudeste <- sus_data_filter_demographics(resp, region = "sudeste", lang = "pt")At the end of this step we have resp_idosos and
cardio_idosos — the subsets of interest
that will be saved and will feed into Tutorial 4.
Function features
sus_data_filter_cid()
Filters by ICD-10. Requires icd_codes
or disease_group (if both are supplied,
disease_group takes precedence). The cause-of-death column
is automatically detected by the system
(SIM → causa_basica,
SIH → diagnostico_principal).
| Argument | Essential? | Description |
|---|---|---|
df |
yes |
climasus_df at stage stand or later |
icd_codes |
one of the two | Code(s)/range(s): "J18.9", c("I21","I22"),
"J00-J99"
|
disease_group |
one of the two | Named group: "respiratory",
"cardiovascular", "dengue", … |
icd_column |
optional | Cause column; NULL = autodetection |
match_type |
optional |
"starts_with" (default), "exact",
"range"
|
backend |
optional |
"arrow" (lazy, default) or "tibble" (in
memory) |
lang / verbose
|
optional | Language ("pt"/"en"/"es") and
messages |
Returns: a filtered climasus_df (stage
filter_cid), preserving all original columns and recording
in its history the codes/groups applied.
sus_data_filter_demographics()
Filters by demographic and geographic characteristics. All criteria
are optional; if none are supplied, the data are returned unchanged.
Combinations are applied in sequence (intersection across criteria);
city and municipality_code are combined by
union.
| Argument | Description |
|---|---|
df |
climasus_df at stage stand or later |
sex |
"Masculino"/"Feminino" (accepts
pt/en/es) |
race |
IBGE categories: "Branca", "Preta",
"Parda", … |
age_range |
Vector c(min, max); use Inf for no upper
limit. Requires age_years
|
education |
Education levels |
region |
Predefined group of states/UFs ("sudeste",
"semi_arido", …) |
city |
Municipality name(s) (tolerant of accents/typos) |
municipality_code |
6- or 7-digit IBGE code(s) |
drop_ignored |
TRUE removes NA/“Ignored” codes from
demographic variables |
backend, use_cache,
cache_dir
|
Backend and spatial cache (relevant with city) |
lang / verbose
|
Language and messages |
Returns: a filtered climasus_df (stage
filter_demo). Internally, municipality codes are expanded
to cover both formats (DATASUS’s 6 digits and IBGE’s 7
digits), so the filter works regardless of the format stored.
sus_data_cid_select()
Disease-group explorer. Does not alter the data — it
only helps discover group names to use in
sus_data_filter_cid().
| Argument | Description |
|---|---|
lang |
"pt" (default), "en",
"es"
|
output |
"browser" (interactive HTML, default) or
"console" (summary in R) |
filter_climate |
TRUE shows only climate-sensitive groups |
verbose |
Informational messages |
Returns: invisibly, a data.frame with
name, icd_codes, climate_factors,
description, category, and
climate_sensitive.
ICD-10 code syntax
The icd_codes syntax is expanded internally by
process_icd_codes(). A range
"J00-J99" is expanded into the sequence of prefixes
.
Formally, for a range of the same letter
between numbers
and
:
The match_type parameter defines how each code is
compared against the cause column:
-
"exact"— exact equality ("I10"matches only"I10"); -
"starts_with"(default) — prefix ("I10"matches"I10","I10.0","I10.9"), which reflects the ICD-10 hierarchy; -
"range"— matching by any prefix of the expanded range.
The fraction of records retained at each filter is simply
Illustrated results
| Grupo | Codigos CID-10 | Sensivel ao clima | Descricao |
|---|---|---|---|
| cardiovascular | I00-I99 | Sim | Doencas do coracao e sistema circulatorio |
| ischemic_heart | I20-I25 | Sim | Doenca arterial coronariana, infarto do miocardio |
| respiratory | J00-J99 | Sim | Doencas do sistema respiratorio |
| pneumonia | J12-J18 | Sim | Pneumonia viral, bacteriana e nao especificada |
| Etapa | Registros | % da base |
|---|---|---|
| Base padronizada (entrada T2) | 4 | 100 |
| Filtro CID-10: respiratorio (J00-J99) | NA | NA |
| Filtro CID-10: cardiovascular (I00-I99) | NA | NA |
| + Demografia: respiratorio 60+ (RMSP) | NA | NA |
| + Demografia: cardiovascular 60+ (RMSP) | NA | NA |

Figure 1. Filtering funnel. Each bar shows how many records remain after the standardized base, the ICD-10 subset (respiratory, J00–J99), and the demographic subset (older adults 60+ residing in the RMSP). The narrowing illustrates how the analysis object is progressively restricted to the study’s scope.

Figure 2. Deaths in older adults (60+) in the RMSP by major cause group, after the combined filtering (ICD-10 + demographics). The comparison between the respiratory (J) and cardiovascular (I) chapters is the starting point for the climate-sensitivity analysis in the next tutorials.
Artefato indisponível — rode
Rscript scripts/tutorial_03_filtragem.R(a partir da raiz do pacote) para gerá-lo.
Figure 3. Age distribution of respiratory deaths.
The filter age_range = c(60, Inf) retains only the 60–79
and 80+ age groups, making explicit the effect of the demographic subset
on the population analyzed.
Artefato indisponível — rode
Rscript scripts/tutorial_03_filtragem.R(a partir da raiz do pacote) para gerá-lo.
Figure 4. Monthly series of respiratory deaths in older adults (60+) in the RMSP, 2014–2019, after filtering. The winter seasonality — expected for respiratory causes — already appears in the subsetted object and will be compared against temperature in the climate and modeling stages.
References
- Bhaskaran, K., Gasparrini, A., Hajat, S., Smeeth, L., & Armstrong, B. (2013). Time series regression studies in environmental epidemiology. International Journal of Epidemiology, 42(4), 1187–1195.
- Gasparrini, A., Guo, Y., Hashizume, M., et al. (2015). Mortality risk attributable to high and low ambient temperature: a multicountry observational study. The Lancet, 386(9991), 369–375.
- Organização Mundial da Saúde. (2016). CID-10: Classificação Estatística Internacional de Doenças e Problemas Relacionados à Saúde, 10ª revisão.
- Ministério da Saúde (Brasil). DATASUS — CID-10. Available at: http://datasus.saude.gov.br/cid10.