Home » Map Groups to Company

Map Groups to Company

Generate result table on the basis of 2 problem tables. Sort is on Group and Company. Try making use of record functions as much as possible to solve this Power Query problem. This is not a complex problem but I want to encourage those people who have not been using record functions to apply record functions wherever possible.

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

Solving the challenge of Map Groups to Company with Power Query

Power Query solution 1 for Map Groups to Company, proposed by Bo Rydobon 🇹🇭:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table2"]}[Content], 
  Ans = Table.ExpandTableColumn(
    Table.TransformColumns(
      Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
      {
        "Company", 
        each Table.Join(
          Table.FromRows(
            List.Transform(
              Text.SplitAny(_, ";,"), 
              each List.Transform(Text.Split(_, ":"), each try Number.From(_) otherwise Text.Trim(_))
            ), 
            {"ID", "Company"}
          ), 
          "Company", 
          Source, 
          "Company"
        )
      }
    ), 
    "Company", 
    {"ID", "Company", "Price"}
  )
in
  Ans
Power Query solution 2 for Map Groups to Company, proposed by Zoran Milokanović:
let
  Source = each Excel.CurrentWorkbook(){[Name = _]}[Content], 
  T1 = Source("Table1"), 
  T2 = Source("Table2"), 
  H = Table.ColumnNames, 
  S = Table.Sort(
    Table.FromRows(
      List.TransformMany(
        Table.ToRows(T1), 
        (i) =>
          List.Split(
            List.Transform(Splitter.SplitTextByAnyDelimiter({",", ":", ";"}, 1)(i{1}), Text.Trim), 
            2
          ), 
        (i, o) => {i{0}} & o & {T2{[Company = o{1}]}[Price]}
      ), 
      {H(T1){0}, "ID"} & H(T2)
    ), 
    H(T1)
  )
in
  S
Power Query solution 3 for Map Groups to Company, proposed by Zoran Milokanović:
let
  Source = each Excel.CurrentWorkbook(){[Name = _]}[Content], 
  T1 = Source("Table1"), 
  S = Table.Sort(
    Table.FromRecords(
      List.Combine(
        Table.AddColumn(
          T1, 
          "Record", 
          (r) =>
            List.Transform(
              List.Split(
                Splitter.SplitTextByAnyDelimiter({",", ":", ";"}, 1)(Record.Field(r, "Company")), 
                2
              ), 
              (m) =>
                let
                  t = Record.TransformFields(
                    Record.FromList(m, {"ID", "Company"}), 
                    {{"ID", Text.Trim}, {"Company", Text.Trim}}
                  )
                in
                  Record.RemoveFields(r, {"Company"})
                    & t
                    & Record.RemoveFields(
                      Source("Table2"){[Company = Record.Field(t, "Company")]}, 
                      "Company"
                    )
            )
        )[Record]
      )
    ), 
    Table.ColumnNames(T1)
  )
in
  S
Power Query solution 4 for Map Groups to Company, proposed by Kris Jaganah:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Expand = Table.ExpandListColumn(
    Table.TransformColumns(Source, {{"Company", Splitter.SplitTextByAnyDelimiter({":", ",", ";"})}}), 
    "Company"
  ), 
  Trim = Table.TransformColumns(
    Expand, 
    {
      "Company", 
      each 
        let
          a = Text.Trim(_), 
          b = try Number.From(a) otherwise a
        in
          b
    }
  ), 
  Idx = Table.AddIndexColumn(Trim, "Index", 1, 0.5), 
  Class = Table.AddColumn(
    Idx, 
    "Custom", 
    each if Number.Mod([Index], 1) = 0 then "ID" else "Company"
  ), 
  IdxRound = Table.TransformColumns(Class, {"Index", each Number.RoundDown(_)}), 
  Pivot = Table.Pivot(IdxRound, List.Distinct(IdxRound[Custom]), "Custom", "Company"), 
  Remove = Table.RemoveColumns(Pivot, {"Index"}), 
  Sort = Table.Sort(Remove, {{"Group", Order.Ascending}, {"Company", Order.Ascending}}), 
  Merge = Table.NestedJoin(Sort, {"Company"}, Table2, {"Company"}, "Table2", JoinKind.LeftOuter), 
  Xpand = Table.ExpandTableColumn(Merge, "Table2", {"Price"}, {"Price"})
in
  Xpand
Power Query solution 5 for Map Groups to Company, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Table.TransformColumns(
    Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
    {
      "Company", 
      each Table.Combine(
        List.Transform(
          Text.SplitAny(Text.Remove(_, " "), ";,"), 
          each Table.FromRows({Text.Split(_, ":")}, {"ID", "Company"})
        )
      )
    }
  ), 
  Xpand = Table.ExpandTableColumn(Source, "Company", {"ID", "Company"}), 
  Sol = Table.Sort(
    Table.AddColumn(
      Xpand, 
      "Custom", 
      (x) => Table.SelectRows(Table2, each [Company] = x[Company])[Price]{0}
    ), 
    {{"Group", 0}, {"Company", 0}}
  )
in
  Sol
Power Query solution 6 for Map Groups to Company, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Process = List.Transform(
    Table.ToRecords(Source), 
    each Record.TransformFields(
      _, 
      {
        "Company", 
        each 
          let
            a = Table.FromRows(
              List.Transform(Text.SplitAny(Text.Remove(_, " "), ";,"), each Text.Split(_, ":")), 
              {"ID", "Company"}
            ), 
            b = Table.AddColumn(
              a, 
              "Price", 
              (x) => List.Select(Table.ToRows(Table2), each List.Contains(_, x[Company])){0}{1}
            )
          in
            b
      }
    )
  ), 
  Groups = Table.Combine(List.Transform(Process, each Table.FromRecords({_}))), 
  Sol = Table.Sort(
    Table.ExpandTableColumn(Groups, "Company", Table.ColumnNames(Groups[Company]{0})), 
    {{"Group", 0}, {"Company", 0}}
  )
in
  Sol
Power Query solution 7 for Map Groups to Company, proposed by Luan Rodrigues:
let
  Fonte = Tabela1, 
  trf = Table.TransformColumns(
    Fonte, 
    {
      "Company", 
      each [
        a = List.Combine(
          List.TransformMany(
            {_}, 
            (o) => Text.Split(Text.Remove(o, " "), ";"), 
            (x, y) => Text.Split(y, ",")
          )
        ), 
        b = Table.Sort(
          Table.FromRows(List.Transform(a, (p) => Text.Split(p, ":")), {"ID", "Company"}), 
          {each [Company], 0}
        ), 
        c = Table.AddColumn(
          b, 
          "Price", 
          each Table.SelectRows(Tabela2, (x) => [Company] = x[Company])[Price]{0}
        )
      ][c]
    }
  ), 
  res = Table.ExpandTableColumn(trf, "Company", Table.ColumnNames(trf[Company]{0}))
in
  res
Power Query solution 8 for Map Groups to Company, proposed by Alexis Olson:
let
  T1 = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  T2 = Excel.CurrentWorkbook(){[Name = "Table2"]}[Content], 
  Split = Table.TransformColumns(
    T1, 
    {{"Company", each Text.SplitAny(Text.Remove(_, " "), ";,"), type list}}
  ), 
  ExpandToRows = Table.ExpandListColumn(Split, "Company"), 
  ToRecord = Table.TransformColumns(
    ExpandToRows, 
    {{"Company", each [ID = Text.BeforeDelimiter(_, ":"), Company = Text.AfterDelimiter(_, ":")]}}
  ), 
  ExpandToCols = Table.ExpandRecordColumn(ToRecord, "Company", {"ID", "Company"}), 
  AddPrice = Table.AddColumn(ExpandToCols, "Price", each T2{[Company = [Company]]}[Price])
in
  AddPrice
Power Query solution 9 for Map Groups to Company, proposed by Ramiro Ayala Chávez:
let
  t1 = Excel.CurrentWorkbook(){[Name = "Tabla1"]}[Content], 
  t2 = Excel.CurrentWorkbook(){[Name = "Tabla2"]}[Content], 
  a = Table.ReplaceValue(t1, ",", ";", Replacer.ReplaceText, {"Company"}), 
  b = Table.ExpandListColumn(
    Table.TransformColumns(a, {{"Company", Splitter.SplitTextByDelimiter(";")}}), 
    "Company"
  ), 
  c = Table.SplitColumn(b, "Company", Splitter.SplitTextByDelimiter(":"), {"ID", "Company"}), 
  d = Table.TransformColumns(c, {{"ID", each Text.Trim(_)}, {"Company", each Text.Trim(_)}}), 
  e = Table.AddColumn(d, "Price", each t2[Price]{List.PositionOf(t2[Company], [Company])}), 
  f = Table.Group(e, {"Group"}, {{"G", each Table.Sort(_, {{"Company", 0}})}})[[G]], 
  Sol = Table.Combine(f[G])
in
  Sol
Power Query solution 10 for Map Groups to Company, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
  S2 = Excel.CurrentWorkbook(){[Name = "T_2"]}[Content], 
  S1 = Excel.CurrentWorkbook(){[Name = "T_1"]}[Content], 
  A1 = Table.AddColumn(
    S1, 
    "C", 
    each Splitter.SplitTextByAnyDelimiter({":", ",", ";"})(Text.Remove([Company], " "))
  ), 
  A2 = Table.AddColumn(
    A1, 
    "C1", 
    each Table.FromColumns(
      {List.Alternate([C], 1, 1, 1), List.Alternate([C], 1, 1)}, 
      {"ID", "Company"}
    )
  ), 
  R = Table.SelectColumns(A2, {"Group", "C1"}), 
  E = Table.ExpandTableColumn(R, "C1", {"Company", "ID"}, {"Company", "ID"}), 
  A3 = Table.AddColumn(E, "C1", each Table.SelectRows(S2, (Inter) => Inter[Company] = [Company])), 
  E2 = Table.ExpandTableColumn(A3, "C1", {"Price"}, {"Price"}), 
  Re = Table.ReorderColumns(E2, {"Group", "ID", "Company", "Price"}), 
  S = Table.Sort(Re, {{"Group", Order.Ascending}, {"Company", Order.Ascending}})
in
  S
Power Query solution 11 for Map Groups to Company, proposed by Rafael González B.:
let
 Source= Excel.Workbook(File.Contents("FileRoute"), null, true),
 Groups_Table = Source{[Item="Groups",Kind="Table"]}[Data],
 Prices_Table = Source{[Item="Prices",Kind="Table"]}[Data],

 TTR = Table.ToRecords(Groups_Table),
 RT = List.Transform(TTR, each 
 Record.TransformFields(_, {"Company", (x) => 
 let
 aa = Text.Remove(x, {" "}),
 a = Text.SplitAny(aa, ",;"),
 b = List.Transform(a, each Text.Split(_, ":")),
 c = Table.FromRows(b, {"ID", "Company1"}),
 d = Table.Join(c, "Company1", Prices_Table, "Company", 1)[[ID], [Company], [Price]],
 e = Record.Field(_, "Group"),
 f = Table.AddColumn(d, "Group", each e)
 in 
 f}
 )[Company]
 )
in
 Table.Combine(RT, {"Group", "ID", "Company", "Price"})

🧙‍♂️🧙‍♂️🧙‍♂️


                    
                  
          
Power Query solution 12 for Map Groups to Company, proposed by Luke Jarych:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Split = Table.TransformColumns(
    Source, 
    {{"Company", each Text.SplitAny(Text.Remove(_, " "), ";,"), type list}}
  ), 
  ExpandColumn = Table.ExpandListColumn(Split, "Company"), 
  ToRecord = Table.TransformColumns(
    ExpandColumn, 
    {{"Company", each [ID = Text.BeforeDelimiter(_, ":"), Company = Text.AfterDelimiter(_, ":")]}}
  ), 
  ExpandedCompany = Table.ExpandRecordColumn(ToRecord, "Company", {"ID", "Company"}), 
  MergedQueries = Table.NestedJoin(
    ExpandedCompany, 
    {"Company"}, 
    Table2, 
    {"Company"}, 
    "Table2", 
    JoinKind.LeftOuter
  ), 
  ExpandedTable2 = Table.ExpandTableColumn(MergedQueries, "Table2", {"Price"}, {"Price"}), 
  Sorted = Table.Sort(ExpandedTable2, {{"Group", Order.Ascending}})
in
  Sorted
Power Query solution 13 for Map Groups to Company, proposed by Kerwin Tan CPA:
let
  Table1 = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Table2 = Excel.CurrentWorkbook(){[Name = "Table2"]}[Content], 
  Transformed = Table.Group(
    Table1, 
    {"Group"}, 
    {
      {
        "Table", 
        each 
          let
            src        = Text.SplitAny(Text.Replace([Company]{0}, " ", ""), ";,"), 
            lookupList = List.Buffer(Table2[Company]), 
            price      = List.Buffer(Table2[Price])
          in
            List.Transform(
              src, 
              each _
                & ":"
                & Text.From(price{List.PositionOf(lookupList, Text.AfterDelimiter(_, ":"))})
            )
      }
    }
  ), 
  Output = Table.SplitColumn(
    Table.ExpandListColumn(Transformed, "Table"), 
    "Table", 
    Splitter.SplitTextByDelimiter(":"), 
    {"ID", "Company", "Price"}
  )
in
  Output

Solving the challenge of Map Groups to Company with Excel

Excel solution 1 for Map Groups to Company, proposed by Bo Rydobon 🇹🇭:
=REDUCE(E1:H1,A2:A5,LAMBDA(a,g,LET(c,SORT(TEXTSPLIT(VLOOKUP(g,A2:B5,2,0),{":"," "},{";",","},1),2),
VSTACK(a,IFNA(HSTACK(g,IFERROR(--c,c),VLOOKUP(DROP(c,,1),A10:B21,2,)),g)))))
Excel solution 2 for Map Groups to Company, proposed by محمد حلمي:
=REDUCE(E1:H1,A2:A5,LAMBDA(a,b,LET(
e,TEXTSPLIT(TAKE(b:B2,-1,-1),{":",": "},{", ","; "}),
VSTACK(a,SORT(IFNA(HSTACK(b,IFERROR(--e,e),
VLOOKUP(DROP(e,,1),A9:B21,2,)),b),2,-1)))))
Excel solution 3 for Map Groups to Company, proposed by 🇰🇷 Taeyong Shin:
=LET(s,TEXTSPLIT(TEXTJOIN(";",,B2:B5),{":",": "},{";",", ","; "}),c,DROP(s,,1),SORT(HSTACK(XLOOKUP("*"&c&"*",B2:B5,A2:A5,,2),IFERROR(--s,s),VLOOKUP(c,A10:B21,2,)),{1,3}))
Excel solution 4 for Map Groups to Company, proposed by Kris Jaganah:
=LET(a,A2:A5,b,B2:B5,c,A10:A21,d,B10:B21,e,REDUCE({"ID","Company"},b,LAMBDA(x,y,VSTACK(x,TRIM(TEXTSPLIT(y,":",{",",";"}))))),f,TAKE(e,,-1),g,IFERROR(MAP(f,LAMBDA(x,FILTER(a,IFERROR(FIND(x,b),0)))),"Group"),h,HSTACK(g,e,XLOOKUP(f,c,d,"Price")),VSTACK(TAKE(h,1),SORT(DROP(h,1),{1,3},{1,1})))
Excel solution 5 for Map Groups to Company, proposed by Nikola Z Grujicic – Nikola Ž Grujičić:
=LET(k,A2:A5,l,IFNA(TEXTSPLIT(TEXTJOIN("|",,B2:B5),{",",";"},"|",TRUE),""),o, VSTACK(k&":"&INDEX(l,,1),k&":"&INDEX(l,,2),k&":"&INDEX(l,,3)),p, FILTER(o, LEN(o)>3),q, SUBSTITUTE(p," ",""),r, TEXTSPLIT(TEXTJOIN("|",,q),":","|",TRUE),u, XLOOKUP(INDEX(r,,3),A10:A21,B10:B21,,0),v, HSTACK(r, u),SORT(SORT(v,3),1))
Excel solution 6 for Map Groups to Company, proposed by Oscar Mendez Roca Farell:
=LET(_c, B2:B5,_m, TRIM(TEXTSPLIT(CONCAT(_c&";"),":",{",",";"},1)),_g, TOCOL(IFS(ISNUMBER(FIND(TAKE(_m, ,1), TOROW(_c))), TOROW(A2:A5)), 2),_p, VLOOKUP(DROP(_m, ,1), A10:B21, 2, ) ,SORT(HSTACK(_g,_m,_p), {1, 3}))
Excel solution 7 for Map Groups to Company, proposed by Duy Tùng:
=LET(a,REDUCE({"Group","ID","Company"},B2:B5,LAMBDA(x,y,VSTACK(x,IFNA(HSTACK(@+A5:y,SORT(TRIM(TEXTSPLIT(y,":",{";",","})),2)),@+A5:y)))),HSTACK(IFERROR(--a,a),VLOOKUP(TAKE(a,,-1),A9:B21,2,)))
Excel solution 8 for Map Groups to Company, proposed by Sunny Baggu:
=LET(
 _n, MAP(B2:B5, LAMBDA(x, ROWS(UNIQUE(TOCOL(SEARCH(":", x, SEQUENCE(30)), 3))))),
 _g, DROP(TEXTSPLIT(CONCAT(REPT(A2:A5 & ",", _n)), , ","), -1),
 _c, TEXTSPLIT(ARRAYTOTEXT&(B2:B5), {" : ", ":", " :", ": "}, {",", ";"}),
 _p, XLOOKUP(TAKE(_c, , -1), A10:A21, B10:B21),
 SORT(HSTACK(_g, _c, _p), {1, 3}, {1, 1})
)
Excel solution 9 for Map Groups to Company, proposed by Asheesh Pahwa:
=DROP(LET(alp, A2:A5, REDUCE("",SEQUENCE(ROWS(B2:B5)), LAMBDA(x,y, VSTACK(x, LET(a, TEXTSPLIT(INDEX(B2:B5,y),{":"," : ",": "},{"; ",", "),s,SORTBY(a, TAKE(a,,-1),1),c,TAKE(s,, 1)&"-"&INDEX(alp,y,), b,XLOOKUP(TAKE(s,,-1), A10:A21,B10:B21),HSTACK(TEXTAFTER(c,"-"),s,b)))))),1)
Excel solution 10 for Map Groups to Company, proposed by Tolga Demirci, PMP, PMI-ACP, MOS-Expert:
=LET(j;MAP(B2:B5;LAMBDA(y;TEXTJOIN(";";;MAP(TEXTSPLIT(y;;{";";","});LAMBDA(x;TEXTAFTER(x;":"))))));p;MAP(B2:B5;LAMBDA(m;TEXTJOIN(";";;SORT(TRIM(TEXTAFTER(TEXTSPLIT(m;;{";";","});":"));;1))));LET(z;TRIM(TEXTSPLIT(TEXTJOIN(";";;p);;";"));HSTACK(BYROW(TRIM(TEXTSPLIT(TEXTJOIN(";";;j);;";"));LAMBDA(z;FILTER(A2:A5;ISNUMBER(SEARCH(z;B2:B5;1)))));BYROW(z;LAMBDA(i;XLOOKUP(i;TRIM(TEXTSPLIT(TEXTJOIN(";";;j);;";"));TRIM(TEXTSPLIT(TEXTJOIN(";";;MAP(B2:B5;LAMBDA(y;TEXTJOIN(";";;MAP(TEXTSPLIT(y;;{";";","});LAMBDA(x;TEXTBEFORE(x;":")))))));;";")))));z;MAP(z;LAMBDA(s;XLOOKUP(s;A10:A21;B10:B21))))))

Solving the challenge of Map Groups to Company with Python

Python solution 1 for Map Groups to Company, proposed by Luke Jarych:
Python xlwings + pandas:
import pandas as pd
import xlwings as xw
# Read Excel workbook
wb = xw.Book(r'C:UsersLukeDownloadsRecords-filtering.xlsx')
sh = wb.sheets[0]
# Extract data from tables
df1 = sh.tables['Table1'].range.options(pd.DataFrame, header=True, index=False).value
df2 = sh.tables['Table2'].range.options(pd.DataFrame, header=True, index=False).value
# Clean and process data
df1['Company'] = df1['Company'].astype(str).str.replace('[ ]', '', regex=True)
df_expanded = df1['Company'].str.split('[,;]', expand=False).explode().str.split(':', expand=True)
df_expanded.columns = ['ID', 'Company']
result_df1 = pd.merge(df1.drop(columns=['Company']), df_expanded, left_index=True, right_index=True, how='left')
# Merge dataframes
df2['Price'] = df2['Price'].astype(int)
# Display result
solution
                    
                  

Solving the challenge of Map Groups to Company with Python in Excel

Python in Excel solution 1 for Map Groups to Company, proposed by Alejandro Campos:
df_a=xl("A1:B5",headers=True)
df_b=xl("A9:B21",headers=True)
s=lambda r:[e.strip() for e in (r.split(';') if ';' in r else r.split(','))]
d=df_a.explode('Company');d['Company']=d['Company'].apply(s);d=d.explode('Company')
d[['ID','Company']]=d['Company'].str.split(':',expand=True)
d['ID'],d['Company']=d['ID'].str.strip(),d['Company'].str.strip()
r=pd.merge(d,df_b,on='Company',how='left')[['Group','ID','Company','Price']] 
 .sort_values(['Group','Company']) 
 .set_index('Group').reset_index()
                    
                  

Solving the challenge of Map Groups to Company with R

R solution 1 for Map Groups to Company, proposed by Konrad Gryczan, PhD:
Finally woke up :D 
library(tidyverse)
library(readxl)
T1 = read_excel("PQ_Challenge_137.xlsx", range = "A1:B5")
T2 = read_excel("PQ_Challenge_137.xlsx", range = "A9:B21")
test = read_excel("PQ_Challenge_137.xlsx", range = "E1:H9")
T1_1 = T1 %>%
 separate_rows(Company, sep = ";|,") %>%
 mutate(Company = str_remove_all(Company, "[:space:]")) %>%
 separate(Company, into = c("ID","Company"),sep = ":") %>%
 mutate(ID = as.numeric(ID)) 
result = T1_1 %>%
 left_join(T2, by = "Company") %>%
 arrange(Group, Company)
                    
                  

&&

Leave a Reply