Flujos de Trabajo y Estimacion (ES)
Source:vignettes/workflows-and-estimation-es.Rmd
workflows-and-estimation-es.Rmd¿Qué es un Workflow?
Luego de transformar los datos de la encuesta con steps y recipes, la siguiente tarea es la estimación: calcular medias, totales, razones y sus errores estándar teniendo en cuenta el diseño complejo de la encuesta.
La función 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 estándar
- Coeficientes de variación (CV)
- Intervalos de confianza
- Metadatos para la reproducibilidad
Configuración inicial
Utilizamos el conjunto de datos Academic Performance Index (API) del
paquete survey, que contiene datos reales de una muestra
estratificada de escuelas de California.
library(metasurvey.core)
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")
)Estimación básica
Media
Estimamos la media poblacional del puntaje API en el año 2000:
result <- workflow(
list(svy),
survey::svymean(~api00, na.rm = TRUE),
estimation_type = "annual"
)
result
#> stat variable value se cv confint_lower
#> <char> <char> <num> <num> <num> <num>
#> 1: survey::svymean: api00 api00 662.2874 9.585429 0.01447322 643.5003
#> confint_upper evaluate
#> <num> <char>
#> 1: 681.0745 ExcellentTotal
Estimamos la matriculación total en todas las escuelas:
result_total <- workflow(
list(svy),
survey::svytotal(~enroll, na.rm = TRUE),
estimation_type = "annual"
)
result_total
#> stat variable value se cv confint_lower
#> <char> <char> <num> <num> <num> <num>
#> 1: survey::svytotal: enroll enroll 3687178 164532.3 0.04462283 3364700
#> confint_upper evaluate
#> <num> <char>
#> 1: 4009655 ExcellentMúltiples estimaciones a la vez
Se pueden pasar varias llamadas de estimación a
workflow() para calcularlas en un único paso:
results <- workflow(
list(svy),
survey::svymean(~api00, na.rm = TRUE),
survey::svytotal(~enroll, na.rm = TRUE),
estimation_type = "annual"
)
results
#> stat variable value se cv
#> <char> <char> <num> <num> <num>
#> 1: survey::svymean: api00 api00 662.2874 9.585429e+00 0.01447322
#> 2: survey::svytotal: enroll enroll 3687177.5324 1.645323e+05 0.04462283
#> confint_lower confint_upper evaluate
#> <num> <num> <char>
#> 1: 643.5003 681.0745 Excellent
#> 2: 3364700.1537 4009654.9112 ExcellentEstimación 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 variable value se cv confint_lower
#> <char> <char> <num> <num> <num> <num>
#> 1: survey::svyby: api00 api00 674.43 12.49343 0.01852443 649.9433
#> 2: survey::svyby: api00 api00 625.82 15.34078 0.02451309 595.7526
#> 3: survey::svyby: api00 api00 636.60 16.50239 0.02592270 604.2559
#> confint_upper evaluate stype
#> <num> <char> <fctr>
#> 1: 698.9167 Excellent E
#> 2: 655.8874 Excellent H
#> 3: 668.9441 Excellent 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 variable value se cv confint_lower
#> <char> <char> <num> <num> <num> <num>
#> 1: survey::svyby: enroll enroll 727.5958 57.54094 0.07908366 614.8177
#> 2: survey::svyby: enroll enroll 520.5114 25.51854 0.04902590 470.4960
#> confint_upper evaluate awards
#> <num> <char> <fctr>
#> 1: 840.3740 Very good No
#> 2: 570.5269 Excellent YesEvaluación de la calidad
El coeficiente de variación (CV) mide la precisión
de la estimación. Se puede utilizar evaluate_cv() para
clasificar la calidad siguiendo las directrices estándar:
| Rango de CV | Calidad | Recomendación |
|---|---|---|
| < 5% | Excelente | Usar sin restricciones |
| 5-10% | Muy buena | Usar con confianza |
| 10-15% | Buena | Usar para la mayoría de los propósitos |
| 15-25% | Aceptable | Usar con precaución |
| 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 estimación con
metadatos, lo que hace que el análisis sea reproducible y compartible.
Registra:
- Qué recipes se utilizaron para la preparación de los datos
- Qué llamadas de estimación se realizaron
- Información de autoría y versionado
Creación 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)Publicación 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] 0Búsqueda de workflows asociados a un recipe
Si se dispone de un recipe y se quiere saber qué estimaciones se
publicaron para él, 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 = "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 difusión más amplia, se pueden publicar workflows en la API
de metasurvey. Las funciones api_*() que aparecen a
continuación las provee el paquete acompañante metasurvey.explorer.backend,
no metasurvey.core:
library(metasurvey.explorer.backend)
# 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 continuación se presenta un pipeline completo, desde los datos crudos hasta la estimación 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 = as.integer(api00 - api99 > 50),
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 variable value se cv
#> <char> <char> <num> <num> <num>
#> 1: survey::svymean: api_growth api_growth 32.8925184 2.1583789 0.06561914
#> 2: survey::svymean: high_growth high_growth 0.2938489 0.0363651 0.12375443
#> confint_lower confint_upper evaluate
#> <num> <num> <char>
#> 1: 28.6621734 37.1228633 Very good
#> 2: 0.2225746 0.3651232 Good
# 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 variable value se cv confint_lower
#> <char> <char> <num> <num> <num> <num>
#> 1: survey::svyby: api00 api00 674.43 12.49343 0.01852443 649.9433
#> 2: survey::svyby: api00 api00 625.82 15.34078 0.02451309 595.7526
#> 3: survey::svyby: api00 api00 636.60 16.50239 0.02592270 604.2559
#> confint_upper evaluate stype
#> <num> <char> <fctr>
#> 1: 698.9167 Excellent E
#> 2: 655.8874 Excellent H
#> 3: 668.9441 Excellent 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 dónde vinieron los datos, qué steps se
aplicaron, cuántas filas sobrevivieron a cada paso y qué versiones de R
y metasurvey se utilizaron. Esto permite rastrear cualquier estimación
hasta los datos originales.
# El provenance se completa automaticamente despues de bake_steps()
prov <- provenance(svy_full)
prov
#> ── Data Provenance ─────────────────────────────────────────────────────────────
#> Loaded: 2026-10-12T14:36:03
#> Initial rows: 200
#>
#> Environment:
#> metasurvey: 0.3.1
#> R: 4.6.1
#> survey: 4.5El provenance también se adjunta a los resultados de
workflow(), de modo que siempre se puede inspeccionar el
linaje completo de una estimación:
prov_wf <- provenance(estimates)
cat("metasurvey version:", prov_wf$environment$metasurvey_version, "\n")
#> metasurvey version: 0.3.1
cat("Steps applied:", length(prov_wf$steps), "\n")
#> Steps applied: 0Para dejar un registro de auditoría, se puede exportar 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 con calidad de publicación
workflow_table() formatea los resultados de estimación
como tablas listas para publicar usando el paquete gt.
Agrega intervalos de confianza, clasificación de calidad del CV con
colores y notas al pie basadas en el provenance.
workflow_table(estimates)| Survey Estimation Results | |||||||
| Statistic | variable | Estimate | SE | CI Lower | CI Upper | CV (%) | Quality |
|---|---|---|---|---|---|---|---|
| :svymean: api_growth | api_growth | 32.89 | 2.158 | 28.66 | 37.12 | 6.6 | Very good |
| :svymean: high_growth | high_growth | 0.29 | 0.036 | 0.22 | 0.37 | 12.4 | Good |
| metasurvey 0.3.1 | CI: 95% | 2026-10-12 | |||||||
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 | variable | Estimate | CI Lower | CI Upper | CV (%) | Quality |
|---|---|---|---|---|---|---|
| :svymean: api_growth | api_growth | 32,89 | 28,66 | 37,12 | 6,6 | Very good |
| :svymean: high_growth | high_growth | 0,29 | 0,22 | 0,37 | 12,4 | Good |
| metasurvey 0.3.1 | CI: 95% | 2026-10-12 | ||||||
Para estimaciones por dominio, la tabla detecta automáticamente las columnas de grupo:
workflow_table(by_school)| Survey Estimation Results | ||||||||
| Statistic | variable | stype | Estimate | SE | CI Lower | CI Upper | CV (%) | Quality |
|---|---|---|---|---|---|---|---|---|
| :svyby: api00 | api00 | E | 674.43 | 12.493 | 649.94 | 698.92 | 1.9 | Excellent |
| :svyby: api00 | api00 | H | 625.82 | 15.341 | 595.75 | 655.89 | 2.5 | Excellent |
| :svyby: api00 | api00 | M | 636.60 | 16.502 | 604.26 | 668.94 | 2.6 | Excellent |
| metasurvey 0.3.1 | CI: 95% | 2026-10-12 | ||||||||
La tabla se puede exportar a cualquier formato que admita
gt::gtsave():
tbl <- workflow_table(estimates)
gt::gtsave(tbl, "estimates.html")
gt::gtsave(tbl, "estimates.docx")
gt::gtsave(tbl, "estimates.png")Próximos pasos
- Creación y publicación de Recipes – Construir pipelines de transformación reproducibles
- Diseños de encuesta y validación – Estratificación, conglomerados, pesos replicados
- Caso de estudio ECH – Análisis completo del mercado laboral con estimación