Graphml 到 R 中的 Sf 对象

Graphml to Sf object in R

我正在尝试将 graphml 文件的节点转换为 R 中的 sf 对象。在我创建 sfc 对象之前它一直有效。一旦我添加了属性,R 就无法再对其进行绘图或进行任何操作。

library(igraph)
library(sf)

#read the graph
gi <- read.graph(
 "https://jospueyo.github.io/root/girona.graphml",
  format = "graphml")

#Extract coordinates and create id vector
x <- as.numeric(V(gi)$x)
y <- as.numeric(V(gi)$y)
id <- as.data.frame(seq(1:length(V(gi))))
 
#convert to sf object
nodes <- st_multipoint(cbind(x,y))
nodes <- st_sfc(nodes, crs=4326)
nodes <- st_sf(id, geometry = nodes)

#here it crashes
plot(st_geometry(nodes))

我尝试了不同的图表,通过不同的方法获得,我得到了相同的结果。

谢谢。

错误是因为 st_multipoint 创建了一个包含所有点的几何体,所以当我使用 length:6000 的向量作为属性创建 sf 对象时,它强制重复 6000 次6000 点 6000 的相同几何形状,导致 36.000.000 点的对象在 6.000 个位置重叠。下面是在 sf 对象中转换图的节点的解决方案:

library(igraph)
library(sf)

#read the graph
gi <- read.graph(
 "https://jospueyo.github.io/root/girona.graphml",
  format = "graphml")

#Extract coordinates and create id vector
x <- as.numeric(V(gi)$x)
y <- as.numeric(V(gi)$y)
id <- as.data.frame(seq(1:length(V(gi))))
colnames(id) <- "id"
 
#create the first sfc object
xi <- x[1]
yi <- y[1]
xyi <- cbind(xi,yi)
nodei <- st_point(xyi)
node_sfc <- st_sfc(nodei)

#add a new sfc for each pair of coordinates
for (i in 2:length(V(gi))){
  xi <- x[i]
  yi <- y[i]
  xyi <- cbind(xi,yi)
  nodei <- st_point(xyi)
  node_sfci <- st_sfc(nodei)
  node_sfc <- c(node_sfc, node_sfci)
  print(i)
}

#create sf object
st_crs(node_sfc) <- 4326
nodes <- st_sf(id, geometry = node_sfc)

我希望它能防止其他人犯与我相同的愚蠢错误。

另一种解决方案是使用 tidygraph 作为中介将数据转换为可以更轻松地传递给 sf:

的 tibble 结构
library(igraph)
library(sf)
library(tidygraph)

gi <- read_graph(
  "https://jospueyo.github.io/root/girona.graphml",
  format = "graphml")

(nodes <- as_tbl_graph(gi) %>% 
  activate("nodes") %>% 
  as_tibble() %>% 
  st_as_sf(coords = c('x', 'y'), crs = 4326))
#> Simple feature collection with 6362 features and 4 fields
#> geometry type:  POINT
#> dimension:      XY
#> bbox:           xmin: 2.786515 ymin: 41.93955 xmax: 2.895689 ymax: 42.02881
#> geographic CRS: WGS 84
#> # A tibble: 6,362 x 5
#>    ref   highway osmid      id                    geometry
#>  * <chr> <chr>   <chr>      <chr>              <POINT [°]>
#>  1 ""    ""      2818883585 2818883585 (2.810092 41.97531)
#>  2 ""    ""      772161540  772161540   (2.814935 41.9714)
#>  3 ""    ""      2818883588 2818883588  (2.80979 41.97537)
#>  4 ""    ""      2818883590 2818883590 (2.810225 41.97548)
#>  5 ""    ""      772177927  772177927  (2.830774 41.98178)
#>  6 ""    ""      772227076  772227076  (2.850591 41.96948)
#>  7 ""    ""      1622622216 1622622216  (2.80656 41.96506)
#>  8 ""    ""      2818883593 2818883593 (2.809976 41.97563)
#>  9 ""    ""      800522251  800522251  (2.828536 41.98674)
#> 10 ""    ""      2818883592 2818883592 (2.810574 41.97554)
#> # ... with 6,352 more rows

plot(st_geometry(nodes))