lupa implementa un modelo de calidad de uso general. La arquitectura sigue el linaje de dimensiones, factores y métricas descrito por Batini y Scannapieco (2016), y permite que cada usuario declare la taxonomía pertinente para su dominio. El marco de AGESIC viene incluido como una instancia verificable, no como una restricción del núcleo.
Declarar dimensiones y factores
marco_calidad() recibe una tabla o una lista con nombres. El resultado es consultable y puede validar que las métricas de un modelo() pertenezcan a los factores declarados.
marco_propio <- marco_calidad("Marco de procedencia", list(
Trazabilidad = c("Origen documentado", "Linaje reproducible"),
Pertinencia = "Adecuación al uso"
))
marco_propio
#>
#> ── Marco de procedencia ──
#>
#> Dimensiones: 2
#> Factores: 3
#> Origen: usuario
as.data.frame(marco_propio)[, c("dimension", "factor")]
#> dimension factor
#> 1 Trazabilidad Origen documentado
#> 2 Trazabilidad Linaje reproducible
#> 3 Pertinencia Adecuación al usoDimensión, factor y métrica son una taxonomía
Una dimensión reúne factores y un factor reúne métricas. Esa jerarquía permite clasificar y navegar el modelo, pero el marco no define una fórmula que produzca un “puntaje de Exactitud” ni un índice global. Promediar factores sin un contrato adicional ocultaría prioridades y correlaciones entre ellos.
Por eso lupa conserva dimension y factor en cada medida, pero agregar() sólo acepta las transiciones de granularidad declaradas.
granularidades()
#> nivel granularidad relacional implementada
#> 1 1 instanciaAtributo celda TRUE
#> 2 2 atributo columna TRUE
#> 3 3 conjuntoAtributos conjunto de columnas TRUE
#> 4 4 instanciaEntidad tupla TRUE
#> 5 5 entidad tabla TRUE
#> 6 6 conjuntoEntidades conjunto de tablas TRUE
#> 7 7 coleccion base de datos FALSE
#> 8 8 conjuntoColecciones <NA> FALSE
#> 9 9 organizacion <NA> FALSE
#> 10 10 conjuntoOrganizaciones <NA> FALSE
transiciones_granularidad()
#> origen destino fuente
#> 1 instanciaAtributo atributo marco
#> 2 instanciaAtributo instanciaEntidad extension_documentada
#> 3 instanciaEntidad entidad marco
#> 4 atributo entidad marco
#> 5 entidad conjuntoEntidades marco
#> 6 entidad coleccion marco
#> 7 coleccion conjuntoColecciones marco
#> 8 coleccion organizacion marco
#> 9 organizacion conjuntoOrganizaciones marcoUna celda puede agregarse hacia su columna o hacia su fila. Esas direcciones son ortogonales, no peldaños de una escala lineal.
Tres niveles de métrica
Una métrica genérica declara semántica, granularidad, tipo de resultado y propiedades. Especializar fija propiedades reutilizables; instanciar liga esa especialización a objetos concretos.
nucleo <- metricas_nucleo()
no_nulo <- nucleo$NoNulo
no_nulo_personas <- especializar(
no_nulo, nombre_especifico = "NoNuloDocumento"
)
documento <- instanciar(no_nulo_personas, "personas", "documento")
documento$declaracion[c("nombre", "granularidad", "tipo_resultado")]
#> $nombre
#> [1] "NoNulo"
#>
#> $granularidad
#> [1] "instanciaAtributo"
#>
#> $tipo_resultado
#> [1] "booleano"La separación permite reutilizar la misma definición sobre entregas y columnas distintas.
Una métrica propia de punta a punta
El gancho metodo recibe una lista con nombre de tablas y la instancia que se está midiendo. Devuelve una fila por objeto medido con las columnas resultado, entidad, atributo, fila y objeto. Este ejemplo declara una métrica ajena a los catálogos incluidos y muestra las dos llamadas de la fábrica: la primera especializa y la segunda instancia.
metodo_origen <- function(tablas, instancia) {
x <- tablas[[instancia$entidad]][[instancia$atributos]]
data.frame(
resultado = !is.na(x) & nzchar(x),
entidad = instancia$entidad,
atributo = instancia$atributos,
fila = seq_along(x),
objeto = paste0(instancia$entidad, "$", instancia$atributos,
"[", seq_along(x), "]")
)
}
OrigenDeclarado <- metrica(
nombre = "OrigenDeclarado",
semantica = "Indica si cada registro declara su sistema de origen.",
granularidad = "instanciaAtributo",
tipo_resultado = "booleano",
dimension = "Trazabilidad",
factor = "Origen documentado",
metodo = metodo_origen
)
origen <- OrigenDeclarado()(entidad = "entrega", atributos = "origen")
datos_origen <- data.frame(origen = c("sistema_a", "", "sistema_b"))
medir(modelo(origen), datos_origen)[, c("objeto_medible", "resultado")]
#> objeto_medible resultado
#> 1 entrega$origen[1] 1
#> 2 entrega$origen[2] 0
#> 3 entrega$origen[3] 1Cuando una métrica declara propiedades, propiedades_metrica() permite consultarlas antes de llamar a especializar().
propiedades_metrica(nucleo$Formato)
#> propiedad configurada
#> 1 expresion_regular FALSE
#> 2 diccionario FALSE
#> 3 validador FALSEValidadores y packs territoriales
Formato acepta cualquier función vectorizada que devuelva un lógico por valor. El núcleo incluye validadores internacionales de códigos ISO, correo, Luhn y módulo 97. Uruguay es un pack territorial de referencia, no una rama especial del motor.
internacionales <- validadores_internacionales()
uruguay <- validadores_uruguay()
internacionales$iso4217(c("UYU", "CLP", "ZZZ"))
#> [1] TRUE TRUE FALSE
uruguay$cedula(c("1.234.567-2", "1.234.567-3"))
#> [1] TRUE FALSE
cedula_valida <- especializar(
nucleo$Formato, "CedulaValida", validador = uruguay$cedula
)
medir(
modelo(cedula_valida("personas", "documento")),
data.frame(documento = c("1.234.567-2", "1.234.567-3"))
)[, c("objeto_medible", "resultado")]
#> objeto_medible resultado
#> 1 personas$documento[1] 1
#> 2 personas$documento[2] 0Un proyecto de otro país construye un pack con pack_validadores() y mantiene su función en su propio paquete o script. No necesita registrar nombres ni modificar lupa; la ayuda de pack_validadores() incluye un ejemplo completo con un RUT chileno.
Medir y agregar
datos <- data.frame(documento = c("1", "2", NA, "4"))
medidas <- medir(
modelo(documento), datos,
id_medicion = "enero",
fecha = as.POSIXct("2026-01-31", tz = "UTC")
)
medidas[, c("objeto_medible", "resultado", "granularidad")]
#> objeto_medible resultado granularidad
#> 1 personas$documento[1] 1 instanciaAtributo
#> 2 personas$documento[2] 1 instanciaAtributo
#> 3 personas$documento[3] 0 instanciaAtributo
#> 4 personas$documento[4] 1 instanciaAtributo
agregar(medidas, "atributo", "ratio")[, c(
"objeto_medible", "resultado", "agregacion"
)]
#> objeto_medible resultado agregacion
#> 1 personas$documento 0.75 ratioLas cuatro agregaciones implementadas son:
-
ratio, para resultados booleanos; -
ratio_umbral, para resultados reales; -
promedio; -
promedio_ponderado, con pesos en[0, 1]que suman uno por destino.
La función valida el tipo de resultado y la transición. No agrega hacia factor, dimensión o modelo. Los resultados no acotados que el marco usa para ErrorEstandar y actualidad conservan su unidad y no entran en estas cuatro agregaciones.
Evaluar no es volver a medir
Una regla expresa una condición sobre resultados. La evaluación de una regla es la proporción que la cumple; la evaluación de un perfil es la media simple de sus reglas. Los perfiles incluidos de AGESIC usan condiciones estrictas > 0.5, > 0.7 y > 0.9; otra familia se construye con umbrales con nombres.
medida_atributo <- agregar(medidas, "atributo", "ratio")
madurez <- perfiles_madurez()
evaluar(medida_atributo, madurez$Intermedio)$perfiles
#> id_medicion fecha perfil n_reglas resultado
#> 1 enero 2026-01-31 Intermedio 1 1
names(perfiles_madurez(umbrales = c(Inicial = 0.4, Consolidado = 0.85)))
#> [1] "Inicial" "Consolidado"El id_medicion y la fecha permanecen en las medidas para comparar corridas y monitorear deriva.
Marcos incluidos
marco_iso25012() ofrece las quince características de ISO/IEC 25012:2008 como otra taxonomía disponible. La norma distingue características inherentes, dependientes del sistema y aplicables desde ambas perspectivas. lupa usa esos tres grupos como dimensiones operativas y las características como factores; es una adaptación para la interfaz dimensión–factor, no la afirmación de que la norma defina esa jerarquía. Sus descripciones están redactadas para el paquete y no reproducen el texto normativo.
iso <- marco_iso25012()
table(as.data.frame(iso)$dimension)
#>
#> Dependiente del sistema Inherente
#> 3 5
#> Inherente y dependiente del sistema
#> 7
head(as.data.frame(iso)[, c("dimension", "factor", "descripcion")])
#> dimension factor
#> 1 Inherente Exactitud
#> 2 Inherente Completitud
#> 3 Inherente Consistencia
#> 4 Inherente Credibilidad
#> 5 Inherente Actualidad
#> 6 Inherente y dependiente del sistema Accesibilidad
#> descripcion
#> 1 Considera si los datos representan correctamente los hechos o valores que pretenden describir.
#> 2 Considera si están presentes los valores y registros necesarios para el uso declarado.
#> 3 Revisa que los datos no se contradigan entre sí ni con reglas acordadas.
#> 4 Expresa la confianza respaldada por el origen y las evidencias disponibles.
#> 5 Considera si los datos conservan vigencia para el momento y uso declarados.
#> 6 Considera si las personas o procesos autorizados pueden obtener y usar los datos.El marco y el catálogo de AGESIC
marco_agesic() devuelve los 17 factores usados por omisión en la cobertura. catalogo_agesic() mantiene por separado las 49 entradas, incluidas las que se obtienen por agregación o requieren insumos externos.
catalogo <- catalogo_agesic()
marco_agesic()
#>
#> ── Marco de calidad de datos de AGESIC ──
#>
#> Dimensiones: 5
#> Factores: 17
#> Origen: AGESIC 2020, versión 1.6
as.data.frame(table(catalogo$estado, catalogo$motivo))
#> Var1 Var2 Freq
#> 1 implementada semantica_completa 6
#> 2 via_agregacion semantica_completa 0
#> 3 pendiente semantica_completa 0
#> 4 fuera_de_alcance semantica_completa 0
#> 5 implementada semantica_parcial 1
#> 6 via_agregacion semantica_parcial 0
#> 7 pendiente semantica_parcial 0
#> 8 fuera_de_alcance semantica_parcial 0
#> 9 implementada agregacion 0
#> 10 via_agregacion agregacion 8
#> 11 pendiente agregacion 0
#> 12 fuera_de_alcance agregacion 0
#> 13 implementada requiere_referencial 3
#> 14 via_agregacion requiere_referencial 0
#> 15 pendiente requiere_referencial 0
#> 16 fuera_de_alcance requiere_referencial 0
#> 17 implementada requiere_configuracion 18
#> 18 via_agregacion requiere_configuracion 0
#> 19 pendiente requiere_configuracion 0
#> 20 fuera_de_alcance requiere_configuracion 0
#> 21 implementada motor_pendiente 0
#> 22 via_agregacion motor_pendiente 0
#> 23 pendiente motor_pendiente 3
#> 24 fuera_de_alcance motor_pendiente 0
#> 25 implementada decision_alcance 0
#> 26 via_agregacion decision_alcance 0
#> 27 pendiente decision_alcance 0
#> 28 fuera_de_alcance decision_alcance 10
catalogo[catalogo$estado == "via_agregacion", c(
"metrica_agesic", "metrica_lupa", "implementacion"
)]
#> metrica_agesic metrica_lupa
#> 3 RatioCorrectitudSemFuerte CorrectitudSemFuerte
#> 4 RatioCorrectitudSemDébil CorrectitudSemDebil
#> 21 RatioIntegridadIntraEntidad ReglaIntegridadIntraEntidad
#> 30 RatioNoNulos NoNulo
#> 31 RatioDensidadPonderada DensidadPonderada
#> 37 RatioAtributoDuplicado AtributoDuplicado
#> 38 RatioConjuntoAtributosDuplicado ConjuntoAtributosDuplicado
#> 39 RatioEntidadesDuplicadas EntidadDuplicada
#> implementacion
#> 3 agregar(m, "atributo", "ratio")
#> 4 agregar(m, "atributo", "ratio")
#> 21 agregar(m, "entidad", "ratio")
#> 30 agregar(m, "atributo", "ratio")
#> 31 agregar(m, "entidad", "ratio_umbral", umbral = u)
#> 37 agregar(m, "atributo", "ratio")
#> 38 agregar(m, "entidad", "ratio")
#> 39 agregar(m, "entidad", "ratio")estado dice si la entrada está implementada, se obtiene por agregación, está pendiente o queda fuera del alcance tabular. motivo explica la causa: por ejemplo, distingue un motor pendiente de una implementación disponible que necesita un referencial o una configuración experta. La observación de cada fila explicita el contrato concreto y las implementaciones parciales.
Un diccionario enumera valores sintácticamente válidos. Un referencial vincula claves y valores externos, y sólo permite medir cobertura cuando declara de qué universo es completo.
padron <- referencial(
data.frame(codigo = c("01", "02"), nombre = c("Artigas", "Canelones")),
clave = "codigo", valor = "nombre", completo = TRUE,
alcance = "departamentos incluidos en el ejemplo"
)
names(metricas_referencial())
#> [1] "CorrectitudSemFuerte" "CorrectitudSemDebil" "RatioCobertura"
padron
#> Referencial: referencial
#> Filas: 2
#> Clave: codigo
#> Valores: nombre
#> Completo: sí
#> Alcance: departamentos incluidos en el ejemploLa tabla del catálogo es la respuesta verificable a “qué implementa el paquete”; las entradas fuera de alcance no se presentan como resueltas.
Lo que no se midió también es un resultado
Un perfil sin hallazgos no demuestra que todos los factores hayan sido evaluados. cobertura_analisis() separa lo medido de lo no declarado, lo que no aplica a los tipos presentes y lo que permanece fuera de alcance.
perfil <- perfilar(datos_administrativos, analizar_dependencias = FALSE)
cobertura_analisis(perfil)
#> marco dimension factor
#> 1 Marco de calidad de datos de AGESIC Exactitud Correctitud semántica
#> 2 Marco de calidad de datos de AGESIC Exactitud Correctitud sintáctica
#> 3 Marco de calidad de datos de AGESIC Exactitud Precisión
#> 4 Marco de calidad de datos de AGESIC Exactitud Exactitud posicional absoluta
#> 5 Marco de calidad de datos de AGESIC Exactitud Exactitud posicional relativa
#> 6 Marco de calidad de datos de AGESIC Exactitud Fidelidad
#> 7 Marco de calidad de datos de AGESIC Consistencia Integridad inter-entidad
#> 8 Marco de calidad de datos de AGESIC Consistencia Integridad intra-entidad
#> 9 Marco de calidad de datos de AGESIC Consistencia Integridad de dominio
#> 10 Marco de calidad de datos de AGESIC Consistencia Consistencia topológica
#> 11 Marco de calidad de datos de AGESIC Completitud Cobertura
#> 12 Marco de calidad de datos de AGESIC Completitud Densidad
#> 13 Marco de calidad de datos de AGESIC Completitud Comisión
#> 14 Marco de calidad de datos de AGESIC Unicidad No-duplicación
#> 15 Marco de calidad de datos de AGESIC Unicidad No-contradicción
#> 16 Marco de calidad de datos de AGESIC Frescura Actualidad
#> 17 Marco de calidad de datos de AGESIC Frescura Oportunidad
#> estado
#> 1 no_declarada
#> 2 no_declarada
#> 3 no_declarada
#> 4 no_aplica
#> 5 no_aplica
#> 6 fuera_de_alcance
#> 7 no_declarada
#> 8 no_declarada
#> 9 no_declarada
#> 10 no_aplica
#> 11 no_declarada
#> 12 medida
#> 13 no_aplica
#> 14 medida
#> 15 no_declarada
#> 16 no_declarada
#> 17 no_declarada
#> motivo
#> 1 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 2 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 3 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 4 No se identificaron columnas de geometría.
#> 5 No se identificaron columnas de geometría.
#> 6 Las métricas del factor requieren capacidades no implementadas en esta versión.
#> 7 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 8 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 9 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 10 No se identificaron columnas de geometría.
#> 11 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 12 El perfil contó ausentes reales y disfrazados en todas las columnas.
#> 13 No se identificaron columnas de geometría.
#> 14 El perfil examinó duplicación de valores, columnas y filas exactas.
#> 15 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 16 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 17 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> como_resolverlo
#> 1 Crear referencial() e instanciar metricas_referencial().
#> 2 Especializar Formato con expresión, diccionario o validador.
#> 3 Declarar escala() o medir ErrorEstandar sobre el atributo.
#> 4 Requiere un backend o referencial especializado que no integra esta versión.
#> 5 Requiere un backend o referencial especializado que no integra esta versión.
#> 6 Requiere un backend o referencial especializado que no integra esta versión.
#> 7 Instanciar ReglaIntegridadInterEntidad con claves confirmadas.
#> 8 Confirmar una regla y especializar ReglaIntegridadIntraEntidad.
#> 9 Proveer un dominio a ValoresPosiblesPorExtension o Comprension.
#> 10 Requiere un backend o referencial especializado que no integra esta versión.
#> 11 Crear un referencial(completo = TRUE) y medir RatioCobertura.
#> 12 Usar NoNulo o DensidadPonderada.
#> 13 Requiere un backend o referencial especializado que no integra esta versión.
#> 14 Usar las métricas de duplicación o el perfil automático.
#> 15 Requiere un backend o referencial especializado que no integra esta versión.
#> 16 Declarar vigencia() y medir DesactualizacionPorFecha o PorCambios.
#> 17 Declarar vigencia() y medir una métrica Oportunidad*.Los contratos temporales y de precisión se declaran con vigencia() y escala(): el paquete no intenta aprenderlos de una sola entrega.
Para otro marco, la misma función informa exclusivamente sus dimensiones y factores:
cobertura_analisis(perfil, modelo = marco_propio)
#> marco dimension factor estado
#> 1 Marco de procedencia Trazabilidad Origen documentado no_declarada
#> 2 Marco de procedencia Trazabilidad Linaje reproducible no_declarada
#> 3 Marco de procedencia Pertinencia Adecuación al uso no_declarada
#> motivo
#> 1 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 2 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> 3 El perfil describe evidencia, pero no recibió un requisito para este factor.
#> como_resolverlo
#> 1 Declarar e instanciar una métrica de este factor.
#> 2 Declarar e instanciar una métrica de este factor.
#> 3 Declarar e instanciar una métrica de este factor.La primera columna de cada salida identifica el marco activo, por lo que una tabla exportada conserva el contexto de la evaluación.
Referencias
Batini C, Scannapieco M (2016). Data and Information Quality: Dimensions, Principles and Techniques. Springer.
AGESIC (2020). Marco de trabajo para la Gestión de la Calidad de Datos en Gobierno Digital, versión 1.6. Presidencia de la República, Uruguay.
ISO/IEC (2008). ISO/IEC 25012:2008 Software engineering — Software product Quality Requirements and Evaluation (SQuaRE) — Data quality model.