sfnetworks icon indicating copy to clipboard operation
sfnetworks copied to clipboard

Edges does not follow right directions

Open latot opened this issue 7 months ago • 2 comments

Describe the bug Imagine you have two nodes,

  1. (0, 1)
  2. (0, 2)

And you have an edge with them, for now it will be not directed.

It is possible for sfnetworks to have a edge of this type:

From 1 to 2 with a linestring (0, 2) to (0, 1) which does not follow the right nodes direction.

Reproducible example

If you compare on roxel network, there is a edge from node 1 to 27 where the first point of the vector is from node 27 instead of node 1.

network <- local({
    network <- sfnetworks::roxel
    network$weight <- sf::st_distance(sf::st_geometry(network))[1,]
    
    network %.>%
    sfnetworks::as_sfnetwork(., directed = FALSE)
})

#Get edge
edge <- network %.>%
sfnetworks::activate(., "edges") %.>%
sf::st_as_sf(.) %.>%
dplyr::filter(., .data$from == 1, .data$to == 27) %.>%
sf::st_geometry(.)[[1]]

#Get start node
node_1 <- network %.>%
sfnetworks::activate(., "nodes") %.>%
sf::st_as_sf(.) %.>%
dplyr::mutate(., id = dplyr::row_number(.)) %.>%
dplyr::filter(., .data$id == 1) %.>%
sf::st_geometry(.)[[1]]

#Get end node
node_27 <- network %.>%
sfnetworks::activate(., "nodes") %.>%
sf::st_as_sf(.) %.>%
dplyr::mutate(., id = dplyr::row_number(.)) %.>%
dplyr::filter(., .data$id == 27) %.>%
sf::st_geometry(.)[[1]]

edge
node_1
node_27

Expected behavior If the edge declares from node X to node Y, the path should start with the node X and end with the node Y.

R Session Info

R version 4.3.2 (2023-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Gentoo Linux

Matrix products: default
BLAS:   /usr/lib64/libblas.so.3.11.0 
LAPACK: /usr/lib64/liblapack.so.3.11.0

locale:
 [1] LC_CTYPE=es_CL.utf8       LC_NUMERIC=C             
 [3] LC_TIME=es_CL.utf8        LC_COLLATE=es_CL.utf8    
 [5] LC_MONETARY=es_CL.utf8    LC_MESSAGES=es_CL.utf8   
 [7] LC_PAPER=es_CL.utf8       LC_NAME=C                
 [9] LC_ADDRESS=C              LC_TELEPHONE=C           
[11] LC_MEASUREMENT=es_CL.utf8 LC_IDENTIFICATION=C      

time zone: Chile/Continental
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] typed_0.0.1    testthat_3.2.0 wrapr_2.1.0    sf_1.0-14     

loaded via a namespace (and not attached):
 [1] crayon_1.5.2       vctrs_0.6.4        sfnetworks_0.6.3   cli_3.6.1         
 [5] rlang_1.1.2        DBI_1.1.3          KernSmooth_2.23-22 purrr_1.0.2       
 [9] generics_0.1.3     glue_1.6.2         lwgeom_0.2-13      e1071_1.7-13      
[13] brio_1.1.3         fansi_1.0.5        sfheaders_0.4.3    grid_4.3.2        
[17] classInt_0.4-10    tibble_3.2.1       lifecycle_1.0.4    compiler_4.3.2    
[21] igraph_1.5.1       dplyr_1.1.4        Rcpp_1.0.11        pkgconfig_2.0.3   
[25] tidyr_1.3.0        wk_0.9.0           R6_2.5.1           class_7.3-22      
[29] tidyselect_1.2.0   utf8_1.2.4         pillar_1.9.0       magrittr_2.0.3    
[33] tidygraph_1.2.3    tools_4.3.2        proxy_0.4-27       s2_1.1.4          
[37] units_0.8-4       

Thx!

latot avatar Nov 20 '23 20:11 latot

This is expected behaviour. In undirected networks igraph/tidygraph will always let the node with the lowest ID be the "from" node. Given that "from" and "to" does not have any meaning in undirected networks, we decided not to reverse the edge linestrings in cases where the endpoint of the line has a lower node ID than the startpoint. Having said that, I am considering changing that behaviour, and actually reverse the linestrings such that the "from" node will always equal the startpoint of the line, since it currently complicates code in some functions

luukvdmeer avatar Nov 21 '23 15:11 luukvdmeer

:O Good to know, personally complicates other codes too, when you work with directed lines you need the line in the right direction for example, to create a particular directed line.

latot avatar Nov 21 '23 15:11 latot