从R中的Delaunay三角剖分生成邻接矩阵

时间:2018-06-29 00:13:33

标签: r graph geo

我有一个数据框,其坐标如下(长,长):

point lat long
1  51 31
2  52 31
3  52 30
4  56 28
5  57 29
6  53 32
7  54 35
8  52 32
9  48 30
10 49 27

我已经设法使用以下代码生成Delaunay三角剖分:

library(deldir)
vtess <- deldir(df$lat, df$long)
plot(vtess, wlines="triang", wpoints="none", number=FALSE, add=TRUE, lty=1)

我现在想做的是生成一个具有以下单元格值的邻接矩阵(10 x 10矩阵):

  1. 如果两个节点未通过Delaunay三角剖分中的边链接:单元格的值= 0
  2. 如果两个节点通过Delaunay三角剖分中的一条边链接:单元格的值=两个节点之间的地理距离(使用DistVincenty选项使用“ geosphere”包中的distm())

2 个答案:

答案 0 :(得分:2)

致OP:请注意评论;对于以后的帖子,使您的帖子和代码独立是很重要的。如果您不共享该转换代码,那么根据样本数据的转换(Delaunay三角剖分)提出问题就毫无意义。


此外,这是一个分步示例,如何根据您的规范构造邻接矩阵。为了简单起见,我在这里假设“两个节点之间的距离” 是指欧几里得距离。

  1. 让我们加载示例数据

    // Adds support for GET requests to our webhook
    app.get('/webhook', (req, res) => {
        ...
        // Responds with the challenge token from the request
        res.status(200).send(challenge);
    });
    
  2. 我们首先使用df <- read.table(text = "point lat long 1 51 31 2 52 31 3 52 30 4 56 28 5 57 29 6 53 32 7 54 35 8 52 32 9 48 30 10 49 27", header = T) 包中的deldir执行Delaunay三角剖分。

    deldir

    让我们绘制结果

    library(deldir)
    dxy <- deldir(df$lat, df$long)
    

    enter image description here

  3. 接下来,我们从Delaunay三角剖分中提取顶点

    plot(df$lat, df$long, col = "red")
    text(df$lat, df$long, df$point, cex = 0.5, col = "red", pos = 2)
    plot(dxy, wlines = "triang", wpoints = "none", add = T)
    
  4. 我们计算所有连接节点之间的欧几里得距离,并重整结果为# Extract the Delaunay vertices vert <- data.frame( id1 = dxy$delsgs$ind1, id2 = dxy$delsgs$ind2)

    data.frame

    请注意,您可以将# Construct adjacency matrix library(tidyverse) dist.eucl <- function(x, y) sqrt(sum((x - y)^2)) df.adj <- vert %>% mutate_all(funs(factor(., levels = df$point))) %>% rowwise() %>% mutate(val = dist.eucl(df[id1, 2:3], df[id2, 2:3])) %>% ungroup() %>% complete(id1, id2, fill = list(val = 0)) %>% spread(id1, val) ## A tibble: 10 x 11 # id2 `1` `2` `3` `4` `5` `6` `7` `8` `9` `10` # <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> # 1 1 0. 1.00 0. 0. 0. 0. 0. 1.41 0. 0. # 2 2 0. 0. 0. 0. 0. 0. 0. 1.00 0. 0. # 3 3 1.41 1.00 0. 4.47 0. 2.24 0. 0. 4. 4.24 # 4 4 0. 0. 0. 0. 1.41 5.00 0. 0. 0. 0. # 5 5 0. 0. 0. 0. 0. 5.00 6.71 0. 0. 0. # 6 6 0. 1.41 0. 0. 0. 0. 3.16 1.00 0. 0. # 7 7 0. 0. 0. 0. 0. 0. 0. 3.61 0. 0. # 8 8 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. # 9 9 3.16 0. 0. 0. 0. 0. 7.81 4.47 0. 3.16 #10 10 0. 0. 0. 7.07 0. 0. 0. 0. 0. 0. 替换为任何其他距离指标,例如Haversine,余弦等。我之所以选择dist.eucl.只是出于方便。

  5. dist.eucl就很简单

    matrix

答案 1 :(得分:2)

Delaunay三角剖分的输出中基本上可以使用邻接矩阵,只需重新格式化即可。我们避免使用distm函数,因为我们不想计算所有成对的点之间的距离,仅计算相邻的成对点之间的距离。直接调用距离函数会更有效。

library(deldir)
library(geosphere)

del = deldir(dd$lat, dd$long)
del$delsgs$dist = with(del$delsgs, 
    distVincentySphere(p1 = cbind(y1, x1), p2 = cbind(y2, x2))
)
# we use y,x because the triangulation was lat,long but 
# distVincentySphere expects long,lat

# create empty adjacency matrix, fill in distances
adj = matrix(0, nrow = nrow(dd), ncol = nrow(dd))
adj[as.matrix(del$delsgs[c("ind1", "ind2")])] = del$delsgs$dist
round(adj)
#        [,1]  [,2]   [,3]   [,4]   [,5]   [,6]   [,7] [,8]   [,9]  [,10]
#  [1,]      0     0 131124      0      0      0      0    0 341685      0
#  [2,] 111319     0  68535      0      0 130321      0    0      0      0
#  [3,]      0     0      0      0      0      0      0    0      0      0
#  [4,]      0     0 464058      0      0      0      0    0      0 782155
#  [5,]      0     0      0 127147      0      0      0    0      0      0
#  [6,]      0     0 175378 422215 484616      0      0    0      0      0
#  [7,]      0     0      0      0 504301 227684      0    0 753748      0
#  [8,] 131124 68535      0      0      0 111319 299883    0 467662      0
#  [9,]      0     0 445278      0      0      0      0    0      0      0
# [10,]      0     0 395715      0      0      0      0    0 247685      0

使用此数据:

dd = read.table(text = "point lat long
1  51 31
2  52 31
3  52 30
4  56 28
5  57 29
6  53 32
7  54 35
8  52 32
9  48 30
10 49 27", header = T)