Home » Pivot Table by Agent

Pivot Table by Agent

Pivot the given table as shown.

📌 Challenge Details and Links
ExcelBI Power Query Challenge Number: 173
Challenge Difficulty: ⭐️⭐️⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn

Solving the challenge of Pivot Table by Agent with Power Query

Power Query solution 1 for Pivot Table by Agent, proposed by Zoran Milokanović:
let
 Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
 S = Table.Combine(Table.Group(Table.Group(Table.FromRecords(Table.TransformRows(Source, each _ & [Year = Date.Year([Date]), Quarter = Date.QuarterOfYear([Date]), Month = DateTime.ToText([Date], "MMM", "en-US")])), {"Year", "Quarter", "Month"}, {{"Total Sale", each List.Sum([Sale])}}), {"Year"}, {{"A", each let g = List.Sum([Total Sale]), t = Table.AddColumn(_ & hashtag#table({"Year", "Total Sale"}, {{Text.From([Year]{0}) & " Total", g}}), "Sale %", each [Total Sale] / g), c = Table.RowCount(t) in Table.FromRecords(List.Generate(() => 0, each _ < c, each _ + 1, each if _ = 0 or _ = c - 1 then t{_} else Record.TransformFields(t{_}, {{"Year", each null}, {"Quarter", (r) => {r}{Number.From(t{_ - 1}[Quarter] = t{_}[Quarter])}?}})))}})[A])
in
 S
                    
                  
          
Power Query solution 2 for Pivot Table by Agent, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Year = Table.AddColumn(Source, "Year", each Date.Year([Date])), 
  Quarter = Table.AddColumn(Year, "Quarter", each Date.QuarterOfYear([Date])), 
  Month = Table.AddColumn(Quarter, "Month", each Text.Start(Date.MonthName([Date]), 3)), 
  Total = Table.Group(Month, {"Year", "Quarter", "Month"}, {{"Total Sale", each List.Sum([Sale])}}), 
  A = Table.ToColumns(Total), 
  YQ = List.Transform(
    {0, 1}, 
    (x) => {A{x}{0}}
      & List.Skip(
        List.Transform(
          {0 .. List.Count(A{x}) - 1}, 
          each if A{x}{_} = A{x}{_ - 1} then null else A{x}{_}
        )
      )
  ), 
  Total2 = Table.FromColumns(YQ & List.Skip(Table.ToColumns(Total), 2), Table.ColumnNames(Total)), 
  Sol = Table.Combine(
    Table.Group(
      Total2, 
      {"Year"}, 
      {
        {
          "B", 
          each 
            let
              a = List.Sum([Total Sale]), 
              b = Table.AddColumn(_, "Sales %", each Number.ToText([Total Sale] / a, "p0")), 
              c = Table.FromRows(
                Table.ToRows(b) & {{"Total " & Text.From(b[Year]{0}), null, null, a, "100%"}}, 
                Table.ColumnNames(b)
              )
            in
              c
        }
      }, 
      0, 
      (x, y) => Number.From(y[Year] <> null)
    )[B]
  )
in
  Sol
Power Query solution 3 for Pivot Table by Agent, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Year = Table.AddColumn(Source, "Year", each Date.Year([Date])), 
  Quarter = Table.AddColumn(Year, "Quarter", each Date.QuarterOfYear([Date])), 
  Month = Table.AddColumn(Quarter, "Month", each Text.Start(Date.MonthName([Date]), 3)), 
  Group = Table.Group(Month, {"Year", "Quarter", "Month"}, {{"Total Sale", each List.Sum([Sale])}}), 
  Sol = Table.Combine(
    Table.Group(
      Group, 
      {"Year"}, 
      {
        {
          "B", 
          each 
            let
              a = List.Sum([Total Sale]), 
              b = Table.AddColumn(_, "Sales %", each Number.ToText([Total Sale] / a, "p0")), 
              c = Table.Group(
                b, 
                {"Year", "Quarter"}, 
                {
                  "C", 
                  each Table.FromRows(
                    List.Zip({[Year], {[Quarter]{0}}, [Month], [Total Sale], [#"Sales %"]}), 
                    Table.ColumnNames(b)
                  )
                }
              ), 
              d = Table.Combine(
                Table.Group(
                  Table.Combine(c[C]), 
                  {"Year"}, 
                  {
                    "D", 
                    each Table.FromRows(
                      List.Zip({{[Year]{0}}, [Quarter], [Month], [Total Sale], [#"Sales %"]})
                    )
                  }
                )[D]
              ), 
              e = Table.FromRows(
                Table.ToRows(d) & {{"Total " & Text.From(b[Year]{0}), null, null, a, "100%"}}, 
                Table.ColumnNames(b)
              )
            in
              e
        }
      }
    )[B]
  )
in
  Sol
Power Query solution 4 for Pivot Table by Agent, proposed by Luan Rodrigues:
let
  Fonte = Tabela1, 
  add = List.Accumulate(
    {"Year", "Quarter", "Month"}, 
    Fonte, 
    (s, c) =>
      Table.AddColumn(
        s, 
        c, 
        each 
          if c = "Year" then
            Date.Year([Date])
          else if c = "Quarter" then
            Date.QuarterOfYear([Date])
          else
            DateTime.ToText([Date], "MMM", "en-us")
      )
  ), 
  gp = Table.Group(add, {"Year", "Quarter", "Month"}, {{"Total Sales", each List.Sum([Sale])}}), 
  grp = Table.Group(
    gp, 
    {"Year"}, 
    {
      "tab", 
      each 
        let
          a = _, 
          b = a
            & #table(
              {"Year", "Quarter", "Month", "Total Sales"}, 
              {{"Total " & Text.From(_[Year]{0}), null, null, List.Sum([Total Sales])}}
            ), 
          c = Table.AddColumn(
            b, 
            "Sales %", 
            each [Total Sales] / List.Sum(a[Total Sales]), 
            Percentage.Type
          )
        in
          c
    }
  )[tab], 
  sb = Table.ReplaceValue(
    Table.Combine(grp), 
    null, 
    each [Month], 
    (a, b, c) => if c = "Jan" or c = null then a else b, 
    {"Year"}
  ), 
  res = Table.ReplaceValue(
    sb, 
    null, 
    each [Month], 
    (a, b, c) => if c = "Jan" or c = "Apr" or c = "Jul" or c = "Oct" then a else b, 
    {"Quarter"}
  )
in
  res
Power Query solution 5 for Pivot Table by Agent, proposed by Eric Laforce:
let
  Source = Excel.CurrentWorkbook(){[Name = "tData173"]}[Content], 
  ChangeType = Table.TransformColumnTypes(Source, {{"Date", type date}}), 
  Add_ListYQM = Table.AddColumn(
    ChangeType, 
    "L", 
    each {Date.Year([Date]), Date.QuarterOfYear([Date]), Date.ToText([Date], "MMM", "en-US")}
  ), 
  GroupYQM = Table.Group(Add_ListYQM, {"L"}, {{"Y", each [L]{0}{0}}, {"S", each List.Sum([Sale])}}), 
  GroupY = Table.Group(
    GroupYQM, 
    "Y", 
    {
      "G", 
      each 
        let
          TYQM = List.Accumulate(
            List.Skip([L]), 
            [r = {[L]{0}}, pq = [L]{0}{1}], 
            (s, c) => [r = s[r] & {{null, if (c{1} = s[pq]) then null else c{1}, c{2}}}, pq = c{1}]
          )[r], 
          SSY = List.Sum([S]), 
          TS = List.Transform([S], each {_, _ / SSY}), 
          TYRow = {Text.Combine({Text.From([Y]{0}), " Total"}), null, null, SSY, 1}, 
          Rows = List.Transform(List.Zip({TYQM, TS}), List.Combine) & {TYRow}
        in
          Table.FromRows(Rows, {"Year", "Quarter", "Month", "Total Sales", "Sales %"})
    }
  ), 
  Combine = Table.Combine(GroupY[G])
in
  Combine
Power Query solution 6 for Pivot Table by Agent, proposed by Yaroslav Drohomyretskyi:
let
  Z = (G, y) =>
    let
      F = Table.SelectRows(G, each ([Y] = y)), 
      S = Table.AddColumn(F, "Sale %", each [Total Sale] / List.Sum(F[Total Sale]), Percentage.Type), 
      T = Table.FromRecords(
        Table.ToRecords(S)
          & {
            [
              Y          = Text.From(List.Average(S[Y])) & " Total", 
              Q          = null, 
              Month      = null, 
              Total Sale = List.Sum(S[Total Sale]), 
              #"Sale %"  = List.Sum(S[#"Sale %"])
            ]
          }
      ), 
      I = Table.AddIndexColumn(T, "Index", 1, 1), 
      Y = Table.AddColumn(I, "Year", each if [Index] = 1 or [Index] = 13 then [Y] else null), 
      Q = Table.AddColumn(
        Y, 
        "Quarter", 
        each if List.Contains({1, 4, 7, 10}, [Index]) then [Q] else null
      ), 
      R = Table.SelectColumns(Q, {"Year", "Quarter", "Month", "Total Sale", "Sale %"})
    in
      R, 
  Source = Excel.CurrentWorkbook(){[Name = "T"]}[Content], 
  G = Table.Group(
    Table.AddColumn(
      Table.AddColumn(
        Table.AddColumn(Source, "Month", each Text.Start(Date.MonthName([Date], "en-US"), 3)), 
        "Q", 
        each Date.QuarterOfYear([Date])
      ), 
      "Y", 
      each Date.Year([Date])
    ), 
    {"Y", "Q", "Month"}, 
    {{"Total Sale", each List.Sum([Sale])}}
  ), 
  N = Table.AddColumn(Table.Distinct(Table.SelectColumns(G, {"Y"})), "X", each Z(G, [Y])), 
  R = Table.TransformColumnTypes(
    Table.RemoveColumns(
      Table.ExpandTableColumn(
        N, 
        "X", 
        {"Year", "Quarter", "Month", "Total Sale", "Sale %"}, 
        {"Year", "Quarter", "Month", "Total Sale", "Sale %"}
      ), 
      {"Y"}
    ), 
    {{"Sale %", Percentage.Type}}
  )
in
  R

Solving the challenge of Pivot Table by Agent with Excel

Excel solution 1 for Pivot Table by Agent, proposed by Bo Rydobon 🇹🇭:
=LET(d,A2:A731,y,YEAR(d),m,MONTH(d),g,REDUCE(D1:H1,UNIQUE(y),LAMBDA(a,v,VSTACK(a,
DROP(GROUPBY(HSTACK(m,y,ROUNDUP(m/3,),TEXT(d,"mmm")),B2:B731,HSTACK(SUM,PERCENTOF),,,,y=v),1,1)))),
c,{1,1,0,0,0},h,DROP(VSTACK(c,g),-1),IF((g="")*(N(h)>2000),h&" Total",IF((g=h)*c,"",g)))
Excel solution 2 for Pivot Table by Agent, proposed by محمد حلمي:
=LET(j,A2:A731,y,YEAR(j),m,MONTH(j),s,SEQUENCE(12),
c,(s-1)/3,q,INT(c)+1,
REDUCE(D1:H1,UNIQUE(y),LAMBDA(a,d,
IFNA(VSTACK(a,LET(
s,MAP(s,LAMBDA(a,SUM(B2:B731*(y=d)*(m=a)))),v,SUM(s),
VSTACK(HSTACK(d,IF(q=c+1,q,""),
TEXT(29*UNIQUE(m),"mmm"),s,s/v),
HSTACK(d&" Total","","",v,1)))),""))))
Excel solution 3 for Pivot Table by Agent, proposed by Julian Poeltl:
=VSTACK({"Year"."Quarter"."Month"."Total Sale"."Sale %"},LET(T,A1:B731,TT,DROP(T,1),D,CHOOSECOLS(TT,1),M,MONTH(D),Y,YEAR(D),S,CHOOSECOLS(TT,2),YU,UNIQUE(Y),MAKEARRAY(13*COUNTA(YU),5,LAMBDA(A,B,IFS(AND(MOD(A,13)=1,B=1),INDEX(YU,ROUNDDOWN(A/13,0)+1),AND(MOD(A,13)=0,B=1),INDEX(YU,ROUNDDOWN(A/13,0))&" Total",AND(B=2,MOD(A,13)=1),1,AND(B=2,MOD(A,13)=4),2,AND(B=2,MOD(A,13)=7),3,AND(B=2,MOD(A,13)=10),4,AND(B=3,MOD(A,13)<>0),TEXT(MOD(A,13)*30,"MMM"),AND(B=4,MOD(A,13)<>0),SUM(FILTER(S,(M=MOD(A,13)*(Y=INDEX(YU,ROUNDDOWN(A/13,0)+1))))),AND(B=5,MOD(A,13)),SUM(FILTER(S,(M=MOD(A,13)*(Y=INDEX(YU,ROUNDDOWN(A/13,0)+1)))))/SUM(FILTER(S,Y=INDEX(YU,ROUNDDOWN(A/13,0)+1))),AND(B=4,MOD(A,13)=0),SUM(FILTER(S,Y=INDEX(YU,ROUNDDOWN(A/14,0)+1))),AND(B=5,MOD(A,13)=0),1,1,"")))))
Excel solution 4 for Pivot Table by Agent, proposed by Sunny Baggu:
=LET(
 _u, UNIQUE(YEAR(A2:A731)),
 REDUCE(
 {"Year", "Quarter", "Month", "Total Sale", "Sale %"},
 _u,
 LAMBDA(x, y,
 VSTACK(
 x,
 LET(
 _q, TOCOL(EXPAND(SEQUENCE(4), , 3, ""), , 0),
 _m, TEXT(EDATE(DATE(y, 1, 1), SEQUENCE(12) - 1), "mmm"),
 _ts, MAP(
 SEQUENCE(12),
 LAMBDA(a, SUM((YEAR(A2:A731) = y) * B2:B731 * (MONTH(A2:A731) = a)))
 ),
 _s, MAP(_ts, LAMBDA(b, b / SUM(_ts))) * 100,
 VSTACK(
 IFNA(HSTACK(y, _q, _m, _ts, _s), ""),
 HSTACK(y & " Total", "", "", SUM(_ts), 100)
 )
 )
 )
 )
 )
)
Excel solution 5 for Pivot Table by Agent, proposed by Md. Zohurul Islam:
=LET(dt,A2:A731,sls,B2:B731,
hdr,{"Year","Quarter","Month","Total Sale","Sale %"},
yr,YEAR(dt),m,MONTH(dt),
a,GROUPBY(HSTACK(yr,m,TEXT(dt,"mmm")),sls,SUM,0,0),
b,CHOOSECOLS(a,1,3,4),
unq,UNIQUE(TAKE(b,,1)),
d,REDUCE(hdr,unq,LAMBDA(j,k,LET(
 p,FILTER(b,TAKE(b,,1)=k),
 q,CEILING(MONTH(--(1&CHOOSECOLS(p,2)))/12*4,1),
 qtr,DROP(REDUCE("",UNIQUE(q),LAMBDA(x,y,VSTACK(x,TAKE(IFNA(HSTACK(y,FILTER(CHOOSECOLS(p,2),q=y)),""),,1)))),1),
 s,SUM(TAKE(p,,-1)),
 prc,MAP(TAKE(p,,-1),LAMBDA(x,x/s)),
 r,HSTACK(k&" Total","","",s,s/s),
 t,HSTACK(k,qtr,DROP(p,,1),prc),
 u,IFNA(VSTACK(t,r),""),
 v,VSTACK(j,u),v))),
d)
Excel solution 6 for Pivot Table by Agent, proposed by Miguel Angel Franco García:
=LET(añosunicos;UNICOS(AÑO(A2:A731));mesesunicos;APILARV(UNICOS(TEXTO(A2:A731;"mmm"));" ");mesesdobles;APILARV(mesesunicos;mesesunicos;" ");añosytotales;SI(mesesunicos="ene";ENFILA(añosunicos);SI(mesesunicos=" ";"Total "&ENFILA(añosunicos);""));modeloañostotal;ENCOL(TRANSPONER(añosytotales));pivota;PIVOTARPOR(MES(A2:A731);AÑO(A2:A731);B2:B731;APILARH(SUMA;PORCENTAJEDE));total1;EXCLUIR(FILTRAR(pivota;TOMAR(pivota;1)=TOMAR(añosunicos;1));2);total2;EXCLUIR(FILTRAR(pivota;TOMAR(pivota;1)=ELEGIRFILAS(añosunicos;2));2);trimestres;SI(mesesdobles="ene";1;SI(mesesdobles="abr";2;SI(mesesdobles="jul";3;SI(mesesdobles="Oct";4;""))));resul;EXCLUIR(APILARH(modeloañostotal;trimestres;mesesdobles;APILARV(total1;total2));-1);resul)
Excel solution 7 for Pivot Table by Agent, proposed by Miguel Angel Franco García:
=LET(añosunicos;UNICOS(AÑO(A2:A731));mesesunicos;APILARV(UNICOS(TEXTO(A2:A731;"mmm"));" ");mesesdobles;APILARV(mesesunicos;" ";mesesunicos;" ");añosytotales;SI(mesesunicos="ene";ENFILA(añosunicos);SI(mesesunicos=" ";"Total "&ENFILA(añosunicos);""));modeloañostotal;ENCOL(TRANSPONER(añosytotales));pivota;PIVOTARPOR(MES(A2:A731);AÑO(A2:A731);B2:B731;APILARH(SUMA;PORCENTAJEDE));total1;EXCLUIR(FILTRAR(pivota;TOMAR(pivota;1)=TOMAR(añosunicos;1));2);total2;EXCLUIR(FILTRAR(pivota;TOMAR(pivota;1)=ELEGIRFILAS(añosunicos;2));2);trimestres;SI(mesesdobles="ene";1;SI(mesesdobles="abr";2;SI(mesesdobles="jul";3;SI(mesesdobles="Oct";4;""))));EXCLUIR(APILARH(modeloañostotal;trimestres;mesesdobles;APILARV(total1;total2));-2))

Solving the challenge of Pivot Table by Agent with Python

Python solution 1 for Pivot Table by Agent, proposed by Luan Rodrigues:
parte 1
import pandas as pd
import numpy as np
file_path = 'PYPQ_Challenge_173PQ_Challenge_173.xlsx'
df = pd.read_excel(file_path, usecols='A:B')
df['Year'] = df['Date'].dt.year
df['year'] = df['Date'].dt.year
df['Quarter'] = df['Date'].dt.quarter
df['Mn'] = df['Date'].dt.month
df['Month'] = df['Date'].dt.month_name().str.slice(stop=3)
df_gpr = df.groupby(['Year','year', 'Quarter', 'Month','Mn'])['Sale'].sum().reset_index(name='Total Sales')
df_gpr = df_gpr.sort_values(['Mn','Year'])
def calculate_sales(group):
 total_sales = group["Total Sales"].sum()
 group["Sales %"] = df_gpr["Total Sales"] / total_sales
 return group
df_result = df_gpr.groupby("Year").apply(calculate_sales).reset_index(drop=True)
df_year = df_result.groupby('Year').agg({'Total Sales': 'sum', 'Sales %': 'sum'}).reset_index()
df_year['Y'] = 'Total ' + df_year['Year'].astype('str')
df_year['year'] = df_year['Year']
df_year['Month'] = 'null'
df_year['Mn'] = 13 
df_year.drop(columns=['Year'], inplace=True)
df_year.columns = ['Total Sales', 'Sales %', 'Year','year', 'Month','Mn']
                    
                  
Python solution 2 for Pivot Table by Agent, proposed by Luan Rodrigues:
parte 2
df_total = pd.concat([df_result, df_year]).sort_values(['year','Mn']).reset_index(drop=True)
trimestre = ['Jan', 'Apr', 'Jul', 'Oct']
ano = ['Jan', 'null']
df_total['Y'] = np.where(df_total['Month'].isin(ano), df_total['Year'], 'null')
df_total['Q'] = np.where(df_total['Month'].isin(trimestre), df_total['Quarter'], 'null')
df_total.drop(columns=['Year', 'Quarter','year'], inplace=True)
df_total.columns = ['Month','Mn', 'Total Sales', 'Sales %', 'Year', 'Quarter']
new_order = ['Year', 'Quarter', 'Month', 'Total Sales', 'Sales %']
df_total = df_total[new_order]
print(df_total)
                    
                  

Solving the challenge of Pivot Table by Agent with R

R solution 1 for Pivot Table by Agent, proposed by Anil Kumar Goyal:
library(readxl)
library(janitor)
library(tidyverse)
df <- read_xlsx("PQ/PQ_Challenge_173.xlsx", range = cell_cols(LETTERS[1:2]))
df %>% 
 group_by(
 Year = year(Date),
 Quarter = as.factor(quarter(Date)),
 Month = month(Date, abbr = TRUE, label = TRUE)
 ) %>% 
 summarise(
 `Total Sale` = sum(Sale),
 .groups = 'drop'
 ) %>% 
 mutate(
 `Sale %` = scales::percent(`Total Sale`/sum(`Total Sale`),
 accuracy = 1),
 .by = Year
 ) %>% 
 group_split(Year) %>% 
 map_dfr(janitor::adorn_totals) %>% 
 mutate(`Sale %` = ifelse(`Sale %` == "-", "100%", `Sale %`))
                    
                  

&&

Leave a Reply