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))
我正在尝试将 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
:
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))