Inicio / Power BI / Power BI: Dashboards e Informes Profesionales / DAX Avanzado: CALCULATE, FILTER y Contexto

DAX Avanzado: CALCULATE, FILTER y Contexto

CALCULATE en profundidad, ALL, ALLEXCEPT, KEEPFILTERS, FILTER, transición de contexto, ranking y análisis ABC.

Intermedio
🔒 Solo lectura
📖

Estás en modo lectura

Puedes leer toda la lección, pero para marcar progreso, hacer ejercicios y ganar XP necesitas una cuenta Pro.

Desbloquear por $9/mes

DAX Avanzado: CALCULATE, FILTER y Contexto

CALCULATE es la función más poderosa de DAX. Dominarla es la diferencia entre un usuario básico y un experto en Power BI.

CALCULATE en profundidad

CALCULATE hace dos cosas:

  1. Evalúa una expresión.
  2. Modifica el contexto de filtro antes de evaluarla.
CALCULATE(<expresión>, <filtro1>, <filtro2>, ...)

Ejemplo fundamental

// Sin CALCULATE: respeta todos los filtros del reporte
Total Ventas = SUM(Ventas[Monto])

// Con CALCULATE: modifica el contexto de filtro
Ventas México = 
CALCULATE(
    SUM(Ventas[Monto]),
    Clientes[País] = "México"
)
// Siempre muestra ventas de México, sin importar qué filtre el usuario

Modificadores de filtro

ALL — Remueve filtros

// Remueve TODOS los filtros de una tabla
Total General = 
CALCULATE([Ingresos], ALL(Ventas))

// Remueve filtro de una columna específica
Total Sin Categoría = 
CALCULATE([Ingresos], ALL(Productos[Categoría]))

// Participación porcentual
% del Total = 
DIVIDE(
    [Ingresos],
    CALCULATE([Ingresos], ALL(Productos[Categoría])),
    0
)

ALLEXCEPT — Remueve todos los filtros excepto los especificados

// Mantiene solo el filtro de País, remueve todo lo demás
% en País = 
DIVIDE(
    [Ingresos],
    CALCULATE([Ingresos], ALLEXCEPT(Ventas, Clientes[País])),
    0
)

REMOVEFILTERS — Alias moderno de ALL en contexto de filtro

Total Sin Filtros = 
CALCULATE([Ingresos], REMOVEFILTERS())

KEEPFILTERS — Intersecta en vez de reemplazar

// Sin KEEPFILTERS: reemplaza el filtro de categoría
Ventas Electrónica = 
CALCULATE([Ingresos], Productos[Categoría] = "Electrónica")
// Si el usuario filtra "Ropa", IGNORA ese filtro y muestra Electrónica

// Con KEEPFILTERS: intersecta con el filtro del usuario
Ventas Electrónica Safe = 
CALCULATE([Ingresos], KEEPFILTERS(Productos[Categoría] = "Electrónica"))
// Si el usuario filtra "Ropa", intersecta Ropa ∩ Electrónica = vacío = 0

FILTER — Tabla de filtro explicita

// FILTER retorna una tabla filtrada
Ventas VIP = 
CALCULATE(
    [Ingresos],
    FILTER(Clientes, Clientes[Total Compras] > 100000)
)

// FILTER puede usar medidas (los filtros simples no pueden)
Ventas de Top Clientes = 
CALCULATE(
    [Ingresos],
    FILTER(
        ALL(Clientes[Nombre]),
        [Ingresos] > 50000
    )
)

Cuándo usar FILTER vs filtro directo

Escenario Usar
Filtrar por valor literal Filtro directo: Tabla[Col] = "valor"
Filtrar por medida FILTER()
Filtrar con operadores complejos FILTER()
Performance importa Filtro directo (más rápido)

Transición de contexto (Context Transition)

Cuando CALCULATE se usa dentro de un contexto de fila (columna calculada o iterador), convierte automáticamente el contexto de fila en contexto de filtro.

// En una columna calculada de la tabla Clientes:
Total Compras Cliente = CALCULATE(SUM(Ventas[Monto]))
// CALCULATE detecta el contexto de fila (cada cliente)
// y lo convierte en filtro: filtra Ventas por ese cliente

SELECTEDVALUE y HASONEVALUE

// Obtener el valor seleccionado actualmente
País Seleccionado = SELECTEDVALUE(Clientes[País], "Todos")

// Lógica condicional basada en selección
KPI Dinámico = 
SWITCH(
    SELECTEDVALUE(SlicerMétrica[Métrica]),
    "Ingresos", [Ingresos],
    "Margen", [Margen %],
    "Clientes", [Num Clientes],
    [Ingresos]
)

VALUES y DISTINCT

// Contar valores únicos con detalle
Num Países = COUNTROWS(VALUES(Clientes[País]))

// Iterar sobre valores únicos
Promedio por País = 
AVERAGEX(
    VALUES(Clientes[País]),
    [Ingresos]
)

Ranking dinámico

Ranking = 
RANKX(
    ALL(Productos[Nombre]),
    [Ingresos],
    ,
    DESC,
    Dense
)

Top N dinámico con slicer

// Medida que muestra el valor solo si está en el Top N
Ingresos Top N = 
VAR TopN = SELECTEDVALUE(SlicerTopN[N], 10)
VAR MiRanking = [Ranking]
RETURN
    IF(MiRanking <= TopN, [Ingresos], BLANK())

Patrones avanzados

ABC Analysis

Clasificación ABC = 
VAR TotalGeneral = CALCULATE([Ingresos], ALL(Productos))
VAR IngresoProducto = [Ingresos]
VAR Acumulado = 
    CALCULATE(
        [Ingresos],
        FILTER(
            ALL(Productos[Nombre]),
            [Ingresos] >= IngresoProducto
        )
    )
VAR PctAcumulado = DIVIDE(Acumulado, TotalGeneral)
RETURN
    SWITCH(TRUE(),
        PctAcumulado <= 0.80, "A",
        PctAcumulado <= 0.95, "B",
        "C"
    )

Nuevos clientes vs recurrentes

Clientes Nuevos = 
COUNTROWS(
    FILTER(
        VALUES(Clientes[ClienteID]),
        CALCULATE(MIN(Ventas[Fecha])) >= MIN(Calendario[Date]) &&
        CALCULATE(MIN(Ventas[Fecha])) <= MAX(Calendario[Date])
    )
)

Resumen

CALCULATE modifica el contexto de filtro y es la función central de DAX. ALL remueve filtros, FILTER crea filtros complejos, KEEPFILTERS intersecta. La transición de contexto convierte contexto de fila en filtro automáticamente. Estos patrones son la base de métricas avanzadas como ranking, ABC y análisis de cohortes.

🔒

Ejercicio práctico disponible

Patrones avanzados con CALCULATE, ALL y FILTER

Desbloquear ejercicios
// Patrones avanzados con CALCULATE, ALL y FILTER
// Desbloquea Pro para acceder a este ejercicio
// y ganar +50 XP al completarlo

function ejemplo() {
    // Tu código aquí...
}

¿Te gustó esta lección?

Con Pro puedes marcar progreso, hacer ejercicios, tomar quizzes, ganar XP y obtener tu constancia.

Ver planes desde $9/mes