metrica() declara una métrica genérica y devuelve una fábrica de closures.
especializar() fija sus propiedades de configuración; la closure específica
resultante puede instanciarse sobre distintas columnas o tablas.
instanciar() liga la métrica a objetos concretos y materializa el método de
medición. modelo() reúne métricas instanciadas sin calcular un índice global.
Uso
metrica(
nombre,
semantica,
granularidad,
tipo_resultado,
propiedades = character(),
dimension = NA_character_,
factor = NA_character_,
metodo = NULL,
validar_propiedades = NULL
)
especializar(metrica, nombre_especifico = NULL, ...)
instanciar(
metrica_especifica,
entidad,
atributos = character(),
nombre_instancia = NULL,
metodo = NULL,
referencial = NULL
)
propiedades_metrica(x)
modelo(..., marco = NULL)
metricas_nucleo()Argumentos
- nombre
Nombre estable y legible.
- semantica
Descripción de lo que mide la métrica.
- granularidad
Uno de los niveles devueltos por
granularidades().- tipo_resultado
"booleano","real"en[0, 1],"numero_real","entero"no negativo o"duracion"no negativa. Los tres últimos conservan resultados no acotados del catálogo y no admiten las cuatro agregaciones normalizadas.- propiedades
Nombres de las propiedades que fija
especializar().- dimension, factor
Metadatos taxonómicos; no se usan para calcular puntuaciones.
- metodo
Método predeterminado opcional. Es una función de
tablaseinstanciaque cumple el contrato descrito en Contrato demetodo.- validar_propiedades
Función opcional que recibe la lista con nombre enviada a
especializar()y debe devolver otra lista con nombre formada sólo por propiedades declaradas. Puede validar alternativas, completar valores predeterminados y normalizar la configuración. Si esNULL, todas las propiedades declaradas son obligatorias y no se admiten otras.- metrica
Objeto de clase
metrica_generica.- nombre_especifico
Nombre de la especialización. Si se omite, conserva el nombre genérico.
- ...
En
especializar(), propiedades con nombre de las declaradas enmetrica(propiedades = ); consúltelas conpropiedades_metrica(). Enmodelo(), métricas instanciadas o una única lista que las contenga.- metrica_especifica
Objeto de clase
metrica_especifica.- entidad
Nombres de las tablas ligadas, en el orden que espera el método.
- atributos
Nombres de las columnas ligadas, en el mismo orden.
- nombre_instancia
Nombre de la instancia. Si se omite, se deriva de la especialización y los objetos ligados.
- referencial
Objeto opcional creado por
referencial(). Se conserva en la instancia sin modificarlo:instanciar()no supone que toda métrica lo use. Elmetododebe leerlo y validar el contrato que necesite; las métricas demetricas_referencial()hacen esa validación al medir.- x
Métrica genérica, específica o instanciada.
- marco
Objeto opcional creado por
marco_calidad(). Cuando se provee, todas las métricas instanciadas deben pertenecer a uno de sus pares dimensión-factor.
Valor
metrica() y especializar() devuelven closures S3;
instanciar() devuelve una metrica_instanciada; modelo() devuelve un
modelo_calidad; metricas_nucleo() devuelve una lista de métricas
genéricas. propiedades_metrica() devuelve un data frame con las
propiedades declaradas y si ya fueron configuradas.
Detalles
metricas_nucleo() devuelve veintiuna métricas automatizables una vez
declaradas sus propiedades; escala() y vigencia() hacen explícitos los
insumos expertos que algunas necesitan. metricas_referencial() aporta por
separado las tres métricas que consumen un padrón tabular. Consulte
catalogo_agesic() para la correspondencia completa.
En ReglaIntegridadInterEntidad, entidad y atributos se ligan como
c(referencia, dependiente) y c(clave_primaria, clave_foranea).
Esta implementación calcula cobertura PK/FK como resultado real y sólo cubre
una parte de la genérica del marco, que declara granularidad
conjuntoEntidades, resultado booleano y admite además una expresión
condicional. catalogo_agesic() deja visible esa cobertura parcial.
Pese a su nombre, ErrorEstandar sigue literalmente la semántica de la
tabla 16.5 del marco y devuelve la desviación estándar muestral sin
normalizar; exige al menos dos valores numéricos válidos. Por eso declara
tipo_resultado = "numero_real" y no admite agregar().
Formato acepta exactamente una de las propiedades expresion_regular,
diccionario o validador. Esta última permite conectar validadores
externos sin incorporarlos como dependencias.
Tanto Formato como ValoresPosiblesPorExtension omiten los valores NA:
un ausente no genera una medida en esas métricas y, por lo tanto, tampoco
integra el denominador de sus agregaciones. La completitud se mide por
separado con NoNulo; así un mismo ausente no se penaliza en dos factores.
NoNulo acepta el vector opcional valores_nulos para aplicar de forma
deliberada el diccionario de nulos que contempla el marco; sin configurarlo,
sólo considera los NA reales.
ValoresPosiblesPorComprension sigue la misma convención y acepta un
predicado o un rango definido por minimo, maximo e inclusivo.
Las métricas de duplicación marcan todas las apariciones que participan
en un grupo repetido, no sólo la segunda y siguientes. AtributoDuplicado
omite ausentes. ConjuntoAtributosDuplicado compara las columnas ligadas y
EntidadDuplicada compara la fila completa cuando se instancia sin
atributos. Si se ligan atributos de clave, sigue la semántica del marco:
marca filas con la misma clave cuyos demás valores son iguales o ausentes en
alguna de las dos. En las comparaciones exactas, los NA forman parte de la
combinación comparada.
DesactualizacionPorFormato devuelve TRUE cuando el valor no cumple el
formato vigente. Conforme a las tablas 16.29 y 16.30 del marco,
OportunidadAtributoPorFecha indica si la fecha es anterior o igual a
fecha_limite, y OportunidadAtributoPorIntervalo si pertenece al intervalo
cerrado [inicio_vigencia, fin_vigencia]; ambas son booleanas.
GradoOportunidadAtributoPorFecha y
GradoOportunidadAtributoPorIntervalo son extensiones propias basadas en el
curso CPAP, no entradas adicionales del catálogo AGESIC. Conservan la fórmula
continua max(0, min(1, 1 - (t1 - t2) / (t3 - t2))) para expresar cuánto
margen de utilidad queda. Exigen que t3 sea posterior a t2; un intervalo
de duración cero se rechaza porque no define el cociente. Todas estas
métricas omiten los valores NA: su ausencia corresponde a completitud y no
genera una segunda medida de incumplimiento.
Desviación documentada del marco: en DensidadPonderada, un atributo
más crítico recibe un coeficiente mayor y, si falta, produce una penalización
mayor. El texto del marco indica acercar a cero el coeficiente de mayor
gravedad, lo que penalizaría menos el ausente crítico y contradice el sentido
de la ponderación. Los coeficientes deben estar en [0, 1] y sumar 1.
tipo_resultado es el contrato canónico que consultan las agregaciones. Las
unidades no forman parte de este núcleo porque el marco presenta ambas
nociones de forma inconsistente y sólo el tipo permite validar las fórmulas.
El argumento referencial se conserva sin transformación dentro de la
instancia; metricas_referencial() declara y valida el contrato específico
de correctitud semántica y cobertura.
Contrato de metodo
El método tiene la firma function(tablas, instancia). tablas es una lista
con nombre de data frames, incluso cuando medir() recibió una sola tabla.
instancia expone entidad, atributos, configuracion, referencial y
declaracion; el método decide cómo interpretar esos vínculos.
Debe devolver un data frame con exactamente una observación por objeto medido y, como mínimo, estas columnas:
resultado: valor medido. Debe respetartipo_resultado: lógicos sinNApara"booleano"; números finitos en[0, 1]para"real"; números finitos para"numero_real"; enteros o duraciones no negativos para los tipos homónimos;entidad: nombre de la tabla a la que corresponde la medida;atributo: nombre de la columna oNA_character_cuando no corresponde;fila: posición de la fila oNA_integer_para resultados agregados;objeto: etiqueta legible y estable del objeto medido.
Las columnas adicionales se descartan. Un metodo pasado a instanciar()
reemplaza el predeterminado sólo para esa instancia. El ejemplo ejecutable
muestra la cadena genérica → específica → instanciada completa.
Contrato de propiedades
propiedades declara los nombres que puede recibir especializar(). Sin
validar_propiedades, todas son obligatorias. Con un validador propio, éste
recibe la lista configuracion, debe rechazar combinaciones inválidas y puede
devolver sólo el subconjunto activo o añadir valores predeterminados, pero no
propiedades ajenas a la declaración. propiedades_metrica() permite consultar
los nombres aceptados sin inspeccionar atributos internos de las closures.
Referencias
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.
Curso CPAP, material Evaluación de Calidad: fórmula continua de
oportunidad implementada bajo los nombres GradoOportunidadAtributo*.
Ejemplos
nucleo <- metricas_nucleo()
no_nulo <- especializar(
nucleo$NoNulo, nombre_especifico = "NoNuloEdad"
)
instancia <- instanciar(no_nulo, entidad = "personas", atributos = "edad")
modelo_calidad <- modelo(instancia)
medir(modelo_calidad, data.frame(edad = c(20, NA, 35)))
#> id_medida
#> 1 medicion-20260808T211924.570809-303753-000001
#> 2 medicion-20260808T211924.570809-303753-000002
#> 3 medicion-20260808T211924.570809-303753-000003
#> id_medicion fecha metrica
#> 1 medicion-20260808T211924.570809-303753 2026-08-08 21:19:24 NoNulo
#> 2 medicion-20260808T211924.570809-303753 2026-08-08 21:19:24 NoNulo
#> 3 medicion-20260808T211924.570809-303753 2026-08-08 21:19:24 NoNulo
#> metrica_especifica metrica_instanciada dimension factor
#> 1 NoNuloEdad NoNuloEdad@personas.edad Completitud Densidad
#> 2 NoNuloEdad NoNuloEdad@personas.edad Completitud Densidad
#> 3 NoNuloEdad NoNuloEdad@personas.edad Completitud Densidad
#> granularidad tipo_resultado entidad atributo fila objeto_medible
#> 1 instanciaAtributo booleano personas edad 1 personas$edad[1]
#> 2 instanciaAtributo booleano personas edad 2 personas$edad[2]
#> 3 instanciaAtributo booleano personas edad 3 personas$edad[3]
#> resultado agregacion
#> 1 1 <NA>
#> 2 0 <NA>
#> 3 1 <NA>
# Las fábricas también se pueden encadenar: genérica() -> específica().
instancia_directa <- nucleo$NoNulo()(
entidad = "personas", atributos = "edad"
)
propiedades_metrica(nucleo$Formato)
#> propiedad configurada
#> 1 expresion_regular FALSE
#> 2 diccionario FALSE
#> 3 validador FALSE
# Métrica propia: las dos llamadas encadenadas son especializar e instanciar.
metodo_origen <- function(tablas, instancia) {
x <- tablas[[instancia$entidad]][[instancia$atributos]]
filas <- seq_along(x)
data.frame(
resultado = !is.na(x) & nzchar(x),
entidad = instancia$entidad,
atributo = instancia$atributos,
fila = filas,
objeto = paste0(instancia$entidad, "$", instancia$atributos,
"[", filas, "]")
)
}
OrigenDeclarado <- metrica(
"OrigenDeclarado", "Indica si se declaró el origen del registro.",
"instanciaAtributo", "booleano",
dimension = "Trazabilidad", factor = "Origen documentado",
metodo = metodo_origen
)
origen <- OrigenDeclarado()(
entidad = "entrega", atributos = "origen"
)
medir(
modelo(origen),
data.frame(origen = c("sistema_a", "", NA), stringsAsFactors = FALSE)
)
#> id_medida
#> 1 medicion-20260808T211924.574556-303753-000001
#> 2 medicion-20260808T211924.574556-303753-000002
#> 3 medicion-20260808T211924.574556-303753-000003
#> id_medicion fecha metrica
#> 1 medicion-20260808T211924.574556-303753 2026-08-08 21:19:24 OrigenDeclarado
#> 2 medicion-20260808T211924.574556-303753 2026-08-08 21:19:24 OrigenDeclarado
#> 3 medicion-20260808T211924.574556-303753 2026-08-08 21:19:24 OrigenDeclarado
#> metrica_especifica metrica_instanciada dimension
#> 1 OrigenDeclarado OrigenDeclarado@entrega.origen Trazabilidad
#> 2 OrigenDeclarado OrigenDeclarado@entrega.origen Trazabilidad
#> 3 OrigenDeclarado OrigenDeclarado@entrega.origen Trazabilidad
#> factor granularidad tipo_resultado entidad atributo fila
#> 1 Origen documentado instanciaAtributo booleano entrega origen 1
#> 2 Origen documentado instanciaAtributo booleano entrega origen 2
#> 3 Origen documentado instanciaAtributo booleano entrega origen 3
#> objeto_medible resultado agregacion
#> 1 entrega$origen[1] 1 <NA>
#> 2 entrega$origen[2] 0 <NA>
#> 3 entrega$origen[3] 0 <NA>
# Especialización oficial de teléfono fijo según el formato vigente del PNN.
telefono_pnn <- especializar(
nucleo$DesactualizacionPorFormato,
nombre_especifico = "TelefonoFijoPNN",
expresion_regular = "^[0-9]{8}$"
)
# La métrica oficial es booleana y recibe la fecha límite Tf.
a_tiempo <- especializar(
nucleo$OportunidadAtributoPorFecha,
nombre_especifico = "EntregaATiempo",
fecha_limite = as.Date("2026-06-30")
)
medir(
modelo(instanciar(a_tiempo, "entregas", "fecha")),
data.frame(fecha = as.Date(c("2026-06-29", "2026-07-01")))
)
#> id_medida
#> 1 medicion-20260808T211924.577380-303753-000001
#> 2 medicion-20260808T211924.577380-303753-000002
#> id_medicion fecha
#> 1 medicion-20260808T211924.577380-303753 2026-08-08 21:19:24
#> 2 medicion-20260808T211924.577380-303753 2026-08-08 21:19:24
#> metrica metrica_especifica metrica_instanciada
#> 1 OportunidadAtributoPorFecha EntregaATiempo EntregaATiempo@entregas.fecha
#> 2 OportunidadAtributoPorFecha EntregaATiempo EntregaATiempo@entregas.fecha
#> dimension factor granularidad tipo_resultado entidad atributo fila
#> 1 Frescura Oportunidad instanciaAtributo booleano entregas fecha 1
#> 2 Frescura Oportunidad instanciaAtributo booleano entregas fecha 2
#> objeto_medible resultado agregacion
#> 1 entregas$fecha[1] 1 <NA>
#> 2 entregas$fecha[2] 0 <NA>
# La extensión continua conserva cuánto margen de utilidad queda.
grado <- especializar(
nucleo$GradoOportunidadAtributoPorFecha,
fecha_solicitud = as.Date("2026-06-01"),
fecha_fin_utilidad = as.Date("2026-07-01")
)
# Formato(NumeroDocumento, DNIC) se obtiene conectando el validador incluido:
cedula_dnic <- especializar(
nucleo$Formato, nombre_especifico = "NumeroDocumentoDNIC",
validador = validar_ci_uy
)