Skip to contents

¿Por qué Recipes?

Cualquier persona que trabaje con microdatos de encuestas de hogares conoce este patrón: se descargan los archivos sin procesar, se abre el libro de códigos y se pasan días recodificando la situación laboral, armonizando variables de ingreso y construyendo indicadores. Meses después, un colega comienza el mismo proyecto y escribe el mismo código desde cero.

En STATA, los equipos comparten archivos .do, pero estos están fuertemente acoplados a rutas de archivos y nombres de variables específicos, y no existe una forma estándar de descubrirlos o validarlos.

Las Recipes son la respuesta de metasurvey a este problema. Una recipe es una colección portable, documentada y validada de pasos de transformación que puede:

  • Aplicarse a cualquier edición compatible de una encuesta con una sola llamada a función
  • Publicarse en un registro donde otros pueden descubrirlas y reutilizarlas
  • Ser certificada por instituciones para uso oficial
  • Generar documentación automática de inputs, outputs y pipeline

Ciclo de Vida de una Recipe

  ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
  │ 1. Desarrollar│────▶│ 2. Empaquetar │────▶│  3. Validar   │
  │  steps sobre  │     │  steps en     │     │  contra datos │
  │  una encuesta │     │  una recipe   │     │  nuevos       │
  └──────────────┘     └──────────────┘     └──────┬───────┘
                                                    │
  ┌──────────────┐     ┌──────────────┐             │
  │ 5. Descubrir  │◀────│ 4. Publicar   │◀────────────┘
  │  y reutilizar │     │  en registro  │
  │  recipes      │     │  o API        │
  └──────────────┘     └──────────────┘

Cargando una Encuesta

El punto de partida típico es cargar una encuesta con load_survey(). Se pueden cargar datos de ejemplo o apuntar a archivos propios:

library(metasurvey)

# Cargar ECH 2022 con datos de ejemplo
ech_2022 <- load_survey(
  load_survey_example("ech", "ech_2022"),
  svy_type    = "ech",
  svy_edition = "2022",
  svy_weight  = add_weight(annual = "pesoano")
)

# O cargar con recipes existentes del registry
ech_2022 <- load_survey(
  load_survey_example("ech", "ech_2022"),
  svy_type    = "ech",
  svy_edition = "2022",
  svy_weight  = add_weight(annual = "pesoano"),
  recipes     = get_recipe("ech", "2022")
)

Construyendo una Recipe a partir de Steps

El flujo de trabajo más común consiste en desarrollar las transformaciones de forma interactiva sobre una encuesta y luego convertir los steps registrados en una recipe.

library(metasurvey)
library(data.table)

set.seed(42)
n <- 200

# Simular microdatos de encuesta (sustituto de load_survey)
dt <- data.table(
  id = 1:n,
  age = sample(18:80, n, replace = TRUE),
  sex = sample(c(1, 2), n, replace = TRUE),
  income = round(runif(n, 5000, 80000)),
  activity = sample(c(2, 3, 5, 6), n,
    replace = TRUE,
    prob = c(0.55, 0.05, 0.05, 0.35)
  ),
  weight = round(runif(n, 0.5, 3.0), 4)
)

svy <- Survey$new(
  data    = dt,
  edition = "2023",
  type    = "ech",
  psu     = NULL,
  engine  = "data.table",
  weight  = add_weight(annual = "weight")
)

# Desarrollar transformaciones interactivamente
svy <- step_compute(svy,
  income_thousands = income / 1000,
  employed = ifelse(activity == 2, 1L, 0L),
  comment = "Escalado de ingreso e indicador de empleo"
)

svy <- step_recode(svy, labor_status,
  activity == 2 ~ "Empleado",
  activity %in% 3:5 ~ "Desempleado",
  activity %in% 6:8 ~ "Inactivo",
  .default = "Otro",
  comment = "Clasificacion OIT de fuerza laboral"
)

svy <- step_recode(svy, age_group,
  age < 25 ~ "Joven",
  age < 45 ~ "Adulto",
  age < 65 ~ "Maduro",
  .default = "Mayor",
  comment = "Grupos etarios estandar"
)

# Convertir todos los steps a una recipe
labor_recipe <- steps_to_recipe(
  name        = "Indicadores de Fuerza Laboral",
  user        = "Equipo de Investigacion",
  svy         = svy,
  description = "Indicadores estandar de fuerza laboral segun definiciones OIT",
  steps       = get_steps(svy),
  topic       = "labor"
)

labor_recipe
#> 
#> ── Recipe: Indicadores de Fuerza Laboral ──
#> Author:  Equipo de Investigacion
#> Survey:  ech / 2023
#> Version: 1.0.0
#> Topic:   labor
#> Description: Indicadores estandar de fuerza laboral segun definiciones OIT
#> Certification: community
#> 
#> ── Requires (3 variables) ──
#>   income, activity, age
#> 
#> ── Pipeline (3 steps) ──
#>   1. [compute] -> income_thousands, employed  "Escalado de ingreso e indicador de empleo"
#>   2. [recode] -> labor_status  "Clasificacion OIT de fuerza laboral"
#>   3. [recode] -> age_group  "Grupos etarios estandar"
#> 
#> ── Produces (4 variables) ──
#>   labor_status [categorical], age_group [categorical], income_thousands [numeric], employed [numeric]

Documentación de Recipes

Toda recipe puede generar automáticamente su documentación a partir de sus steps. El método doc() devuelve una lista con las variables de entrada, las variables de salida y el pipeline paso a paso:

doc <- labor_recipe$doc()
names(doc)
#> [1] "meta"             "input_variables"  "output_variables" "pipeline"
# ¿Qué variables necesita la recipe?
doc$input_variables
#> [1] "income"   "activity" "age"

# ¿Qué variables crea?
doc$output_variables
#> [1] "income_thousands" "employed"         "labor_status"     "age_group"

# Pipeline paso a paso
doc$pipeline
#> [[1]]
#> [[1]]$index
#> [1] 1
#> 
#> [[1]]$type
#> [1] "compute"
#> 
#> [[1]]$outputs
#> [1] "income_thousands" "employed"        
#> 
#> [[1]]$inputs
#> [1] "income"   "activity"
#> 
#> [[1]]$inferred_type
#> [1] "numeric"
#> 
#> [[1]]$comment
#> [1] "Escalado de ingreso e indicador de empleo"
#> 
#> 
#> [[2]]
#> [[2]]$index
#> [1] 2
#> 
#> [[2]]$type
#> [1] "recode"
#> 
#> [[2]]$outputs
#> [1] "labor_status"
#> 
#> [[2]]$inputs
#> [1] "activity"
#> 
#> [[2]]$inferred_type
#> [1] "categorical"
#> 
#> [[2]]$comment
#> [1] "Clasificacion OIT de fuerza laboral"
#> 
#> 
#> [[3]]
#> [[3]]$index
#> [1] 3
#> 
#> [[3]]$type
#> [1] "recode"
#> 
#> [[3]]$outputs
#> [1] "age_group"
#> 
#> [[3]]$inputs
#> [1] "age"
#> 
#> [[3]]$inferred_type
#> [1] "categorical"
#> 
#> [[3]]$comment
#> [1] "Grupos etarios estandar"

Esta documentación se genera automáticamente, sin necesidad de esfuerzo manual.

Validación

Antes de aplicar una recipe a nuevos datos, es conveniente verificar que todas las variables requeridas existan. El método validate() se detiene con un error claro si falta alguna dependencia:

labor_recipe$validate(svy)
#> [1] TRUE

Aplicación de Recipes a una Encuesta

Se pueden adjuntar una o más recipes a una encuesta y aplicarlas con bake_recipes():

# Crear una encuesta nueva con la misma estructura (simulando una nueva edición)
set.seed(99)
dt2 <- data.table(
  id = 1:100,
  age = sample(18:80, 100, replace = TRUE),
  sex = sample(c(1, 2), 100, replace = TRUE),
  income = round(runif(100, 5000, 80000)),
  activity = sample(c(2, 3, 5, 6), 100,
    replace = TRUE,
    prob = c(0.55, 0.05, 0.05, 0.35)
  ),
  weight = round(runif(100, 0.5, 3.0), 4)
)

svy2 <- Survey$new(
  data = dt2, edition = "2024", type = "ech",
  psu = NULL, engine = "data.table",
  weight = add_weight(annual = "weight")
)

# Adjuntar y aplicar
svy2 <- add_recipe(svy2, labor_recipe)
svy2 <- bake_recipes(svy2)

head(get_data(svy2)[, .(id, income_thousands, labor_status, age_group)], 5)
#>       id income_thousands labor_status age_group
#>    <int>            <num>       <char>    <char>
#> 1:     1           47.346  Desempleado     Mayor
#> 2:     2           28.114     Empleado    Maduro
#> 3:     3           43.583     Empleado    Maduro
#> 4:     4           13.440  Desempleado    Maduro
#> 5:     5           55.638     Empleado     Mayor

La misma recipe aplicada a una edición diferente produce resultados consistentes. Así es como metasurvey garantiza la reproducibilidad a lo largo del tiempo.

En la práctica, se puede cargar una encuesta y aplicar recipes publicadas en una sola llamada:

# Cargar ECH 2023 y aplicar la recipe laboral del registry
ech_2023 <- load_survey(
  load_survey_example("ech", "ech_2023"),
  svy_type    = "ech",
  svy_edition = "2023",
  svy_weight  = add_weight(annual = "pesoano"),
  recipes     = get_recipe("ech", "2023", topic = "labor_market"),
  bake        = TRUE
)

Categorías

Las categorías ayudan a organizar las recipes por tema:

cats <- default_categories()
vapply(cats, function(c) c$name, character(1))
#> [1] "labor_market" "income"       "education"    "health"       "demographics"
#> [6] "housing"

Agregar categorías a una recipe con add_category():

labor_recipe <- add_category(labor_recipe, "labor_market", "Analisis del mercado laboral")
labor_recipe <- add_category(labor_recipe, "income", "Indicadores de ingreso")
labor_recipe
#> 
#> ── Recipe: Indicadores de Fuerza Laboral ──
#> Author:  Equipo de Investigacion
#> Survey:  ech / 2023
#> Version: 1.0.0
#> Topic:   labor
#> Description: Indicadores estandar de fuerza laboral segun definiciones OIT
#> Certification: community
#> Categories: labor_market, income
#> 
#> ── Requires (3 variables) ──
#>   income, activity, age
#> 
#> ── Pipeline (3 steps) ──
#>   1. [compute] -> income_thousands, employed  "Escalado de ingreso e indicador de empleo"
#>   2. [recode] -> labor_status  "Clasificacion OIT de fuerza laboral"
#>   3. [recode] -> age_group  "Grupos etarios estandar"
#> 
#> ── Produces (4 variables) ──
#>   labor_status [categorical], age_group [categorical], income_thousands [numeric], employed [numeric]

Certificación

El sistema de certificación ofrece tres niveles de confianza:

Nivel Significado
community Contribución de usuario (por defecto), sin revisión
reviewed Revisada por pares de un equipo reconocido
official Avalada para estadísticas oficiales

Los niveles de certificación más altos aparecen primero en los resultados de búsqueda e indican que la recipe ha sido revisada.

Publicación y Descubrimiento de Recipes

El verdadero poder de las recipes radica en compartirlas. Cada recipe que crees puede ser publicada en el registry de metasurvey, donde otros investigadores pueden descubrirla, reutilizarla y construir sobre tu trabajo.

Publicar en el Registry Público

El flujo recomendado es publicar las recipes en la API pública. Cualquier persona puede explorar recipes sin cuenta; para publicar se necesita registro:

# Una sola vez: registrarse y autenticarse
api_register("Tu Nombre", "tu@email.com", "password")
api_login("tu@email.com", "password")

# Publicar tu recipe (tu perfil se adjunta automáticamente)
api_publish_recipe(labor_recipe)

Al estar autenticado, api_publish_recipe() adjunta automáticamente tu perfil de usuario a la recipe. Los demás usuarios ven quién la publicó, junto con la afiliación institucional y el nivel de certificación. Esto genera responsabilidad y confianza en las recipes compartidas.

Exploración y Búsqueda

No se necesita autenticación para explorar y descargar recipes:

# Explorar todas las recipes de la ECH
ech_recipes <- api_list_recipes(survey_type = "ech")

# Obtener una recipe por ID
r <- api_get_recipe(id = "recipe_id_aqui")

Explorador Interactivo

La app Shiny provee una interfaz visual para explorar recipes y workflows:

El explorador muestra tarjetas de recipes con badges de certificacion, conteo de descargas y preview del pipeline. Al hacer clic en una recipe se abre una vista de detalle con el pipeline completo, snippet de codigo R y links a workflows relacionados.

Registry Privado para Instituciones

Las instituciones que trabajan con encuestas confidenciales o de acceso restringido pueden necesitar un registry privado. metasurvey soporta esto mediante un backend propio con MongoDB:

# Apuntar a la API privada de tu institución
configure_api("https://tu-institucion.example.com/api")

# A partir de aquí, el flujo es idéntico
api_login("analista@institucion.edu", "password")
api_publish_recipe(labor_recipe)
api_list_recipes(survey_type = "ech")

Consulta la vignette API y Base de Datos para instrucciones sobre cómo desplegar la API Plumber con MongoDB para tu propia organización.

Buenas Prácticas

  1. Nombrar las recipes de forma descriptiva – incluir el tipo de encuesta y el tema (por ejemplo, "ECH Indicadores de Fuerza Laboral").
  2. Agregar descripciones – documentar qué calcula la recipe y por qué.
  3. Usar categorías y temas – facilitar que las recipes sean descubribles.
  4. Validar antes de compartir – llamar a validate() sobre datos de ejemplo para asegurar que todas las dependencias existan.
  5. Versionar las recipes – usar set_version() al actualizarlas.

Próximos Pasos