Skip to contents

Objetivo

Al final de este tutorial usted será capaz de dejar la base bruta del DATASUS lista para el análisis, ejecutando las dos funciones de la segunda etapa del pipeline:

  1. sus_data_clean_encoding() — audita las columnas de texto y corrige problemas de codificación de caracteres (texto Latin1 leído como UTF-8, que convierte “São Paulo” en secuencias ilegibles);
  2. sus_data_standardize() — traduce los nombres de las columnas a etiquetas legibles y decodifica los valores categóricos (por ejemplo, SEXO = 1 se convierte en "Masculino", RACACOR = 4 se convierte en "Parda"), además de convertir columnas de fecha al tipo Date. Todo esto de forma multilingüe ("pt", "en", "es").

Esta es la segunda etapa del pipeline (import → clean → stand → …). Ella transforma una tabla con nombres crípticos y códigos numéricos en una tabla auditable, que los tutoriales siguientes (filtrado, creación de variables, agregación) pueden manipular sin ambigüedad.

Contexto científico

Los microdatos del DATASUS se distribuyen en archivos .dbc heredados de sistemas antiguos, que graban texto en Latin1 (ISO-8859-1). Cuando esos bytes se leen como UTF-8, los acentos y las eñes se convierten en “mojibake” — caracteres corruptos que rompen las uniones por nombre, las agrupaciones y los informes. El paquete microdatasus (Saldanha, Bastos & Barcellos, 2019) ya realiza buena parte del preprocesamiento, pero sus_data_clean_encoding() actúa como auditor final, garantizando que toda columna de texto sea UTF-8 válido antes del análisis.

Además de la codificación, los campos del SIM, SIH, SINAN y demás sistemas llegan con nombres abreviados (CAUSABAS, CODMUNRES, DTOBITO) y categorías codificadas en números (Brasil, Ministério da Saúde). Trabajar directamente con esos códigos es frágil y propenso a errores. La estandarización hacia un vocabulario controlado y legible — y la posibilidad de producirlo en tres idiomas — es lo que hace que el análisis sea reproducible y comunicable a lectores de diferentes países (principio FAIR de interoperabilidad; Wilkinson et al., 2016).

Caso conductor. Investigamos la temperatura y los desenlaces de salud en personas mayores (60+) en la Región Metropolitana de São Paulo, 2014–2019. En el Tutorial 1 armamos la base bruta multi-sistema (caso_base_importado.rds). Aquí tomamos la base de defunciones (SIM-DO), corregimos su codificación y estandarizamos nombres/categorías (sexo, raza/color, CID, fechas). El resultado se guarda en caso_padronizado.rds, la entrada del Tutorial 3 (Filtrado).

Datos utilizados

Objeto Origen Papel en el caso
caso_base_importado$obitos SIM-DO (Tutorial 1) Base bruta a limpiar y estandarizar
Diccionario de traducción PT/EN/ES R/utils-i18n.R Mapea códigos → etiquetas por sistema

Recorte: estado de São Paulo, 2014–2019. Si el .rds del Tutorial 1 aún no existe, el script de generación recurre a un ejemplo mínimo (texto deliberadamente en Latin1) para que la etapa siga siendo ilustrable sin conexión.

Pipeline completo

Los bloques a continuación reproducen lo que ejecuta el script scripts/tutorial_02_encoding_padronizacao.R. Comience cargando el paquete y la base del tutorial anterior:

library(climasus4r)

caso_base   <- readRDS("vignettes-pt/dados/caso_base_importado.rds")
obitos_bruto <- caso_base$obitos

Paso 1 — Corregir la codificación

sus_data_clean_encoding() recorre todas las columnas de texto, detecta las que contienen bytes UTF-8 inválidos y las convierte de Latin1 a UTF-8. Las columnas numéricas y de fecha se ignoran.

obitos_utf8 <- sus_data_clean_encoding(
  df      = obitos_bruto,
  backend = "tibble",   # "arrow" (lazy, padrão) ou "tibble" (em memória)
  lang    = "pt",        # idioma das mensagens: "pt", "en", "es"
  verbose = TRUE         # imprime quais colunas foram corrigidas
)

Paso 2 — Estandarizar nombres y categorías

sus_data_standardize() detecta automáticamente el sistema (SIM, SIH, SINAN, …), traduce los nombres de las columnas al vocabulario controlado y decodifica los valores categóricos en el idioma elegido. También convierte las columnas de fecha (prefijo data_ en portugués) al tipo Date.

obitos_padr <- sus_data_standardize(
  df                 = obitos_utf8,
  lang               = "pt",   # "pt" / "en" / "es"
  translate_columns  = TRUE,   # CAUSABAS -> causa_basica, SEXO -> sexo, ...
  standardize_values = TRUE,   # 1 -> Masculino; 4 -> Parda; ...
  keep_original      = FALSE,  # TRUE mantém as colunas originais lado a lado
  backend            = "tibble",
  verbose            = TRUE
)

Encadenando las dos funciones

Como toda función de la etapa recibe y devuelve un climasus_df, las dos se encadenan naturalmente con el pipe — exactamente la forma recomendada de uso:

obitos_padr <- obitos_bruto |>
  sus_data_clean_encoding(backend = "tibble", lang = "pt") |>
  sus_data_standardize(lang = "pt", backend = "tibble")

Al final, obitos_padr es la base limpia y estandarizada — con stage = "stand" en los metadatos — que guardamos para el próximo tutorial.

Características de las funciones

sus_data_clean_encoding()

Auditor final de codificación. Detecta columnas de texto con bytes UTF-8 inválidos y convierte Latin1 → UTF-8.

Argumento ¿Esencial? Descripción
df sí data.frame/tibble/climasus_df (u objeto Arrow recolectable)
backend opcional "arrow" (lazy, por defecto) o "tibble" (en memoria); con "arrow", recae en tibble si la evaluación perezosa falla
lang opcional Idioma de los mensajes: "pt" (por defecto), "en", "es"
verbose opcional TRUE (por defecto) imprime las columnas verificadas y corregidas

Cómo funciona. Para cada columna de texto, se prueba stringi::stri_enc_isutf8() sobre los valores no nulos; si cualquier valor es UTF-8 inválido, la columna se considera “enferma” y se convierte completa con stringi::stri_conv(x, "latin1", "utf8"). En el backend "arrow", se usa una muestra de hasta 10.000 filas para detectar qué columnas necesitan corrección.

Retorno: un climasus_df con las columnas de texto en UTF-8 válido, stage = "clean" y una entrada de historial que registra la corrección.

sus_data_standardize()

Traduce nombres de columnas y decodifica valores categóricos, con detección automática del sistema DATASUS.

Argumento ¿Esencial? Descripción
df sí Salida de sus_data_import() / sus_data_clean_encoding()
lang opcional Idioma de nombres y etiquetas: "pt" (por defecto), "en", "es"
translate_columns opcional TRUE (por defecto) traduce los nombres de las columnas
standardize_values opcional TRUE (por defecto) decodifica los valores categóricos
keep_original opcional TRUE mantiene las columnas originales junto a las traducidas
backend opcional "arrow" (lazy, por defecto) o "tibble" (en memoria)
verbose opcional TRUE (por defecto) imprime el informe de estandarización

Etapas internas. (1) detecta el sistema (detect_health_system() o metadatos); (2) traduce nombres de columnas según el diccionario del sistema/idioma; (3) decodifica valores categóricos (ej.: SEXO, RACACOR, LOCOCOR) a factores legibles; (4) convierte columnas de fecha a Date con formatos explícitos (%Y-%m-%d, %Y%m%d, %d%m%Y), de modo portátil entre sistemas operativos.

Retorno: un climasus_df con stage = "stand", system completado y nombres de columnas únicos (make.unique()).

Detección de codificación: la heurística

La regla de decisión de sus_data_clean_encoding() para marcar una columna cc como “a corregir” puede escribirse como:

corrigir(c)=[∃x∈c:¬isUTF8(x)] \text{corrigir}(c) \;=\; \Bigl[\; \exists\, x \in c \;:\; \neg\,\mathrm{isUTF8}(x) \;\Bigr]

es decir, basta un valor con bytes UTF-8 inválidos para que toda la columna sea convertida de Latin1 a UTF-8. Como diagnóstico, el script de generación mide la fracción de cadenas inválidas por columna, antes y después:

finv(c)=1nc∑i=1nc𝟏[¬isUTF8(xi)] f_{\text{inv}}(c) \;=\; \frac{1}{n_c}\sum_{i=1}^{n_c} \mathbf{1}\!\left[\neg\,\mathrm{isUTF8}(x_i)\right]

donde ncn_c es el número de valores no nulos de la columna. Tras la corrección, finv(c)=0f_{\text{inv}}(c) = 0 para toda columna de texto.

Sistemas y diccionarios soportados

sus_data_standardize() carga un diccionario diferente según el sistema detectado. Cada sistema tiene diccionarios en los tres idiomas (pt, en, es):

  • SIM — get_translation_dict_{pt,en,es}()
  • SIH — get_translation_dict_{pt,en,es}_sih()
  • SINAN — get_translation_dict_{pt,en,es}_sinan()
  • CNES — get_translation_dict_{pt,en,es}_cnes()
  • SINASC — get_translation_dict_{pt,en,es}_sinasc()
  • SIA (y subtipos AM, AQ, AR, AD, PS) — get_translation_dict_*_sia*()

La tabla a continuación muestra una muestra del diccionario PT del SIM usado para decodificar los valores categóricos del caso conductor (sexo, raza/color y lugar de ocurrencia de la defunción):

Tabla 1. Muestra del diccionario de traducción SIM (pt): código numérico → etiqueta legible.
Variavel Codigo Rotulo
SEXO (sexo) 1 Masculino
SEXO (sexo) 2 Feminino
SEXO (sexo) 0 Ignorado
RACACOR (raca) 1 Branca
RACACOR (raca) 2 Preta
RACACOR (raca) 3 Amarela
RACACOR (raca) 4 Parda
RACACOR (raca) 5 Indigena
RACACOR (raca) 9 Ignorado
LOCOCOR (local_ocorrencia_obito) 1 Hospital
LOCOCOR (local_ocorrencia_obito) 2 Outro estabelecimento de saude
LOCOCOR (local_ocorrencia_obito) 3 Domicilio
LOCOCOR (local_ocorrencia_obito) 4 Via publica
LOCOCOR (local_ocorrencia_obito) 5 Outros
LOCOCOR (local_ocorrencia_obito) 6 Aldeia indigena
LOCOCOR (local_ocorrencia_obito) 9 Ignorado

Resultados ilustrados

Figura 1. Diagnóstico de codificación antes y después de sus_data_clean_encoding(). Cada barra es el porcentaje de cadenas con bytes UTF-8 inválidos en una columna de texto. Tras la conversión Latin1 → UTF-8, la fracción de inválidos cae a cero — sin ninguna alteración en el contenido legible.

Figura 2. Distribución de defunciones por sexo después de la estandarización. Los códigos numéricos del SIM (1, 2) fueron decodificados a etiquetas legibles (Masculino, Feminino) por sus_data_standardize(), listos para su uso en gráficos y tablas.

Figura 3. Distribución de defunciones por raza/color después de la estandarización. Los códigos (1–5, 9) fueron traducidos a Branca, Preta, Amarela, Parda, Indígena e Ignorado. Esta decodificación es un prerrequisito para los análisis de equidad en salud en las etapas siguientes.

Tabla 2. Resumen de la etapa: dimensiones, codificación, sistema detectado y estadio del pipeline.
Indicador Valor
Linhas 4
Colunas (bruto) 8
Colunas (padronizado) 8
Colunas de texto auditadas 8
Sistema detectado SIM
Estagio (sus_meta$stage) stand
Idioma de saida pt

Tabla 2. Resumen del antes/después de la etapa. El stage de los metadatos avanza a stand, señalando a los tutoriales siguientes que la base ya está estandarizada.

Referencias

  • Brasil. Ministério da Saúde. Manual de Instruções para o preenchimento da Declaração de Óbito. Brasília: Ministério da Saúde. (Define os códigos das variáveis do SIM, como SEXO, RACACOR e LOCOCOR.)
  • Saldanha, R. de F., Bastos, R. R., & Barcellos, C. (2019). Microdatasus: pacote para download e pré-processamento de microdados do Departamento de Informática do SUS (DATASUS). Cadernos de Saúde Pública, 35(9), e00032419.
  • Wilkinson, M. D., et al. (2016). The FAIR Guiding Principles for scientific data management and stewardship. Scientific Data, 3, 160018.