Home » Hierarchical Structure!

Hierarchical Structure!

Solving Hierarchical Structure challenge by Power Query, Power BI, Excel, Python and R

In the question table, parents and their children with different IDs are listed. Based on this table, generate a code for each ID. Assuming the code for parent A is “1,” the codes for its children should be numbered as “1-1,” “1-2,” and “1-3,” respectively.

📌 Challenge Details and Links
Challenge Number: 180
Challenge Difficulty: ⭐⭐⭐⭐
📥Download Sample File
📥Link to the solutions on LinkedIn

Solving the challenge of Hierarchical Structure! with Power Query

Power Query solution 1 for Hierarchical Structure!, proposed by Kris Jaganah:
let
  A = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  B = Table.ToColumns(A), 
  C = [Code = "1", IDs = B{0}{0}], 
  D = List.Transform(
    List.Zip({B{0}, List.Positions(B{0})}), 
    each {B{0}{_{1}}, B{1}{_{1}}, Text.From(_{1} - List.PositionOf(B{0}, _{0}) + 1)}
  ), 
  E = List.Accumulate(
    {0 .. 4}, 
    D, 
    (x, y) =>
      List.Transform(
        x, 
        each {
          _{0}, 
          _{1}, 
          _{2}, 
          if _{0} = C[IDs] then
            C[Code] & "-" & _{2}
          else
            List.Last(x{List.PositionOf(List.Zip(x){1}, _{0})}) & "-" & _{2}
        }
      )
  ), 
  F = Table.FromRecords({C} & List.Transform(E, each [Code = _{3}, IDs = _{1}]))
in
  F
Power Query solution 2 for Hierarchical Structure!, proposed by Seokho MOON:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Group = Table.Group(Source, "Parent", {"tbl", each Table.AddIndexColumn(_, "Idx", 1)})[tbl], 
  Rec = List.Accumulate(
    Table.ToRows(Table.Combine(Group)), 
    [A = "1"], 
    (a, v) => Record.AddField(a, v{1}, Record.Field(a, v{0}) & "-" & Text.From(v{2}))
  ), 
  Res = Table.FromColumns({Record.ToList(Rec), Record.FieldNames(Rec)}, {"Code", "IDs"})
in
  Res
Power Query solution 3 for Hierarchical Structure!, proposed by Vida Vaitkunaite:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Group = Table.Group(
    Source, 
    {"Parent"}, 
    {{"All", each Table.RenameColumns(Table.AddIndexColumn(_, "Index", 1, 1), {{"Child", "IDs"}})}}
  ), 
  Reverse = Table.ReverseRows(
    Table.TransformColumnTypes(Table.Combine(Group[All]), {{"Index", type text}})
  ), 
  Replacements = {{"A", "1"}} & List.Zip({Reverse[IDs]} & {Reverse[Index]}), 
  Accumulate = Table.AddColumn(
    Reverse, 
    "Code", 
    each Text.Combine(
      List.ReplaceMatchingItems(
        Text.ToList(
          Text.Reverse(
            List.Accumulate(
              {0 .. List.Count(Reverse[IDs]) - 1}, 
              [IDs] & [Parent], 
              (Text, No) =>
                Text.Combine(
                  List.Distinct(
                    Text.ToList(
                      Text.Replace(Text, Reverse[IDs]{No}, Reverse[IDs]{No} & Reverse[Parent]{No})
                    )
                  )
                )
            )
          )
        ), 
        Replacements
      ), 
      "-"
    )
  ), 
  Selected = Table.SelectColumns(Accumulate, {"Code", "IDs"}), 
  Reverse2 = Table.ReverseRows(Selected), 
  Final = Table.InsertRows(Reverse2, 0, {[IDs = "A", Code = "1"]})
in
  Final

Solving the challenge of Hierarchical Structure! with Excel

Excel solution 1 for Hierarchical Structure!, proposed by Bo Rydobon 🇹🇭:
=SORT(
    REDUCE(
        HSTACK(
            B3,
            1
        ),
        C3:C13,
        LAMBDA(
            a,
            v,
            LET(
                x,
                TAKE(
                    B3:v,
                    ,
                    1
                ),
                p,
                TAKE(
                    x,
                    -1
                ),
                VSTACK(
                    a,
                    HSTACK(
                        v,
                        VLOOKUP(
                            p,
                            a,
                            2,
                            
                        )&-COUNTIF(
                            x,
                            p
                        )
                    )
                )
            )
        )
    ),
    ,
    ,
    1
)
Excel solution 2 for Hierarchical Structure!, proposed by Oscar Mendez Roca Farell:
=SORT(
    REDUCE(
        HSTACK(
            B3,
            1
        ),
        B3:B13,
        LAMBDA(
            i,
            x,
            LET(
                c,
                OFFSET(
                    x,
                    ,
                    1
                ),
                VSTACK(
                    i,
                    HSTACK(
                        c,
                        VLOOKUP(
                            XLOOKUP(
                                c,
                                C3:C13,
                                B3:B13
                            ),
                            i,
                            2,
                            
                        )&-COUNTIF(
                            B3:x,
                            x
                        )
                    )
                )
            )
        )
    ),
    ,
    ,
    1
)
Excel solution 3 for Hierarchical Structure!, proposed by Kris Jaganah:
=LET(
    a,
    "A"&","&1,
    b,
    B3:B13,
    c,
    MAP(
        b,
        LAMBDA(
            x,
            COUNTIF(
                B3:x,
                x
            )
        )
    ),
    d,
    TEXTSPLIT(
        CONCAT(
            VSTACK(
                a,
                SCAN(
                    a,
                    SEQUENCE(
                        5
                    ),
                    LAMBDA(
                        x,
                        y,
                        TEXTJOIN(
                            "#",
                            ,
                            MAP(
                                TEXTSPLIT(
                                    x,
                                    ,
                                    "#",
                                    1
                                ),
                                LAMBDA(
                                    w,
                                    TEXTJOIN(
                                        "#",
                                        ,
                                        FILTER(
                                            C3:C13&","&TEXTAFTER(
                                                w,
                                                ","
                                            )&"-"&c,
                                            b=LEFT(
                                                w
                                            ),
                                            ""
                                        )
                                    )
                                )
                            )
                        )
                    )
                )
            )&"*"
        ),
        ",",
        {"#",
        "*"},
        1
    ),
    VSTACK(
        {"Code",
        "IDs"},
        HSTACK(
            TAKE(
                d,
                ,
                -1
            ),
            TAKE(
                d,
                ,
                1
            )
        )
    )
)
Excel solution 4 for Hierarchical Structure!, proposed by Kris Jaganah:
=LET(
    a,
    B3:B13,
    b,
    REDUCE(
        {"A",
        1},
        SEQUENCE(
            20
        ),
        LAMBDA(
            x,
            y,
            VSTACK(
                x,
                FILTER(
                    HSTACK(
                        C3:C13,
                        INDEX(
                            x,
                            y,
                            2
                        )&"-"&MAP(
                            a,
                            LAMBDA(
                                x,
                                COUNTIF(
                                    B3:x,
                                    x
                                )
                            )
                        )
                    ),
                    a=INDEX(
                        x,
                        y,
                        1
                    ),
                    ""
                )
            )
        )
    ),
    c,
    TAKE(
        b,
        ,
        1
    ),
    HSTACK(
        TOCOL(
            TAKE(
                b,
                ,
                -1
            ),
            3
        ),
        FILTER(
            c,
            c<>""
        )
    )
)
Excel solution 5 for Hierarchical Structure!, proposed by Hussein SATOUR:
=LET(
    V,
    VSTACK,
    X,
    XLOOKUP,
    I,
    INDEX,
    W,
    XMATCH,
    t,
    V(
        {"",
        "A"},
        SORT(
            B3:C13,
            1,
            1,
            2
        )
    ),
    a,
    I(
        t,
        ,
        2
    ),
    b,
    I(
        t,
        ,
        1
    ),
    HSTACK(
        REDUCE(
            1,
            DROP(
                a,
                1
            ),
            LAMBDA(
                y,
                z,
                LET(
                    c,
                    X(
                        z,
                        a,
                        b
                    ),
                    d,
                    FILTER(
                        t,
                        b=c
                    ),
                    e,
                    W(
                        z,
                        TAKE(
                            d,
                            ,
                            -1
                        )
                    ),
                    f,
                    W(
                        z,
                        a
                    ),
                    g,
                    X(
                        c,
                        TAKE(
                            a,
                            f-1
                        ),
                        y
                    ),
                    V(
                        y,
                        g&"-"&e
                    )
                )
            )
        ),
        a
    )
)
Excel solution 6 for Hierarchical Structure!, proposed by Pieter de B.:
=LET(
    p,
    B3:B13,
    c,
    C3:C13,
    SORTBY(
        REDUCE(
            HSTACK(
                @+p,
                "1"
            ),
            c,
            LAMBDA(
                a,
                b,
                LET(
                    d,
                    XLOOKUP(
                        b,
                        c,
                        p
                    ),
                    VSTACK(
                        a,
                        HSTACK(
                            b,
                            VLOOKUP(
                                d,
                                a,
                                2,
                                
                            )&-XMATCH(
                                b,
                                FILTER(
                                    c,
                                    p=d
                                )
                            )
                        )
                    )
                )
            )
        ),
        {2,
        1}
    )
)
Excel solution 7 for Hierarchical Structure!, proposed by Pieter de B.:
=LET(
    p,
    B3:B13,
    c,
    C3:C13,
    REDUCE(
        HSTACK(
            "1",
            @+p
        ),
        c,
        LAMBDA(
            a,
            b,
            LET(
                d,
                XLOOKUP(
                        b,
                        c,
                        p
                    ),
                VSTACK(
                    a,
                    HSTACK(
                        XLOOKUP(
                            d,
                            DROP(
                                a,
                                ,
                                1
                            ),
                            TAKE(
                                a,
                                ,
                                1
                            )
                        )&-XMATCH(
                                b,
                                FILTER(
                                    c,
                                    p=d
                                )
                            ),
                        b
                    )
                )
            )
        )
    )
)
Excel solution 8 for Hierarchical Structure!, proposed by Seokho MOON:
=LET(
 data,
     B3:C13, num_rows,
     ROWS(
         data
     ), initial_entry,
     {"",
     "1",
     "A"}, Func,
     LAMBDA(a,
     v, LET(
 parent,
     INDEX(
         data,
          v,
          1
     ), child,
     INDEX(
         data,
          v,
          2
     ), parent_code,
     INDEX(
         a,
          MATCH(
              parent,
               INDEX(
                   a,
                    ,
                    3
               ),
               0
          ),
          2
     ), child_code,
     parent_code & "-" &
 SUM(--(parent = INDEX(
     a,
      ,
      1
 ))) + 1, new_entry,
     HSTACK(
         parent,
          child_code,
          child
     ), VSTACK(
     a,
      new_entry
 )
 )
 ), res,
     REDUCE(
         initial_entry,
          SEQUENCE(
              num_rows
          ),
          Func
     ), DROP(
     res,
      ,
      1
 )
)

Solving the challenge of Hierarchical Structure! with Python in Excel

Python in Excel solution 1 for Hierarchical Structure!, proposed by Alejandro Campos:
df = xl("B2:C13", headers=True)

def generate_codes(df):
 codes, counter = {"A": "1"}, {}
 for _, row in df.iterrows():
 parent, child = row['Parent'], row['Child']
 counter[parent] = counter.get(parent, 0) + 1
 codes[child] = f"{codes[parent]}-{counter[parent]}"
 return pd.DataFrame(list(codes.items()), columns=["IDs", "Code"])[["Code", "IDs"]].reset_index(drop=True)

generate_codes(df)
Python in Excel solution 2 for Hierarchical Structure!, proposed by Seokho MOON:
df = xl("Table1[
hashtag
#All]", headers=True)
res = {"A": ["1", None]}
for parent, child in df.itertuples(index=False):
 parent_value = res[parent][0]
 serial_number = sum(1 for k, v in res.items() if v[1] == parent) + 1
 res[child] = [f"{parent_value}-{serial_number}", parent]
res_df = pd.DataFrame([(v[0], k) for k, v in res.items()], columns=["Code", "IDs"])
res_df

Solving the challenge of Hierarchical Structure! with R

R solution 1 for Hierarchical Structure!, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
library(igraph)
path <- "files/CH-180 Hierarchical Structure.xlsx"
input <- read_excel(path, range = "B2:C13")
test <- read_excel(path, range = "E2:F14") %>% arrange(Code)
in2 <- input %>% mutate(code = row_number(), .by = Parent)
g <- graph_from_data_frame(in2, directed = TRUE)
all_paths <- all_simple_paths(g, from = "A", to = V(g))
df <- map_df(all_paths, ~ data.frame(paths = paste(names(.x), collapse = "-")))
result <- df %>%
 mutate(IDs = str_extract(paths, "\w$"), rn = row_number()) %>%
 mutate(path = str_replace_all(paths, "\d", ~ in2$code[as.numeric(.x)])) %>%
 separate_rows(paths, sep = "-") %>%
 left_join(in2 %>% add_row(Parent = NA, Child = "A", code = 1), by = c("paths" = "Child")) %>%
 summarise(Code = paste0(code, collapse = "-"), .by = IDs) %>%
 select(Code, IDs) %>%
 add_row(Code = "1", IDs = "A") %>%
 arrange(Code)
all.equal(result, test, check.attributes = FALSE)
# [1] TRUE

Solving the challenge of Hierarchical Structure! with Google Sheets

Google Sheets solution 1 for Hierarchical Structure!, proposed by Peter Krkos:
PowerQuery solution:
https://docs.google.com/spreadsheets/d/1zR5IZLz8OT76vhaPEHfsPrw8-RDKnLyyqS49IJjdhFk/edit?pli=1&gid=911883962#gid=911883962

Leave a Reply