简体   繁体   中英

Finding the minimum distances/levels between nodes in a graph like dataframe in R

I have some graph data stored in a data.table that describe the transitions between some nodes such as:

lfs = data.table( from = c(NA, 'x', 'x', 'y'), to = c('x', 'y', 'p', 'z'), level = 0)
lfs
#  from to level
#:   NA  x     0
#:    x  y     0
#:    x  p     0
#:    y  z     0

I want to find the distance of each node from the start node NA . The expected result is as follows:

#  from to level
#:   NA  x     1
#:    x  y     2
#:    x  p     2
#:    y  z     3

I can solve this problem in a very cumbersome way as follows:

lfs[ is.na(lfs$from) ]$level = 1
target = lfs$from %in% (lfs[ lfs$level == 1 ]$to) 
lfs[target]$level = 2
target = lfs$from %in% (lfs[ lfs$level == 2 ]$to) 
lfs[target]$level = 3

I guess there should be easier and more generic solutions most probably by using graph manipulation functions in graph libraries such as igraph but I don't know them very well and I don't know what to search for in these libraries specifically.

How can I get the expected output using graph algorithms or do you think of any other easier solutions?

You can use the igraph package to calculate the distances

library(igraph)

lfs = data.frame( from = c('start', 'x', 'x', 'y'), 
                  to = c('x', 'y', 'p', 'z'), 
                  level = 0)

# create graph from data.frame
g <- graph_from_data_frame(lfs)

# find distances from chosen node
distances(g, "start")
#      start x y p z
#start     0 1 2 2 3

If we assume that each unique value in from is already present in a previous row in column to (except "start" ) - and the data is ordered the way you describe it - we could simply convert the form column to numeric to attain the expected output.

lfs$level <- as.numeric(as.factor(lfs$from))
> lfs
#   from to level
#1 start  x     1  first 'from' value cannot be NA though
#2     x  y     2
#3     x  p     2
#4     y  z     3

We can use rleid from data.table

library(data.table)
lfs[, levels := rleid(from)]
lfs
#   from to level levels
#1:   NA  x     0      1
#2:    x  y     0      2
#3:    x  p     0      2
#4:    y  z     0      3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM