In Excel I have a data table of Paired Items that are tagged with an identifier. Essentially, named linkages.
Worksheet: Links
| Tag | Point-A | Point-B |
|---|---|---|
| Route 1 | Home | Office |
| Route 2 | Home | Grocery 1 |
| Happy Hour | Office | Bar |
| Sad Hour | Office | Dump |
| Headaches | Bar | Pharmacy |
| Sick | Bar | Dump |
| Route 3 | Office | Moms |
| Route 4 | Office | Park |
| Victory | Park | Bar |
| Discard | Park | Dump |
I want to transform this data into a grid of all points in rows and columns with the tag placed at the intersection (Much like old paper road maps with grids for city distances)
Worksheet: Grid
| A \ B | Bar | Dump | Grocery 1 | Home | Home | Moms | Office | Office | Park | Pharmacy |
|---|---|---|---|---|---|---|---|---|---|---|
| Bar | Sick | Happy Hour | Victory | Headaches | ||||||
| Dump | Sick | Sad Hour | Discard | |||||||
| Grocery 1 | Route 2 | |||||||||
| Home | Route 1 | |||||||||
| Home | Route 2 | |||||||||
| Moms | Route 3 | |||||||||
| Office | Happy Hour | Sad Hour | Route 1 | Route 3 | ||||||
| Office | Route 4 | |||||||||
| Park | Victory | Discard | Route 4 | |||||||
| Pharmacy | Headaches |
I have written the following M code for transforming, but it seems a bit wayward and overwrought. I am using bit coding of points to construct a join key, so the bitting process will probably break around 32 points.
Is there a shorter set of LETs that do the same transform to grid ?
Is there a way to create a key that is Min(Point-A,Point-B) delimited concatenation with Max(Point-A,Point-B), and thus not rely of bitting?
M code (copied from Advanced Editor)
let
LinksTable = Table.SelectRows(Excel.CurrentWorkbook(), each [Name] = "Links"),
Links = Table.RemoveColumns(Table.ExpandTableColumn(LinksTable, "Content", {"Tag", "Point-A", "Point-B"}), "Name"),
AllPoints = Table.Combine(
{ Table.SelectColumns(Table.RenameColumns(Links,{"Point-A", "Point"}), "Point"),
Table.SelectColumns(Table.RenameColumns(Links,{"Point-B", "Point"}), "Point")
}),
ThePoints = Table.Sort(Table.Distinct(AllPoints),{"Point"}),
PointsIndexed = Table.AddIndexColumn(ThePoints, "Index", 0, 1, Int64.Type),
PointsBitted = Table.RemoveColumns(Table.AddColumn(PointsIndexed, "Bit", each Number.Power(2, [Index]), Int64.Type),"Index"),
AllPairsBitted = Table.Join(
Table.RenameColumns(PointsBitted, {{"Point", "Point-A"}, {"Bit", "Bit-A"}}), {},
Table.RenameColumns(PointsBitted, {{"Point", "Point-B"}, {"Bit", "Bit-B"}}), {},
JoinKind.FullOuter
),
AllPairsKeyed = Table.RemoveColumns(
Table.AddColumn(AllPairsBitted, "BitKeyPair", each Number.BitwiseOr([#"Bit-A"],[#"Bit-B"])),
{ "Bit-A", "Bit-B"}
),
#"Links-A-Bitted" = Table.Join(
Links, "Point-A",
Table.RenameColumns(PointsBitted,{{"Point", "Point-A"}, {"Bit", "Bit-A"}}), "Point-A"
),
#"Links-AB-Bitted" = Table.Join(
#"Links-A-Bitted", "Point-B",
Table.RenameColumns(PointsBitted,{{"Point", "Point-B"}, {"Bit", "Bit-B"}}), "Point-B"
),
LinksKeyed = Table.RemoveColumns(
Table.AddColumn(#"Links-AB-Bitted", "BitKeyLink", each Number.BitwiseOr([#"Bit-A"],[#"Bit-B"])),
{ "Bit-A", "Bit-B"}
),
AllPairsTagged = Table.Sort( Table.RemoveColumns(
Table.Join(
AllPairsKeyed, "BitKeyPair",
Table.SelectColumns(LinksKeyed, {"BitKeyLink", "Tag"}), "BitKeyLink",
JoinKind.LeftOuter
),
{"BitKeyPair", "BitKeyLink"}
),
{"Point-A", "Point-B"}
),
Grid = Table.Pivot(AllPairsTagged, List.Distinct(AllPairsTagged[#"Point-B"]), "Point-B", "Tag", List.First)
in
Grid