4

I have an organisational structure expressed as a tree.

library(data.tree)
library(dplyr)
    
df <-
  data.frame(
    from = c(
      'BIG CORP Inc.',
      'BIG CORP Inc.',
      'BIG CORP Inc.',
      'ABC Inc.',
      'ABC Inc.',
      'Subsidiary 1',
      'Subsidiary 1',
      'Subsidiary 2',
      'Subsidiary 2',
      'BCD Inc.',
      'CDE Inc.'
    ),
    to   = c(
      'ABC Inc.',
      'BCD Inc.',
      'CDE Inc.',
      'Subsidiary 1',
      'Subsidiary 2',
      'Subsidiary 3',
      'Subsidiary 4',
      'Subsidiary 4',
      'Subsidiary 3',
      'Subsidiary 4',
      'Subsidiary 4'
    ),
    ownership = c(1, 1, 1, 1, 0.5, 0.5, 0.25, 0.25, 0.5, 0.25, 0.25),
    cost = c(0, 100, 100, 100, 100, 100, 100, 100, 100 , 500, 500)
  )

org_str1 <- FromDataFrameNetwork(df)

print(org_str1, "ownership", "cost", "exposure" , "level")

If you note, the relationship in the tree is that one child can have many parents. As you can see in the image below, Subsidiary 4 sits under 4 unique underlying branches. Similarly Subsidiary 3 sits on 2 unique branches.

Tree Structure

How can I summarize my tree so that wherever a child sits on multiple branches I can view that child under the earliest common ancestor.

So for example Subsidiary 4 would need to sit under BIG CORP as that is the first common ancestor of all branches with Subsidiary 4 in it. Similarly Subsidiary 3 should report directly under ABC Inc.

ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
Alex Bădoi
  • 830
  • 2
  • 9
  • 24

1 Answers1

0

I think you can try mst to prune the network into a tree after adding the shortcuts from leaf to root, e.g.,

library(igraph)
library(data.tree)

# graph object
g <- df %>%
    graph_from_data_frame()

# leaf nodes
e <- V(g)[degree(g, mode = "out") == 0]
# root node
b <- V(g)[degree(g, mode = "in") == 0]

# shortcuts from leaf to root
ps <- lapply(
    e,
    \(x) rev(Reduce(
        intersect,
        all_simple_paths(g, x, b, mode = "in")
    ))
)

# add shortcuts and then prune the network into a tree (using `mst`)
Reduce(\(graph, p) graph + path(p), ps, g) %>%
    simplify() %>%
    mst() %>%
    as_data_frame() %>%
    FromDataFrameNetwork()

and you will obtain

1 BIG CORP Inc.
2  ¦--ABC Inc.
3  ¦   ¦--Subsidiary 1
4  ¦   ¦--Subsidiary 2
5  ¦   °--Subsidiary 3
6  ¦--BCD Inc.
7  ¦--CDE Inc.
8  °--Subsidiary 4
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81