Appreciate any pointers to the below output that want. I know I need to do some form of recursion but sure how to do that exactly.
I have the following code
>> start of code
# BOM data
library("dplyr")
library(igraph)
text1 <- ("
matnr,comp
FG1,SA1
FG1,SA2
SA1,SA3
SA1,SA4
SA1,SA5
SA5,SA6
FG2,SA1
FG2,SA8
SA8,SA9
SA9,SA10
SA9,SA11")
df1 <- read.table(textConnection(text1), header = TRUE, stringsAsFactors=FALSE, strip.white = TRUE, sep=",")
head(df1)
net <- graph_from_data_frame(df1)
net
neighbors_FG1 <- neighbors(net, v=c("FG1"), mode=c("out"))
neighbors_FG1
neighbors_FG2 <- neighbors(net, v=c("FG2"), mode=c("out"))
neighbors_FG2
neighbors_SA1 <- neighbors(net, v=c("SA1"), mode=c("out"))
neighbors_SA1
>> end of code
I want to be able to produce a data frame like below. I would think that this will need some sort of recursion and I would like to get help with this. If you can even help me with how I can get to the output below, that will be great.
FG,level,material,Comp
FG1,1,FG1,SA1
FG1,1,FG1,SA2
FG1,2,SA1,SA3
FG1,2,SA1,SA4
FG1,2,SA1,SA5
FG1,3,SA5,SA6
FG2,1,FG2,SA1
FG2,1,FG2,SA8
FG2,2,SA8,SA9
Here is an igraph option
lst <- lapply(
names(V(net))[degree(net, mode = "in") == 0],
function(x) {
d <- Filter(
is.finite,
setNames(
c(distances(net, x, mode = "out") + 1),
names(V(net))
)
)
cbind(
FG = x,
merge(
setNames(get.data.frame(
induced_subgraph(
net,
names(d)
)
), c("matnr", "comp")),
setNames(
rev(stack(d)),
c("matnr", "lvl")
)
)
)
}
)
res <- `row.names<-`(
subset(
do.call(rbind, lst),
ave(seq_along(matnr), matnr, comp, lvl, FUN = seq_along) == 1
), NULL
)
which gives
> res
FG matnr comp lvl
1 FG1 FG1 SA1 1
2 FG1 FG1 SA2 1
3 FG1 SA1 SA3 2
4 FG1 SA1 SA4 2
5 FG1 SA1 SA5 2
6 FG1 SA5 SA6 3
7 FG2 FG2 SA1 1
8 FG2 FG2 SA8 1
9 FG2 SA8 SA9 2
10 FG2 SA9 SA10 3
11 FG2 SA9 SA11 3
I use tidyverse, igraph and tidygraph to solve this question:
net so that it can be manipulated by the TidyGraph packagegr <- as_tbl_graph(net)
name_vector <- gr %>%
activate(nodes) %>%
as_tibble() %>%
as_vector()
start_node = 1 # The first node is FG1
temp <- gr %>%
activate(nodes) %>%
mutate(
# Get the nodes from which each node is visited in a breath first search
material = bfs_parent(root = start_node),
# Get the succession in which the nodes are visited in a depth first search
level = bfs_dist(root = start_node)) %>%
as_tibble() %>%
drop_na() %>%
rename(Comp = name)
temp <- temp %>%
mutate(FG = name_vector[start_node],
material = name_vector[material])
And that's the result:
> temp %>% arrange(level)
# A tibble: 6 x 4
Comp material level FG
<chr> <chr> <int> <chr>
1 SA1 FG1 1 FG1
2 SA2 FG1 1 FG1
3 SA5 SA1 2 FG1
4 SA3 SA1 2 FG1
5 SA4 SA1 2 FG1
6 SA6 SA5 3 FG1
Based on the code above, We found all the cases where start_node = 1.
You can use loops to redefine the start_node and combine these results together.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With