Funções DAX para Análise Avançada: INDEX, OFFSET e WINDOW

Tempo de leitura:

5-8 minutos

As funções INDEX, OFFSET e WINDOW representam uma evolução importante na forma como escrevemos cálculos analíticos em DAX. Estas funções permitem navegar em tabelas ordenadas, identificar linhas por posição, comparar a linha atual com linhas anteriores ou seguintes e criar cálculos baseados em intervalos de linhas.

Em termos simples, estas funções ajudam-nos a responder a perguntas como:

  • Qual é o primeiro produto no ranking de vendas?
  • Qual foi o valor do mês anterior?
  • Qual é a diferença entre a linha atual e a linha anterior?
  • Qual é o acumulado até à linha atual?
  • Qual é a média móvel dos últimos três períodos?

Antes destas funções, muitos cálculos em DAX exigiam combinações mais complexas de funções como FILTER, TOPN, RANKX, CALCULATE, ALL, EARLIER ou outras técnicas avançadas.

Por exemplo, comparar o valor de vendas de um produto com o produto anterior num ranking exigia normalmente criar uma lógica de ranking e depois procurar manualmente a posição anterior.

Função INDEX

A função INDEX devolve uma linha numa posição específica dentro de uma tabela ordenada. Podemos considerar que a função responde à pergunta: “qual é a linha na posição X?”

A sintaxe simplificada da função é:

INDEX (

    posição,

    tabela,

    ORDERBY(…)

)

A função inclui ainda outros argumentos opcionais, onde o mais utilizado é o PARTITIONBY que permite dividir a tabela em grupos independentes.

Os seus argumentos principais são:

position

Define a posição da linha a devolver.

  • 1 devolve a primeira linha.
  • 2 devolve a segunda linha.
  • -1 devolve a última linha.
  • -2 devolve a penúltima linha.


relation

É a tabela ou expressão de tabela sobre a qual a função vai trabalhar.

orderBy

Define a ordem das linhas.

partitionBy

Permite dividir a tabela em grupos independentes.

Exemplo de aplicação

Vamos ver um exemplo, imaginando uma determinada medida já implementada no modelo.

Total de Vendas =

SUMX(

    ‘Transações’;

    ‘Transações'[Quantidade] * RELATED(Produtos[P. Unit.])

)

Vamos aceder à vista DAX Query para podermos testar a visualização de uma tabela, que é o resultado da função INDEX (a função INDEX devolve uma linha ou tabela).

Interface do Power BI Desktop com foco no painel de consultas DAX, mostrando opções para executar consultas e atualizar o modelo.

E vamos criar uma tabela que mostra o total de vendas por cada produto.

EVALUATE

VAR ProdutosComVendas =

    ADDCOLUMNS (

        ALL ( Produtos[Produto] ),

        “@TotalVendas”, [Total de Vendas]

    )

RETURN

    ProdutosComVendas

Captura de tela do Power BI Desktop mostrando um script DAX para calcular produtos com vendas, incluindo uma tabela com nomes de produtos e suas respectivas quantidades vendidas.

Imaginamos agora que pretendemos obter apenas 1 linha, e essa linha mostra o produto com a maior venda.

EVALUATE

VAR ProdutosComVendas =

    ADDCOLUMNS (

        ALL ( Produtos[Produto] ),

        “@TotalVendas”, [Total de Vendas]

    )

RETURN

    SELECTCOLUMNS(

        INDEX(

            1,

            ProdutosComVendas,

            ORDERBY( [@TotalVendas], DESC)

        ),

        “@Produto”, Produtos[Produto]

    )

Tela do Power BI exibindo um código DAX com a função EVALUATE e resultados de vendas de produtos.

A tabela a ser utilizada pela função INDEX pode ser qualquer uma, e no exemplo seguinte vamos usar uma das tabelas do modelo e devolver toda a linha.

EVALUATE

INDEX(

    -1,

    Produtos,

    ORDERBY( Produtos[P. Unit.], DESC)

)

Tela do Power BI mostrando uma consulta DAX com a função EVALUATE e a tabela Produtos, listando resultados de um produto chamado 'Tapete Yoga' na categoria Fitness.

Vamos ver agora a expressão com a opção partitionby, que permite obter por exemplo o produto com o preço unitário mais alto, agrupado por categoria.

Tela do Power BI Desktop mostrando uma consulta DAX com código para organizar produtos por categoria e unidades, e seus resultados listados abaixo.

Função OFFSET

A função OFFSET devolve uma linha antes ou depois da linha atual. Em linguagem simples: a função OFFSET responde à pergunta: “qual é a linha anterior ou seguinte?”

Os seus argumentos diretos são:

OFFSET (

    delta   ,

    relação,

    ORDERBY(…)

)

delta

Define quantas linhas queremos andar para trás ou para a frente.

  • -1 devolve a linha anterior.
  • 1 devolve a linha seguinte.
  • -2 devolve duas linhas antes.
  • 2 devolve duas linhas depois.

relation

Define a tabela sobre a qual queremos navegar.

orderBy

Define a ordem lógica das linhas.

partitionBy

Permite aplicar o deslocamento dentro de cada grupo

Exemplo da expressão

No exemplo vamos devolver o preço unitário do produto da “linha anterior”.

No cenário precisamos de uma tabela, e adicionar uma coluna, por isso vamos usar a função ADDCOLUMNS. Precisamos também de especifica a função SELECTCOLUMNS, uma vez que a função OFFSET devolve uma linha, e não conseguimos colocar uma linha inteira dentro de uma coluna.

Interface do Power BI exibindo um script DAX e resultados de uma consulta de produtos, destacando a 'Sapatilha WL373' com suas respectivas unidades.

Neste exemplo, a função offset com a opção -1 devolve o produto imediatamente anterior, especificamente o preço unitário.

Devemos usar então a função OFFSET quando precisamos de obter uma linha numa posição relativa em vez de absoluta -> INDEX por exemplo para comparar a linha atual com uma linha anterior, ou próxima linha.

Exemplos:

  • Vendas do mês anterior.
  • Diferença face ao produto anterior no ranking.
  • Valor do cliente seguinte.
  • Crescimento face ao período anterior.
  • Comparação linha a linha

Função WINDOW

A função WINDOW devolve várias linhas dentro de um intervalo definido, respondendo à pergunta: “qual é o conjunto de linhas entre o ponto A e o ponto B?”

A sua sintaxe simplificada é:

WINDOW (

    início, tipo_início,

    fim, tipo_fim,

    tabela,

    ORDERBY(…)

)

from

Define onde começa a janela.

from_type

Define se o início é absoluto ou relativo:

  • ABS significa posição absoluta.
  • REL significa posição relativa à linha atual.

to

Define onde acaba a janela.

to_type

Define se o fim é absoluto ou relativo.

Exemplo da expressão

No exemplo vamos ver como obter uma “janela” de linhas do inicio da tabela até à 5ª linha, ambas absolutas.

EVALUATE

WINDOW(

    0, ABS,

    5, ABS,

    Produtos,

    ORDERBY(Produtos[ID Produto])

    )

Captura de tela do Power BI Desktop mostrando uma consulta DAX com a função EVALUATE e resultados de produtos em uma tabela, incluindo identificadores e categorias.

O resultado devolve as 5 primeiras linhas da tabela Produtos.

Modificando o 2 argumento para relativo, obtemos uma “janela” de registos desde o início até 5 linhas “antes” da linha atual no contexto a ser avaliado.

Na query o contexto é a tabela inteira de produtos, por isso, em termos práticos estamos a dizer que estamos a obter todas as linhas, menos as 5 últimas…

EVALUATE

WINDOW(

    0, ABS,

    – 5, REL,

    Produtos,

    ORDERBY(Produtos[ID Produto])

    )

Captura de tela do Power BI mostrando uma consulta DAX com resultados de produtos de corrida e ciclismo, incluindo informações como ID do produto, nome, categoria e preço unitário.

Num cenário mais específico, vamos imaginar que pretendemos uma nova coluna na tabela, que mostra os últimos 5 produtos em relação à linha atual. Esta expressão vai usar várias funções:

  • ADDCOLUMNS, para adicionar uma nova coluna na tabela.
  • CONCATENATEX, para juntar texto.
  • WINDOW, para mostrar uma “janela” de produtos.
Tabela de produtos com colunas como ID do produto, nome do produto, categoria e preço unitário, exibindo diversas sapatilhas e bicicletas.

No exemplo conseguimos analisar o produto da linha atual (0) e os últimos 5 produtos (-5) em relação à linha atual.

Exemplo prático de aplicação

Vamos agora ver um exemplo prático de aplicação.

Quando estamos a comparar períodos temporais, para criar acumulados, ou mesmo homólogos, usamos funções TIMEINTELLIGENCE. Mas estas funções são específicas para períodos temporais com datas.

Vamos imaginar que queremos criar um acumulado de vendas baseado em produtos. Mais especificamente criar um visual, que mostra um gráfico de “pareto”.

No exemplo temos o nosso modelo, com a medida [Total de Vendas] apresentada num gráfico e numa tabela. Os dados estão ordenados por vendas, do maior para o menor, para podermos verificar melhor a tendência dos valores e apresentar o formato “pareto”.

Gráfico de barras mostrando o total de vendas por produto, com destaque para Bicicleta Trail 115 e Sportcross 216, apresentando valores em euros.

Pretendemos então criar uma medida que calcula o valor da venda atual, com a próxima, acumulando os valores.

No final iremos ter os valore em % para apresentarmos o “gráfico de pareto” com o crescimento.

Acumulado Pareto =

VAR MaiorVendaProduto =

    WINDOW(

        1; ABS;

        0; REL;

        ALL(Produtos);

        ORDERBY([Total de Vendas]; DESC)

    )

RETURN

    CALCULATE(

        [Total de Vendas];

        MaiorVendaProduto

    )

Captura de tela do Power BI Desktop mostrando o código DAX para análise de vendas e um gráfico de barras representando o total de vendas por produto.

O resultado apresentado na tabela é o seguinte:

Agora para definirmos a linha do gráfico, criamos uma medida que junta a informação toda.

Linha Pareto =

VAR VendasAcumuladas =

    CALCULATE(

        [Total de Vendas];

        WINDOW(

            1; ABS;

            0; REL;

            ALL(Produtos);

            ORDERBY([Total de Vendas]; DESC)

        )

    )

VAR TodasAsVendas =

    CALCULATE(

        [Total de Vendas];

        ALL(Produtos)

    )

VAR PctPareto =

    DIVIDE(VendasAcumuladas; TodasAsVendas)

RETURN

    PctPareto

Aplicando esta medida no gráfico, obtemos a linha acumulada em %, onde podemos também consultar os valores na tabela.

Gráfico de vendas mostrando o total de vendas e a linha Pareto por produto. Barras azuis representam o total de vendas de diferentes produtos, enquanto a linha roxa indica a porcentagem acumulada das vendas.

As funções INDEX, OFFSET e WINDOW tornam o código DAX mais expressivo e mais próximo da forma como muitos analistas pensam os seus cálculos: por posição, por linha anterior ou por intervalo.

Estas funções são especialmente úteis em cenários de ranking, comparação sequencial, análises temporais, médias móveis e acumulados como Pareto.

Embora muitas destas análises já fossem possíveis em DAX com combinações mais complexas de funções, INDEX, OFFSET e WINDOW permitem escrever fórmulas mais claras, mais legíveis e, muitas vezes, mais fáceis de manter.

Para quem trabalha com Power BI em contextos analíticos avançados, dominar estas três funções é um passo importante para criar medidas mais elegantes, comparações mais robustas e análises mais dinâmicas.

Próximo artigo:

Artigo Anterior:


Comentários

Leave a Reply

Discover more from Exceldriven

Subscribe now to keep reading and get access to the full archive.

Continue reading