Home » Pivoting Data

Pivoting Data

Pivot the Customer’s table Create a Total for each Month Dynamic array function allowed but Extra marks for Legacy solutions or PowerQuery Solution

📌 Challenge Details and Links
Challenge Number: 22
Challenge Difficulty: ⭐⭐⭐
📥Link to the solutions on LinkedIn

Solving the challenge of Pivoting Data with Power Query

Power Query solution 1 for Pivoting Data, proposed by Omid Motamedisedeh:
let
  Source = Excel.CurrentWorkbook(){[Name = "tblSales"]}[Content], 
  Mrg = Table.CombineColumns(
    Source, 
    {"Month", "Customers", "Sales"}, 
    each Table.FromColumns(
      {{_{0}}, Text.Split(_{1}, ","), List.Transform(Text.Split(_{2}, ","), Number.From)}, 
      {"a", "b", "c"}
    ), 
    "N"
  ), 
  TtlRow = Table.TransformColumns(
    Mrg, 
    {
      {
        "N", 
        each Table.FillDown(_, {"a", "b"})
          & Table.FromRows({{"Total " & _[a]{0}, List.Sum(_[c])}}, {"a", "c"})
      }
    }
  ), 
  Result = Table.ExpandTableColumn(TtlRow, "N", {"a", "b", "c"}, {"Month", "Customer", "Sale"})
in
  Result
Power Query solution 2 for Pivoting Data, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "tblSales"]}[Content], 
  S = Table.FromRows(
    List.TransformMany(
      Table.ToRows(Source), 
      each 
        let
          l = each Text.Split(Text.Remove(_, " "), ","), 
          c = l(_{1}), 
          s = List.Transform(l(_{2}), Number.From)
        in
          List.Zip(
            {c & List.Repeat({List.Last(c)}, List.Count(s) - List.Count(c)), s & {List.Sum(s)}}
          ), 
      (i, _) => {{"", "Total "}{Number.From(_{0} = null)} & i{0}} & _
    ), 
    Table.ColumnNames(Source)
  )
in
  S
Power Query solution 3 for Pivoting Data, proposed by Aditya Kumar Darak 🇮🇳:
let
  Source = Excel.CurrentWorkbook(){[Name = "tblSales"]}[Content], 
  List = Table.AddColumn(
    Source, 
    "L", 
    each [
      M = [Month], 
      C = Text.Split([Customers], ", "), 
      S = List.Transform(Text.Split([Sales], ","), (f) => Number.From(f)), 
      Z = List.Zip({{M}, C, S}), 
      R = Z & {{"Total " & M, null, List.Sum(S)}}
    ][R]
  ), 
  Table = Table.FromRows(List.Combine(List[L]), Table.ColumnNames(Source)), 
  Return = Table.FillDown(Table, {"Month"})
in
  Return
Power Query solution 4 for Pivoting Data, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "tblSales"]}[Content], 
  Sol = Table.Combine(
    Table.Group(
      Source, 
      {"Month"}, 
      {
        {
          "A", 
          each 
            let
              a = _, 
              b = Table.AddColumn(
                a, 
                "B", 
                each Table.FromColumns(
                  List.Transform({[Customers], [Sales]}, each Text.Split(_, ", ")), 
                  List.Skip(Table.ColumnNames(a))
                )
              ), 
              c = Table.SelectColumns(b, {"Month", "B"}), 
              d = Table.ExpandTableColumn(c, "B", Table.ColumnNames(b[B]{0})), 
              e = d
                & Table.FromRows(
                  {
                    {"Total " & d[Month]{0}}
                      & {null}
                      & {List.Sum(List.Transform(d[Sales], Number.From))}
                  }, 
                  Table.ColumnNames(a)
                )
            in
              e
        }
      }
    )[A]
  )
in
  Sol
Power Query solution 5 for Pivoting Data, proposed by Luan Rodrigues:
let
 Fonte = tblSales,
 tab = Table.AddColumn(Fonte, "tab", each 
let
a = Table.FillDown(Table.FromRows(List.Zip(List.Transform(Record.FieldValues(_),each Text.Split(_,","))),Table.ColumnNames(Fonte)),{"Month","Customers"}),
b = 
hashtag
#table(Table.ColumnNames(Fonte),{{"Total "&a[Month]{0},null,List.Sum(List.Transform(a[Sales],Number.From))}} )
in a & b
)[tab],
 res = Table.Combine(tab)
in
 res
Power Query solution 6 for Pivoting Data, proposed by Brian Julius:
let/in statement - a topic I posted about a couple of times last week.

In this case, you can just build the monthly tables step-by-step within the record, checking your steps as you go, and then just call the final table when you're done. Easy-peasy. 😁

Here's my 
hashtag
#powerquery solution:

let
 Source = Excel.CurrentWorkbook(){[Name="tblSales"]}[Content],
 BuildTables = Table.SelectColumns( Table.AddColumn(Source, "Build", each [
 M = [Month], 
 C = Text.Split( [Customers], ", "),
 S = List.Transform(Text.Split( [Sales], ","), each Number.From(_)),
 T1 = Table.FromColumns( {{M}, C, S }),
 T2 = Table.FromColumns( {{"Total " & M}, {}, {List.Sum(S) }}),
 T = Table.FillDown( T1 & T2, {"Column1"} )
 ][T]), "Build"),
 Head = Table.ColumnNames(Source),
 Expand = Table.ExpandTableColumn(BuildTables, "Build", {"Column1", "Column2", "Column3"}, Head)
in
 Expand
Power Query solution 7 for Pivoting Data, proposed by Ramiro Ayala Chávez:
let
  S = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  a = Table.TransformColumns(
    S, 
    {
      {"Customers", each Text.Split(_, ", ")}, 
      {"Sales", each List.Select(Text.SplitAny(_, ",, "), each _ <> "")}
    }
  ), 
  b = Table.AddColumn(a, "M", each Table.FromColumns({[Customers], [Sales]}))[[Month], [M]], 
  c = Table.TransformColumnTypes(
    Table.FillDown(Table.ExpandTableColumn(b, "M", {"Column1", "Column2"}), {"Column1"}), 
    {"Column2", Int64.Type}
  ), 
  d = Table.RenameColumns(c, List.Zip({Table.ColumnNames(c), Table.ColumnNames(S)})), 
  e = Table.Group(d, {"Month"}, {"G", each _})[[G]], 
  f = Table.TransformColumns(
    e, 
    {
      "G", 
      each Table.Group(
        _, 
        {}, 
        {
          {"Month", each "Total " & [Month]{0}}, 
          {"Customers", each ""}, 
          {"Sales", each List.Sum([Sales])}
        }
      )
    }
  ), 
  g = List.Generate(
    () => [i = 0], 
    each [i] < Table.RowCount(f), 
    each [i = [i] + 1], 
    each Record.ToTable(e{[i]})[[Value]] & Record.ToTable(f{[i]})[[Value]]
  ), 
  Sol = Table.Combine(Table.Combine(g)[Value])
in
  Sol
Power Query solution 8 for Pivoting Data, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
  S = Excel.CurrentWorkbook(){[Name = "tblSales"]}[Content], 
  B = Table.AddColumn(
    S, 
    "T", 
    each Table.FillDown(
      Table.FromColumns(
        {
          Splitter.SplitTextByDelimiter(",")([Customers]), 
          Splitter.SplitTextByDelimiter(",")([Sales])
        }, 
        {"Customer", "Sales"}
      ), 
      {"Customer"}
    )
  ), 
  C = Table.SelectColumns(B, {"Month", "T"}), 
  D = Table.ExpandTableColumn(C, "T", {"Customer", "Sales"}, {"Customer", "Sales"}), 
  E = Table.TransformColumnTypes(D, {{"Sales", Int64.Type}}), 
  F = Table.TransformColumns(E, {{"Customer", Text.Trim, type text}}), 
  G = Table.AddColumn(
    F, 
    "Index", 
    each 
      if [Month] = "Jan" then
        1
      else if [Month] = "Feb" then
        2
      else if [Month] = "Mar" then
        3
      else if [Month] = "Apr" then
        4
      else
        null, 
    Int64.Type
  ), 
  H = Table.Group(G, {"Month"}, {{"Sales", each List.Sum([Sales]), type nullable number}}), 
  I = Table.AddIndexColumn(H, "Index", 1, 1, Int64.Type), 
  J = Table.TransformColumns(I, {{"Month", each "Total " & _, type text}}), 
  K = Table.Combine({G, J}), 
  L = Table.Sort(K, {{"Index", Order.Ascending}, {"Sales", Order.Ascending}}), 
  M = Table.SelectColumns(L, {"Month", "Customer", "Sales"})
in
  M
Power Query solution 9 for Pivoting Data, proposed by Peter Tholstrup:
let
  Source = Excel.CurrentWorkbook(){[Name = "tblSales"]}[Content], 
  transform = List.Transform(
    Table.ToRecords(Source), 
    each [
      getList            = (lst, func) => List.Transform(Text.Split(lst, ","), func), 
      customers          = getList([Customers], Text.Trim), 
      sales              = getList([Sales], Number.FromText), 
      pair               = List.Zip({customers, sales}), 
      month              = [Month], 
      sales_per_customer = List.Transform(pair, each [Month = month, Customer = _{0}, Sales = _{1}]), 
      details            = Table.FillDown(Table.FromRecords(sales_per_customer), {"Customer"}), 
      totals             = Table.FromRecords({[Month = "Total " & month, Sales = List.Sum(sales)]}), 
      result             = Table.Combine({details, totals})
    ][result]
  ), 
  result = Table.Combine(transform)
in
  result
Power Query solution 10 for Pivoting Data, proposed by Nelson Mwangi:
let
  Source = Excel.CurrentWorkbook(){[Name = "tblSales"]}[Content], 
  SplitCust = Table.AddColumn(Source, "Custom", each Text.Split([Customers], ",")), 
  SplitSales = Table.AddColumn(SplitCust, "Custom.1", each Text.Split([Sales], ",")), 
  TableFromCols = Table.AddColumn(
    SplitSales, 
    "Data", 
    each Table.FromColumns({[Custom], [Custom.1]}, {"Customers", "Sales"})
  ), 
  RemoveCols = Table.SelectColumns(TableFromCols, {"Month", "Data"}), 
  Expand = Table.ExpandTableColumn(RemoveCols, "Data", {"Customers", "Sales"}), 
  FillD = Table.FillDown(Expand, {"Customers"}), 
  DataType = Table.TransformColumnTypes(FillD, {{"Sales", type number}}), 
  Totals = Table.Group(DataType, {"Month"}, {{"Sales", each List.Sum([Sales])}}), 
  CreateTotalColumn = Table.AddColumn(Totals, "M", each "Total " & Text.From([Month])), 
  RemoveMonth = Table.SelectColumns(CreateTotalColumn, {"Sales", "M"}), 
  Rename = Table.RenameColumns(RemoveMonth, {{"M", "Month"}}), 
  Combine = Table.Combine({DataType, Rename})
in
  Combine

Solving the challenge of Pivoting Data with Excel

Excel solution 1 for Pivoting Data, proposed by 🇰🇷 Taeyong Shin:
=LET(
   d,
   B3:D6,
   REDUCE(
       B2:D2,
       TAKE(
           d,
           ,
           1),
       LAMBDA(
           a,
           v,
           LET(
               f,
               LAMBDA(
                   c,
                   TEXTSPLIT(
                       INDEX(
                           v:D6,
                           1,
                           c),
                       ,
                       ",")),
               s,
               --f(
                   3),
               VSTACK(
                   a,
                   CHOOSE(
                       {1,
                       2,
                       3},
                       v,
                       f(
                           2),
                       s),
                   HSTACK(
                       "Total"&v,
                       "",
                       SUM(
                           s)))))))
Excel solution 2 for Pivoting Data, proposed by Julian Poeltl:
=LET(
   T,
   B2:D6,
   TT,
   DROP(
       T,
       1),
   LC,
   LAMBDA(
       T,
       LEN(
           T)-LEN(
           SUBSTITUTE(
               T,
               ",",
               ""))),
   M,
   TAKE(
       TT,
       ,
       1),
   S,
   TAKE(
       TT,
       ,
       -1),
   C,
   CHOOSECOLS(
       TT,
       2),
   CR,
   MAP(
       C,
       S,
       LAMBDA(
           A,
           B,
           IF(
               ISNUMBER(
                   SEARCH(
                       ",",
                       A)),
               A,
               REPT(
                   A&",",
                   LC(
                       B)+1)))),
   CCor,
   IF(
       RIGHT(
           CR,
           1)=",",
       LEFT(
           CR,
           LEN(
               CR)-1),
       CR),
   ToC,
   LAMBDA(
       A,
       TEXTSPLIT(
           TEXTJOIN(
               ", ",
               ,
               A),
           ,
           {", ",
           ","})),
   CC,
   ToC(
       CCor),
   SC,
   ToC(
       S)*1,
   AM,
   MAP(
       M,
       S,
       LAMBDA(
           M,
           S,
           REPT(
               M&",",
               LC(
       S)+1))),
   AMC,
   DROP(
       TEXTSPLIT(
           CONCAT(
               AM),
           ,
           ","),
       -1),
   US,
   MAP(
       M,
       LAMBDA(
           A,
           SUM(
               FILTER(
                   SC,
                   AMC=A)))),
   FM,
   TEXT(
       SEQUENCE(
           4,
           ,
           ,
           31),
       "MMM"),
   ST,
   
    VSTACK(
        HSTACK(
            AMC,
            CC,
            SC),
        IFERROR(
            HSTACK(
                M&" Total",
                "",
                US),
            "")),
   Sort,
   XMATCH(
       LEFT(
           TAKE(
               ST,
               ,
               1),
           2)&"*",
       M,
       2),
   Sorted,
   SORTBY(
       ST,
       Sort),
   VSTACK(
       HSTACK(
           TAKE(
               T,
               1,
               1),
           "Customer",
           TAKE(
               T,
               1,
               -1)),
       HSTACK(
           SCAN(
               ,
               TAKE(
                   Sorted,
                   ,
                   1),
               LAMBDA(
                   A,
                   B,
                   TEXTAFTER(
                       B,
                       " ",
                       ,
                       ,
                       ,
                       B)&" "&TEXTBEFORE(
                       B,
                       " ",
                       ,
                       ,
                       ,
                       ""))),
           DROP(
                   Sorted,
                   ,
                   1))))
Excel solution 3 for Pivoting Data, proposed by Oscar Mendez Roca Farell:
=REDUCE(
   B2:D2,
    D3:D6,
    LAMBDA(
        i,
         x,
         LET(
             a,
              TAKE(
                  B3:x,
                   -1),
              F,
              LAMBDA(
                  r,
                   TEXTSPLIT(
                       INDEX(
                           a ,
                            ,
                           r),
                       ,
                       ","&{"",
                       " "})),
              s,
             --F(
                 3),
              VSTACK(
                  i,
                   VSTACK(
                       IFNA(
                           HSTACK(
                               F(
                                   1),
                                F(
                                    2),
                                s),
                            a),
                        HSTACK(
                            "Total "&F(
                                   1),
                            "",
                             SUM(
                                 s)))))))
Excel solution 4 for Pivoting Data, proposed by Sunny Baggu:
=REDUCE(
   
    tblSales[
   hashtag
   #Headers],
   
    SEQUENCE(
        ROWS(
            tblSales)),
   
    LAMBDA(
        x,
         y,
        
         VSTACK(
             
              x,
             
              LET(
                  
                   _c,
                   INDEX(
                       tblSales,
                        y,
                        ),
                  
                   _a,
                   DROP(
                       
                        REDUCE(
                            
                             "",
                            
                             SEQUENCE(
                                 COLUMNS(
            tblSales)),
                            
                             LAMBDA(
                                 a,
                                  v,
                                  HSTACK(
                                      a,
                                       TEXTSPLIT(
                                           INDEX(
                                               _c,
                                                ,
                                                v),
                                            ,
                                            {",",
                                            ", "},
                                            1)))
                             ),
                       
                        ,
                       
                        1
                        ),
                  
                   _b,
                   HSTACK(
                       TAKE(
                           _a,
                            ,
                            2),
                        --TAKE(
                            _a,
                             ,
                             -1)),
                  
                   VSTACK(
                       
                        IFNA(
                            _b,
                             INDEX(
                                 _c,
                                  ,
                                  1)),
                       
                        HSTACK(
                            "Total " & INDEX(
                                 _c,
                                  ,
                                  1),
                             "",
                             SUM(
                                 TAKE(
                                     _b,
                                      ,
                                      -1)))
                        )
                   )
              )
         )
   )
Excel solution 5 for Pivoting Data, proposed by Abdallah Ally:
=REDUCE(
   B2:D2,
   B3:B6,
   LAMBDA(
       x,
       y,
       LET(
           b,
           OFFSET(
               y,
               ,
               1),
           c,
           TEXTSPLIT(
               b,
               ,
               {", ",
               ","}),
           d,
           --TEXTSPLIT(
               OFFSET(
                   y,
                   ,
                   2),
               ,
               {", ",
               ","}),
           e,
           COUNT(
               d),
           VSTACK(
               x,
               HSTACK(
                   EXPAND(
                       y,
                       e,
                       ,
                       y),
                   IF(
                       COUNTA(
                           c)<>e,
                       EXPAND(
                           b,
                           e,
                           ,
                           b),
                       c),
                   d),
               HSTACK(
                   "Total "&y,
                   "",
                   SUM(
               d))))))
Excel solution 6 for Pivoting Data, proposed by Asheesh Pahwa:
=VSTACK(B2:D2,
   DROP(REDUCE("",
   SEQUENCE(
       4),
    LAMBDA(x,
   y,
   VSTACK(x,
   LET(I,
   INDEX(
       B3:D7,
       y,
       ),
   
f,
   IFNA(DROP(REDUCE("",
   
SEQUENCE (COLUMNS(
   I)),
    LAMBDA(a,
   v,
   HSTACK(a,
   LET(t,
   INDEX(
       I,
       ,
       v),
    DROP(REDUCE("",
   t,
   LAMBDA (ac,
   it,
    VSTACK(
        ac,
         TEXTSPLIT(
             it,
             ,
             {", ",
             ","})))),
   1))))),
   ,
   1),
   0),
    ff,
    IF(
        f=0,
        INDEX(
            f,
            1,
            ),
         f),
   VSTACK(ff,
   HSTACK ("Total "&TAKE(
       ff,
       1,
       1),
   "",
   SUM(
       --TAKE(
           ff,
           ,
           -1)))))))),
   1))
Excel solution 7 for Pivoting Data, proposed by Burhan Cesur:
=REDUCE(
   tblSales[
   hashtag
   #Headers],
   SEQUENCE(
       ROWS(
           tblSales[Sales])),
   LAMBDA(
       s,
       v,
       LET(
           f,
           LAMBDA(
               x,
               --TRIM(
                   TEXTSPLIT(
                       INDEX(
                           tblSales[Sales],
                           x,
                           1),
                       ,
                       ","))),
           VSTACK(
               s,
               HSTACK(
                   EXPAND(
                       INDEX(
                           tblSales[Month],
                           v,
                           1),
                       ROWS(
                           f(
                               v)),
                       ,
                       INDEX(
                           tblSales[Month],
                           v,
                           1)),
                   LET(
                       e,
                       TEXTSPLIT(
                           INDEX(
                               tblSales[Customers],
                               v,
                               1),
                           ,
                           ","),
                       r,
                       ROWS(
                           f(
                               v)),
                       IF(
                           AND(
                               ROWS(
                                   e)

Solving the challenge of Pivoting Data with R

R solution 1 for Pivoting Data, proposed by Anil Kumar Goyal:
#tidyverse solution
library(readxl)
library(janitor)
library(tidyverse)
df <- read_xlsx("Others/Easy Excel Challenge 28th April.xlsx", range = "B2:D6")
df |> 
 group_by(Month) |> 
 group_split(.keep = TRUE) |> 
 map_dfr(~ .x |> 
 separate_rows(-Month, convert = TRUE) |> 
 adorn_totals(name = paste("Total", first(.$Month))))

Leave a Reply