Cómo calcular día de la semana ponderado en DAX: paso a paso
Vamos a crear una medida en DAX que calcula un valor medio ponderado por día de la semana (por ejemplo, ventas ponderadas por importancia del día). Esto es útil cuando algunos días tienen mayor relevancia, coste o impacto en el negocio y quieres reflejar eso en los análisis — por ejemplo, si el sábado tiene tráfico un 50% superior, o si el lunes es menos representativo por festivos. La idea es aplicar pesos por WeekdayNumber y calcular una media ponderada que sustituya a la media simple o al total simple.
Prerequisitos
- Power BI Desktop con un modelo simple: tabla FactSales (Date, SalesAmount, Quantity) y tabla Date con columna WeekdayName y WeekdayNumber (1‑7). Nota: por defecto DAX WEEKDAY devuelve 1=Domingo; ajusta según tu calendario si usas 1=Lunes).
- Conocimiento básico de medidas en DAX, relaciones entre tablas y funciones como SUMX, VALUES y LOOKUPVALUE.
- Objetivo: crear una medida WeightedSalesByWeekday en DAX que refleje pesos asignados a cada día de la semana.
Paso 1: Definir la tabla de pesos por día de la semana
Necesitamos una tabla que asocie cada día de la semana a un peso (por ejemplo, lun=1, sáb=1.5). Puedes crear una tabla calculada en DAX o cargar una tabla manual vía Power Query/CSV. La ventaja de DATATABLE es que queda en el modelo y es fácil de modificar. Ejemplo con pesos plausibles: días laborables 1.0, jueves 1.2, viernes 1.3, sábado 1.5.
WeekdayWeights =
DATATABLE(
"WeekdayNumber", INTEGER,
"Weight", DOUBLE,
{
{1, 1.0}, -- Domingo (ajusta conforme a tua WeekdayNumber)
{2, 1.1}, -- Segunda
{3, 1.0}, -- Terça
{4, 1.0}, -- Quarta
{5, 1.2}, -- Quinta
{6, 1.3}, -- Sexta
{7, 1.5} -- Sábado
}
)
Paso 2: Asegurar relación entre Date y WeekdayWeights
Si tu tabla Date tiene WeekdayNumber, crea una relación entre Date[WeekdayNumber] y WeekdayWeights[WeekdayNumber]. Esto permite filtrar por día de la semana y usar RELATED o reglas de contexto de filtro. Sin relación, tendrás que usar LOOKUPVALUE con cuidado, lo que puede afectar al rendimiento. Confirma también que la granularidad de la tabla Date cubre todo el periodo de FactSales (por ejemplo, 3 años = ~1 095 filas).
Paso 3: Medida básica de ventas
Crear una medida simple para usar como base: SalesAmountTotal. Es la referencia para comparar el resultado ponderado con el total no ponderado.
SalesAmountTotal = SUM(FactSales[SalesAmount])
Paso 4: Medida de peso aplicado por fila de venta (opcional)
Si tienes granularidad en la fact table con la fecha de la venta, puedes obtener el peso usando RELATED a través de la relación Date → WeekdayWeights (o vía LOOKUPVALUE si no hay relación). Esto permite ver, fila a fila, cuál es el Weight aplicado. Útil para depuración y validación: por ejemplo, si una venta el 2026‑08‑07 (sábado) tiene peso 1.5.
SaleWeight =
VAR wd = RELATED('Date'[WeekdayNumber])
RETURN
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], wd)
Paso 5: Crear la medida WeightedSalesByWeekday (ejemplo recomendado)
La medida que interesa es la suma de las ventas multiplicadas por el peso, dividida por la suma de los pesos (media ponderada). Usamos CALCULATE y SUMX para iterar por los días en la tabla Date visible en el contexto actual. Esto garantiza que los filtros por periodo o por producto se respeten.
WeightedSalesByWeekday =
VAR VisibleDays = VALUES('Date'[Date])
VAR Numerator =
SUMX(
VisibleDays,
CALCULATE(SUM(FactSales[SalesAmount])) *
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], MAX('Date'[WeekdayNumber]))
)
VAR Denominator =
SUMX(
VisibleDays,
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], MAX('Date'[WeekdayNumber]))
)
RETURN
IF(Denominator = 0, BLANK(), Numerator / Denominator)
Ejemplo concreto: si en un periodo tuviste 7 días con ventas diarias [100, 120, 80, 90, 110, 200, 150] y pesos [1,1.1,1,1,1.2,1.3,1.5], el Numerator será la suma de cada venta*peso (~100*1 + 120*1.1 + ... = ~1 204) y el Denominator la suma de los pesos (~8.1), resultando en una media ponderada ~148.6 en lugar de la media simple ~120. Una diferencia significativa que muestra el impacto del peso del fin de semana.
Paso 6: Versión alternativa por agregación por Weekday
Un enfoque más eficiente agrega primero por WeekdayNumber y luego aplica los pesos. Útil para grandes volúmenes donde iterar por cada día individual es costoso. Aquí agregas ventas por Weekday y multiplicas por los pesos, reduciendo llamadas a LOOKUPVALUE.
WeightedSalesByWeekday_Agg =
VAR AggByWeekday =
SUMMARIZE(
'Date',
'Date'[WeekdayNumber],
"SalesPerDay", CALCULATE(SUM(FactSales[SalesAmount]))
)
VAR Numerator =
SUMX(
AggByWeekday,
[SalesPerDay] *
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], 'Date'[WeekdayNumber])
)
VAR Denominator =
SUMX(
AggByWeekday,
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], 'Date'[WeekdayNumber])
)
RETURN
IF(Denominator = 0, BLANK(), Numerator / Denominator)
Verificar el resultado
Coloca las medidas WeightedSalesByWeekday y SalesAmountTotal en un visual (tabla o tarjeta) y prueba con filtros de periodo y por WeekdayName. Verifica casos conocidos: si todos los pesos son 1, la medida debe igualar SalesAmountTotal; si un día tiene peso mayor, ese día debe influir más en el resultado. Prueba también con filtros por hora/tienda para garantizar que la granularidad de la Date corresponde a la FactSales.
Conclusión
Con estas medidas puedes analizar ventas (o cualquier métrica) ajustada por pesos de día de la semana — útil en operaciones, staffing o análisis estacional. Próximos pasos: parametrizar los pesos con un What‑if parameter para ajustar interactivamente, o permitir edición vía Power Query. Consejo final: evita usar LOOKUPVALUE dentro de bucles muy grandes sin necesidad; la versión agregada tiende a ser más eficiente en modelos con cientos de miles de registros.