Flujos de Trabajo y Estimacion (ES)
Source:vignettes/workflows-and-estimation-es.Rmd
workflows-and-estimation-es.RmdQue es un Workflow?
Luego de transformar los datos de la encuesta con steps y recipes, la siguiente tarea es la estimacion: calcular medias, totales, razones y sus errores estandar teniendo en cuenta el diseno complejo de la encuesta.
La funcion workflow() envuelve los estimadores del
paquete survey (svymean,
svytotal, svyratio, svyby) y
devuelve resultados ordenados en formato data.table que
incluyen:
- Estimaciones puntuales y errores estandar
- Coeficientes de variacion (CV)
- Intervalos de confianza
- Metadatos para la reproducibilidad
Configuracion inicial
Utilizamos el conjunto de datos Academic Performance Index (API) del
paquete survey, que contiene datos reales de escuelas
estratificadas de California.
library(metasurvey)
library(survey)
library(data.table)
data(api, package = "survey")
dt <- data.table(apistrat)
svy <- Survey$new(
data = dt,
edition = "2000",
type = "api",
psu = NULL,
engine = "data.table",
weight = add_weight(annual = "pw")
)Estimacion basica
Multiples estimaciones a la vez
Es posible pasar varias llamadas de estimacion a
workflow() para calcularlas en un unico paso:
results <- workflow(
list(svy),
survey::svymean(~api00, na.rm = TRUE),
survey::svytotal(~enroll, na.rm = TRUE),
estimation_type = "annual"
)
results
#> stat value se cv confint_lower
#> <char> <num> <num> <num> <num>
#> 1: survey::svymean: api00 662.2874 9.585429e+00 0.01447322 643.5003
#> 2: survey::svytotal: enroll 3687177.5324 1.645323e+05 0.04462283 3364700.1537
#> confint_upper
#> <num>
#> 1: 681.0745
#> 2: 4009654.9112Estimacion por dominio
Utilizamos survey::svyby() para calcular estimaciones
por subpoblaciones (dominios):
# Mean API score by school type
api_by_type <- workflow(
list(svy),
survey::svyby(~api00, ~stype, survey::svymean, na.rm = TRUE),
estimation_type = "annual"
)
api_by_type
#> stat value se cv confint_lower
#> <char> <num> <num> <num> <num>
#> 1: survey::svyby: api00 [stype=E] 674.43 12.49343 0.01852443 649.9433
#> 2: survey::svyby: api00 [stype=H] 625.82 15.34078 0.02451309 595.7526
#> 3: survey::svyby: api00 [stype=M] 636.60 16.50239 0.02592270 604.2559
#> confint_upper stype
#> <num> <fctr>
#> 1: 698.9167 E
#> 2: 655.8874 H
#> 3: 668.9441 M
# Mean enrollment by awards status
enroll_by_award <- workflow(
list(svy),
survey::svyby(~enroll, ~awards, survey::svymean, na.rm = TRUE),
estimation_type = "annual"
)
enroll_by_award
#> stat value se cv
#> <char> <num> <num> <num>
#> 1: survey::svyby: enroll [awards=No] 727.5958 57.54094 0.07908366
#> 2: survey::svyby: enroll [awards=Yes] 520.5114 25.51854 0.04902590
#> confint_lower confint_upper awards
#> <num> <num> <fctr>
#> 1: 614.8177 840.3740 No
#> 2: 470.4960 570.5269 YesEvaluacion de la calidad
El coeficiente de variacion (CV) mide la precision
de la estimacion. Se puede utilizar evaluate_cv() para
clasificar la calidad siguiendo las directrices estandar:
| Rango de CV | Calidad | Recomendacion |
|---|---|---|
| < 5% | Excelente | Usar sin restricciones |
| 5-10% | Muy buena | Usar con confianza |
| 10-15% | Buena | Usar para la mayoria de los propositos |
| 15-25% | Aceptable | Usar con precaucion |
| 25-35% | Deficiente | Solo para tendencias generales |
| >= 35% | No confiable | No publicar |
# Evaluate quality of the API score estimate
cv_pct <- results$cv[1] * 100
quality <- evaluate_cv(cv_pct)
cat("CV:", round(cv_pct, 2), "%\n")
#> CV: 1.45 %
cat("Quality:", quality, "\n")
#> Quality: ExcellentRecipeWorkflow: Estimaciones publicables
Un RecipeWorkflow agrupa llamadas de estimacion con
metadatos, lo que hace que el analisis sea reproducible y compartible.
Registra:
- Que recipes se utilizaron para la preparacion de los datos
- Que llamadas de estimacion se realizaron
- Informacion de autoria y versionado
Creacion de un RecipeWorkflow
wf <- RecipeWorkflow$new(
name = "API Score Analysis 2000",
description = "Mean API score estimation by school type",
user = "Research Team",
survey_type = "api",
edition = "2000",
estimation_type = "annual",
recipe_ids = character(0),
calls = list(
"survey::svymean(~api00, na.rm = TRUE)",
"survey::svyby(~api00, ~stype, survey::svymean, na.rm = TRUE)"
)
)
wf
#>
#> ── Workflow: API Score Analysis 2000 ──
#> Author: Research Team
#> Survey: api / 2000
#> Version: 1.0.0
#> Description: Mean API score estimation by school type
#> Certification: community
#> Estimation types: annual
#>
#> ── Calls (2) ──
#> 1. survey::svymean(~api00, na.rm = TRUE)
#> 2. survey::svyby(~api00, ~stype, survey::svymean, na.rm = TRUE)Publicacion en el registro
Publicamos el workflow para que otros puedan descubrirlo y reutilizarlo:
# Configure a local backend
wf_path <- tempfile(fileext = ".json")
set_workflow_backend("local", path = wf_path)
# Publish
publish_workflow(wf)
# Discover workflows
all_wf <- list_workflows()
length(all_wf)
#> [1] 1
# Search by text
found <- search_workflows("income")
length(found)
#> [1] 0
# Filter by survey type
ech_wf <- filter_workflows(survey_type = "ech")
length(ech_wf)
#> [1] 0Busqueda de workflows asociados a un recipe
Si se dispone de un recipe y se desea conocer que estimaciones han
sido publicadas para el mismo, se puede utilizar
find_workflows_for_recipe():
# Create a workflow that references a recipe
wf2 <- RecipeWorkflow$new(
name = "Labor Market Estimates",
user = "Team",
survey_type = "ech",
edition = "2023",
estimation_type = "annual",
recipe_ids = c("labor_force_recipe_001"),
calls = list("survey::svymean(~employed, na.rm = TRUE)")
)
publish_workflow(wf2)
# Find all workflows that use this recipe
related <- find_workflows_for_recipe("labor_force_recipe_001")
length(related)
#> [1] 1
if (length(related) > 0) cat("Found:", related[[1]]$name, "\n")
#> Found: Labor Market EstimatesCompartir mediante la API remota
Para una difusion mas amplia, es posible publicar workflows en la API de metasurvey:
# Requires authentication
api_login("you@example.com", "password")
# Publish
api_publish_workflow(wf)
# Browse
all <- api_list_workflows(survey_type = "ech")
specific <- api_get_workflow("workflow_id_here")Pipeline completo
A continuacion se presenta un pipeline completo desde los datos crudos hasta la estimacion publicable, utilizando el conjunto de datos API:
# 1. Create survey from real data
dt_full <- data.table(apistrat)
svy_full <- Survey$new(
data = dt_full,
edition = "2000",
type = "api",
psu = NULL,
engine = "data.table",
weight = add_weight(annual = "pw")
)
# 2. Apply steps: compute derived variables
svy_full <- step_compute(svy_full,
api_growth = api00 - api99,
high_growth = ifelse(api00 - api99 > 50, 1L, 0L),
comment = "API score growth indicators"
)
svy_full <- step_recode(svy_full, school_level,
stype == "E" ~ "Elementary",
stype == "M" ~ "Middle",
stype == "H" ~ "High",
.default = "Other",
comment = "School level classification"
)
# 3. Estimate means
estimates <- workflow(
list(svy_full),
survey::svymean(~api_growth, na.rm = TRUE),
survey::svymean(~high_growth, na.rm = TRUE),
estimation_type = "annual"
)
estimates
#> stat value se cv confint_lower
#> <char> <num> <num> <num> <num>
#> 1: survey::svymean: api_growth 32.8925184 2.1583789 0.06561914 28.6621734
#> 2: survey::svymean: high_growth 0.2938489 0.0363651 0.12375443 0.2225746
#> confint_upper
#> <num>
#> 1: 37.1228633
#> 2: 0.3651232
# 4. Domain estimation (by school type)
by_school <- workflow(
list(svy_full),
survey::svyby(~api00, ~stype, survey::svymean, na.rm = TRUE),
estimation_type = "annual"
)
by_school
#> stat value se cv confint_lower
#> <char> <num> <num> <num> <num>
#> 1: survey::svyby: api00 [stype=E] 674.43 12.49343 0.01852443 649.9433
#> 2: survey::svyby: api00 [stype=H] 625.82 15.34078 0.02451309 595.7526
#> 3: survey::svyby: api00 [stype=M] 636.60 16.50239 0.02592270 604.2559
#> confint_upper stype
#> <num> <fctr>
#> 1: 698.9167 E
#> 2: 655.8874 H
#> 3: 668.9441 M
# 5. Assess quality
for (i in seq_len(nrow(estimates))) {
cv_val <- estimates$cv[i] * 100
cat(
estimates$stat[i], ":",
round(cv_val, 1), "% CV -",
evaluate_cv(cv_val), "\n"
)
}
#> survey::svymean: api_growth : 6.6 % CV - Very good
#> survey::svymean: high_growth : 12.4 % CV - GoodProvenance: Linaje de datos
Cada objeto Survey registra metadatos de
provenance: de donde vinieron los datos, que steps se
aplicaron, cuantas filas sobrevivieron a cada paso y que versiones de R
y metasurvey se utilizaron. Esto permite rastrear cualquier estimacion
hasta los datos originales.
# El provenance se completa automaticamente despues de bake_steps()
prov <- provenance(svy_full)
prov
#> ── Data Provenance ─────────────────────────────────────────────────────────────
#> Loaded: 2026-02-25T12:03:10
#> Initial rows: 200
#>
#> Environment:
#> metasurvey: 0.0.21
#> R: 4.5.2
#> survey: 4.5El provenance tambien se adjunta a los resultados de
workflow(), de modo que siempre es posible inspeccionar el
linaje completo de una estimacion:
prov_wf <- provenance(estimates)
cat("metasurvey version:", prov_wf$environment$metasurvey_version, "\n")
#> metasurvey version: 0.0.21
cat("Steps applied:", length(prov_wf$steps), "\n")
#> Steps applied: 0Para pistas de auditoria, se exporta el provenance a JSON:
provenance_to_json(prov, "audit_trail.json")Para comparar dos ejecuciones (por ejemplo, diferentes ediciones), se
utiliza provenance_diff():
diff <- provenance_diff(prov_2022, prov_2023)
diff$steps_changed
diff$n_final_changedTablas de calidad publicacion
workflow_table() formatea los resultados de estimacion
como tablas listas para publicar usando el paquete gt.
Agrega intervalos de confianza, clasificacion de calidad del CV con
colores y notas al pie basadas en el provenance.
workflow_table(estimates)| Survey Estimation Results | ||||||
| Statistic | Estimate | SE | CI Lower | CI Upper | CV (%) | Quality |
|---|---|---|---|---|---|---|
| :svymean: api_growth | 32.89 | 2.158 | 28.66 | 37.12 | 6.6 | Very good |
| :svymean: high_growth | 0.29 | 0.036 | 0.22 | 0.37 | 12.4 | Good |
| metasurvey 0.0.21 | CI: 95% | 2026-02-25 | ||||||
Se puede personalizar la salida:
# Locale en espaniol, ocultar SE, titulo personalizado
workflow_table(
estimates,
locale = "es",
show_se = FALSE,
title = "Indicadores de crecimiento API",
subtitle = "Escuelas de California, 2000"
)| Indicadores de crecimiento API | |||||
| Escuelas de California, 2000 | |||||
| Statistic | Estimate | CI Lower | CI Upper | CV (%) | Quality |
|---|---|---|---|---|---|
| :svymean: api_growth | 32,89 | 28,66 | 37,12 | 6,6 | Very good |
| :svymean: high_growth | 0,29 | 0,22 | 0,37 | 12,4 | Good |
| metasurvey 0.0.21 | CI: 95% | 2026-02-25 | |||||
Para estimaciones por dominio, la tabla detecta automaticamente las columnas de grupo:
workflow_table(by_school)| Survey Estimation Results | |||||||
| Statistic | stype | Estimate | SE | CI Lower | CI Upper | CV (%) | Quality |
|---|---|---|---|---|---|---|---|
| :svyby: api00 | E | 674.43 | 12.493 | 649.94 | 698.92 | 1.9 | Excellent |
| :svyby: api00 | H | 625.82 | 15.341 | 595.75 | 655.89 | 2.5 | Excellent |
| :svyby: api00 | M | 636.60 | 16.502 | 604.26 | 668.94 | 2.6 | Excellent |
| metasurvey 0.0.21 | CI: 95% | 2026-02-25 | |||||||
Se exporta a cualquier formato soportado por
gt::gtsave():
tbl <- workflow_table(estimates)
gt::gtsave(tbl, "estimates.html")
gt::gtsave(tbl, "estimates.docx")
gt::gtsave(tbl, "estimates.png")Proximos pasos
- Creacion y publicacion de Recipes – Construir pipelines de transformacion reproducibles
- Disenos de encuesta y validacion – Estratificacion, conglomerados, pesos replicados
- Estudio de caso: ECH – Analisis completo del mercado laboral con estimacion