Cómo crear una columna de categoría dinámica en DAX: paso a paso
Este tutorial muestra cómo crear una columna calculada en DAX que clasifica productos o transacciones en categorías dinámicas (por ejemplo: "Top", "Medio", "Bajo") en base a reglas de negocio como ventas y margen. Una columna de categoría ayuda a segmentar análisis en Power BI y a crear filtros y visuales más útiles. Vamos a explicar por qué elegir una columna calculada frente a una medida y dar un ejemplo práctico, con valores concretos y atención al rendimiento.
Requisitos previos
- Power BI Desktop o Tabular model con una tabla de hechos (por ejemplo, Sales) y una tabla de productos (Products).
- Conocimientos básicos de DAX: medidas, columnas calculadas y funciones como RELATED, CALCULATE, IF y VAR.
- Una columna de ventas (Sales[Amount]) y, opcionalmente, margen (Sales[Margin] o cálculo equivalente).
- Una tabla de fechas bien poblada (Date) si se va a usar Time Intelligence; relaciones entre Sales[ProductID] y Products[ProductID] correctamente definidas.
Paso 1: Definir la regla de categorización
Antes de escribir DAX, decida las reglas. Reglas bien definidas evitan lógica ambigua y permiten pruebas. Ejemplo práctico: categorizar productos por Ventas Totales en los últimos 12 meses (L12M) y Margen medio ponderado. Criterios propuestos:
- "Top": Ventas L12M > €100.000 y Margen medio >= 20%.
- "Medio": Ventas L12M entre €20.000 y €100.000 (inclusive, margen medio indiferente).
- "Bajo": Ventas L12M <= €20.000 o ausencia de ventas.
Estos umbrales son ejemplos; en un contexto real debe basarse en percentiles (p. ej. top 10% de los productos) o en la estrategia de la empresa. Decidir si la categorización debe ser estática (columna calculada) o dinámica en función del filtro temporal (medida) es crucial — aquí mostramos la columna calculada usando medidas agregadas para capturar L12M.
Paso 2: Crear una medida para Ventas Totales (si aún no existe)
Una medida es necesaria para un cálculo consistente con el contexto. Las medidas son eficientes cuando se usan en visuales y soportan filtros automáticamente.
Sales Total = SUM(Sales[Amount])
Paso 3: Crear una medida para Ventas últimos 12 meses
Usar Time Intelligence permite comparar periodos y evita duplicar lógica. Suponiendo que tiene una tabla Date con columnas continuas, use DATESINPERIOD para calcular L12M. Esto garantiza que, si el usuario aplica un slicer de fechas, la medida responda correctamente.
Sales L12M =
CALCULATE(
[Sales Total],
DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -12, MONTH)
)
Paso 4: Crear una medida para Margen medio por producto (opcional)
Un margen medio ponderado por ventas es más representativo que una media simple. Use DIVIDE para evitar error de división por cero. Si la empresa guarda margen como valor monetario (MarginAmount), calcule el porcentaje agregado así:
Margin Avg =
DIVIDE(
SUM(Sales[MarginAmount]),
SUM(Sales[Amount]),
0
)
El tercer argumento de DIVIDE devuelve 0 cuando el denominador es cero. En escenarios reales, podemos querer BLANK() para señalar falta de datos.
Paso 5: Crear una columna calculada de categoría en la tabla Products
Ahora creamos la columna calculada en Products que evalúa cada productID usando las medidas agregadas. Como las medidas dependen del contexto de fila, usamos CALCULATE con FILTER para forzar el contexto por producto. Este patrón es común cuando necesita materializar la categoría por producto.
Product Category =
VAR vSales =
CALCULATE([Sales L12M], FILTER(ALL(Sales), Sales[ProductID] = Products[ProductID]))
VAR vMargin =
CALCULATE([Margin Avg], FILTER(ALL(Sales), Sales[ProductID] = Products[ProductID]))
RETURN
IF(
vSales > 100000 && vMargin >= 0.20, "Top",
IF(vSales > 20000, "Medio", "Bajo")
)
Ejemplo concreto: si un producto tuvo €150.000 en ventas en los últimos 12 meses y margen del 22%, recibe "Top". Si tuvo €30.000 de ventas con margen 10%, recibe "Medio".
Paso 6: Evitar errores comunes (división por cero, relaciones, rendimiento)
Puntos a vigilar:
- Relaciones: si Products y Sales no están relacionados por ProductID, vSales será BLANK(). Verifique la dirección y cardinalidad.
- División por cero: use DIVIDE con tercer argumento (p. ej.: 0 o BLANK()).
- Rendimiento: columnas calculadas en modelos grandes (por ejemplo, 100k+ productos) pueden tardar. Considere calcular offline o usar una tabla agregada. Las medidas son generalmente más eficientes para cálculos dinámicamente filtrados.
- Contexto temporal: una columna calculada estática se evalúa en el momento de la creación; si desea que la categoría cambie con el slicer de fechas, utilice una medida o una tabla calculada con actualizaciones programadas.
// Ejemplo seguro de margen
Margin Avg =
DIVIDE(
SUM(Sales[MarginAmount]),
SUM(Sales[Amount]),
0
)
Verificar el resultado
Coloque Products[Product Category] en una tabla visual junto con Ventas L12M y Margin Avg. Valide con muestras: filtre el año anterior y confirme que un conjunto de 10 productos con mayores ventas realmente aparece como "Top". Si observa muchos "Bajo", revise los umbrales o utilice percentiles (p. ej. TOP 10% > median). Si algunas filas aparecen en blanco, verifique relaciones y valores nulos en Sales.
Conclusión
Crear una columna de categoría dinámica en DAX permite segmentar informes y facilitar análisis en Power BI. Use umbrales claros, pruebe con conjuntos de datos representativos (p. ej. 1.000 productos, 100k transacciones) y elija entre columna calculada y medida según la necesidad de interactividad temporal. Próximos pasos: transformar umbrales en parámetros "what-if" para hacerlos interactivos, o generar una tabla agregada si el rendimiento es crítico.