partidos = FileAttachment("datos/partidos.csv").csv()
// Normalizar vacíos
esVacio = (v) => {
if (v === null || v === undefined) return true
const t = String(v).trim().toLowerCase()
return t === "" || t === "nan" || t === "null" || t === "none" || t === "s/n"
}
// Campos evaluados para completitud de perfil
campos = [
"logo",
"sigla",
"presidente",
"militantes",
"ideologia",
"descripcion",
"colores",
"label",
"item",
"sede",
"fundador",
"fundacion"
]
totalCampos = campos.length
// Cálculo por partido
partidosCompletitud = partidos.map((p) => {
const llenos = campos.filter((k) => !esVacio(p[k])).length
const faltantes = totalCampos - llenos
const completitud = llenos / totalCampos
const camposFaltantes = campos.filter((k) => esVacio(p[k]))
const ideologiaNombre = p.ideologia || "(Sin dato)"
const tipoNombre = p.tipo || "(Sin dato)"
const siglaNombre = p.sigla || "(Sin dato)"
const puntajeImportancia = faltantes
return {
...p,
llenos,
faltantes,
camposFaltantes,
ideologiaNombre,
tipoNombre,
siglaNombre,
puntajeImportancia,
completitud,
completitudPct: Math.round(completitud * 100)
}
})
totalPartidos = partidosCompletitud.length
promedioCompletitud = totalPartidos
? partidosCompletitud.reduce((acc, d) => acc + d.completitud, 0) / totalPartidos
: 0
perfilesCompletos = partidosCompletitud.filter((d) => d.completitud === 1).length
sinLogo = partidosCompletitud.filter((d) => esVacio(d.logo)).length
// Completitud por campo
completitudCampos = campos.map((campo) => {
const llenos = partidosCompletitud.filter((d) => !esVacio(d[campo])).length
return {
campo,
llenos,
total: totalPartidos,
pct: totalPartidos ? (llenos / totalPartidos) * 100 : 0
}
})
// Promedio por ideología
completitudIdeologia = Array.from(
partidosCompletitud.reduce((m, d) => {
const k = d.tipoNombre
if (!m.has(k)) m.set(k, [])
m.get(k).push(d.completitud)
return m
}, new Map()),
([ideologia, valores]) => ({
ideologia,
pct: (valores.reduce((a, b) => a + b, 0) / valores.length) * 100
})
).sort((a, b) => b.pct - a.pct)
// Ranking con menor completitud
peorCompletitud = [...partidosCompletitud]
.sort((a, b) => b.puntajeImportancia - a.puntajeImportancia)
.slice(0, 12)
siglasDisponibles = ["(Todos)", ...new Set(partidosCompletitud.map((d) => d.siglaNombre))]
ideologiasDisponibles = ["(Todos)", ...new Set(partidosCompletitud.map((d) => d.tipoNombre))]