Columnas condicionales y personalizadas en Power Query: casos de uso de valor
En el desarrollo de modelos de datos profesionales, la decisión de dónde ubicar la lógica de transformación marca la diferencia entre un informe ágil y una pesadilla de mantenimiento. Muchos analistas cometen el error de sobrecargar el motor DAX con columnas calculadas para realizar segmentaciones que pertenecen, por derecho propio, a la capa de preparación de datos. Power Query es la herramienta diseñada para esta tarea, permitiéndonos enriquecer el modelo antes de que los datos se compriman en el motor VertiPaq.
Añadir columnas en Power Query no es una decisión trivial. Cada columna nueva consume memoria y aumenta el tiempo de actualización, pero si se hace correctamente, mejora drásticamente la usabilidad del informe para el usuario final. En este artículo analizaremos cómo implementar segmentaciones complejas y clasificaciones de texto, comparando el uso de la interfaz gráfica frente a la escritura directa en lenguaje M.
La jerarquía de la transformación: por qué Power Query
Antes de entrar en el cómo, debemos entender el porqué. Como consultor, mi regla de oro es aplicar la transformación lo más cerca posible de la fuente de origen. Si puedes hacerlo en SQL, hazlo en SQL. Si no puedes tocar la base de datos, hazlo en Power Query. Solo si la lógica depende de la interacción del usuario en el informe (filtros dinámicos), recurre a DAX.
El uso de columnas condicionales en Power Query frente a las columnas calculadas en DAX ofrece dos ventajas críticas: mejor ratio de compresión y ahorro de recursos en tiempo de consulta. Al materializar la columna durante la carga, el motor de Power BI puede ordenar y segmentar los datos de forma más eficiente. Si te interesa profundizar en la eficiencia de los procesos de carga, te recomiendo revisar el artículo sobre Plegado de consultas en Power Query: guía para optimizar el rendimiento, ya que añadir columnas personalizadas puede, en ocasiones, romper este plegado.
Caso de uso 1: Segmentación de rangos de edad de deuda (Aging)
En proyectos de finanzas o sector público, el análisis de antigüedad de deuda es un estándar. No basta con saber cuánto se debe; el negocio necesita saber cuánto tiempo lleva esa factura pendiente. Intentar gestionar esto con múltiples filtros en el informe es ineficiente; lo ideal es una columna de dimensión que agrupe los días en cubos (buckets).
Implementación con la interfaz de Columna Condicional
La interfaz de «Columna condicional» es excelente para reglas simples y lineales. Para un escenario de deuda, la lógica sería:
- Si [DiasPendientes] <= 30 entonces «0-30 días»
- Si [DiasPendientes] <= 60 entonces «31-60 días»
- Si [DiasPendientes] <= 90 entonces «61-90 días»
- De lo contrario «+90 días»
Es vital mantener el orden de las cláusulas. Power Query evalúa de arriba abajo y se detiene en la primera coincidencia. Un error común es empezar por el rango más alto sin usar el operador correcto, lo que clasifica erróneamente todos los registros en la primera categoría que se cumpla.
El enfoque en lenguaje M para mayor control
Cuando los rangos dependen de múltiples variables (por ejemplo, si el tipo de cliente es ‘VIP’ el rango de tolerancia cambia), la interfaz se queda corta. Aquí es donde entra Table.AddColumn con una estructura if...then...else manual. El código resultante es mucho más legible y fácil de auditar.
// Ejemplo de segmentación avanzada en M
Table.AddColumn(Origen, "SegmentoDeuda", each
if [DiasPendientes] <= 15 then "Pronto Pago"
else if [TipoCliente] = "VIP" and [DiasPendientes] <= 45 then "Rango VIP"
else if [DiasPendientes] <= 60 then "Estándar"
else "Crítico")Caso de uso 2: Clasificación de tickets y motivos de visita
En el sector retail o en servicios de atención al cliente, los campos de texto libre son comunes. Agrupar miles de motivos de visita en 5 o 6 categorías maestras es fundamental para cualquier análisis de tendencias. Aquí no buscamos una coincidencia exacta, sino la presencia de palabras clave.
Para este escenario, la columna condicional de la interfaz es inútil porque solo permite comparaciones de igualdad, comienzo o final de cadena de forma muy rígida. Necesitamos recurrir a una columna personalizada y funciones de texto de M como Text.Contains.
Uso de Text.Contains y Case Sensitivity
Un error recurrente es olvidar que el lenguaje M distingue entre mayúsculas y minúsculas (case sensitive). Para clasificar tickets de soporte técnico, debemos normalizar el texto o usar el comparador de ignorar mayúsculas.
// Clasificación de tickets basada en palabras clave
Table.AddColumn(#"PasoAnterior", "CategoriaTicket", each
if Text.Contains([Descripcion], "password", Comparer.OrdinalIgnoreCase) or
Text.Contains([Descripcion], "contraseña", Comparer.OrdinalIgnoreCase)
then "Acceso"
else if Text.Contains([Descripcion], "lento", Comparer.OrdinalIgnoreCase)
then "Rendimiento"
else "Otros")Este patrón permite limpiar datos sucios de entrada y transformarlos en dimensiones útiles para el modelo en estrella. Al mover esta lógica a Power Query, evitamos que el motor DAX tenga que procesar funciones de texto pesadas en tiempo de ejecución del informe.
Comparativa técnica: ¿Qué método elegir?
La elección entre la interfaz y el código depende de la complejidad y la mantenibilidad. No siempre lo más complejo es lo mejor. En la siguiente tabla comparamos las opciones disponibles para crear estas columnas.
| Característica | Columna Condicional (UI) | Columna Personalizada (M) | Columna Calculada (DAX) |
|---|---|---|---|
| Dificultad | Baja | Media | Media/Alta |
| Flexibilidad | Limitada (lineal) | Máxima (lógica anidada) | Alta (contexto de fila) |
| Rendimiento de carga | Óptimo | Óptimo (si hay folding) | Lento (post-carga) |
| Impacto en el modelo | Bajo (buena compresión) | Bajo (buena compresión) | Alto (usa RAM de consulta) |
| Uso recomendado | Rangos numéricos simples | Lógica de negocio compleja | Lógica dependiente de filtros |
Es importante monitorizar cuánto tiempo añade cada columna al proceso de refresco. Para ello, puedes utilizar las herramientas que describo en Cuánto tarda cada paso en Power Query: Guía de Diagnóstico.
Errores frecuentes al añadir columnas en proyectos reales
A lo largo de mis años de consultoría, he visto patrones de error que degradan la calidad del dato y el rendimiento del sistema:
- No definir el tipo de datos: Por defecto, Power Query asigna el tipo
anya las nuevas columnas. Esto es un error grave. Siempre, tras añadir una columna, añade un paso deTable.TransformColumnTypeso especifica el tipo en la propia funciónTable.AddColumn. - Ignorar los valores nulos: Una comparación
if [Campo] > 10devolverá un error si el campo esnull. Debes gestionar proactivamente estos casos. Para una estrategia robusta, consulta Gestión proactiva de errores en Power Query: el patrón de la tabla de control. - Abusar de las columnas personalizadas en tablas de hechos masivas: Si tu tabla tiene 100 millones de filas y la fuente es un SQL Server, intenta que esta lógica se resuelva en la vista de SQL para asegurar el folding. Si la lógica es demasiado compleja, Power Query descargará los datos a memoria para procesarlos, ralentizando todo el pipeline.
- Anidamiento excesivo: Escribir 20
else ifseguidos hace que el código sea difícil de mantener. En esos casos, es mejor usar una tabla de referencia y un proceso de combinación (Join). Tienes más detalles sobre este enfoque en Unir y anexar consultas en Power Query: la diferencia que casi nadie usa bien.
Consideraciones de diseño y mantenimiento
Cuando trabajas en equipos medianos o grandes, la legibilidad del código M es tan importante como su funcionamiento. Al usar columnas personalizadas, renombra los pasos de Power Query para que reflejen la intención de negocio (ej. «Agregado Rango Deuda») en lugar de dejar el genérico «Personalizada agregada».
Además, recuerda que las columnas añadidas en Power Query son estáticas respecto a los datos cargados. Si tu lógica de negocio cambia frecuentemente (por ejemplo, los umbrales de los rangos de deuda), considera usar una tabla de parámetros externa. Esto permite que el usuario de negocio actualice los rangos sin necesidad de entrar al Editor de Power Query y tocar el código.
Checklist de implementación
- ¿He intentado realizar esta transformación en la base de datos de origen (SQL) antes que en Power Query?
- ¿La columna tiene asignado un tipo de datos explícito (Texto, Número entero, etc.)?
- ¿He gestionado los valores
nullpara evitar errores en la carga? - ¿El nombre de la columna es intuitivo para el usuario que va a crear el informe?
- Si he usado código M manual, ¿he incluido comentarios básicos para explicar la lógica?
Preguntas frecuentes
¿Es mejor usar una columna condicional o una tabla de búsqueda (Lookup)?
Si tienes más de 5 o 6 condiciones, o si estas condiciones cambian con el tiempo, es mucho mejor crear una tabla de configuración y usar un proceso de «Combinar consultas». Esto mantiene tu código limpio y permite cambios rápidos.
¿Afectan las columnas personalizadas al Query Folding?
Depende de la función utilizada. Funciones simples como sumas o concatenaciones suelen mantener el folding. Funciones más complejas o llamadas a bibliotecas externas suelen romperlo, lo que obliga a Power Query a procesar los datos localmente.
¿Por qué mi columna condicional da error en algunas filas?
Casi siempre se debe a una discrepancia en los tipos de datos o a la presencia de valores nulos. Asegúrate de que la columna sobre la que aplicas la condición no contenga errores previos y que todos los valores sean del tipo esperado (numérico para comparaciones de mayor/menor).
¿Puedo usar funciones de otras columnas dentro de mi columna personalizada?
Sí, puedes invocar cualquier valor de la fila actual usando la palabra clave each o definir funciones personalizadas más complejas si necesitas reutilizar la lógica en varias consultas del mismo archivo.
»


