假设我有点的坐标,每个点都有ID。我如何从delaunay三角测量中提取距离到列表对象?
# My data are similar to this structure
id <- c("A","B","C","D","E","F","G","H","I","J","K","L","M","N")
x_coor <- c(0.5,1,1,1.5,2,3,3,3.5,4,4.5,5,5,6,7)
y_coor <- c(5.5,3,7,6.5,5,3.5,3,1.5,1,2.5,4,5,3.5,5.5)
my.data <- data.frame(id = id, x_coor = x_coor, y_coor = y_coor)
# When I perform Delaunay triangulation, I can see the distances....
library(tripack)
my.triangles<-tri.mesh(my.data$x_coor, my.data$y_coor)
plot(my.triangles, do.points=FALSE, lwd=0.2)
points(my.data$x, my.data$y, col = "black", pch=20, cex = 1.5)
text(my.data$x, my.data$y, labels = my.data$id)
如何像这样提取“对”点列表对象?
# I need something like this...
my.list
[[A]]
[1] 2.55 1.58 1.41 1.58 (all distances connected to "A")
[[B]]
[1] 2.55 2.24 2.06 2.00 2.92 3.61 (all distances connected to "B")
etc.
答案 0 :(得分:3)
从tri.mesh()
开始,我们有:
my_triangles <- tri.mesh(my.data$x_coor, my.data$y_coor)
plot(my_triangles, do.points=FALSE, lwd=0.2)
从str(my_triangles)
和?neighbours
上的R文档,我们可以按照以下方式为每个点提取邻居:
neiblist <- neighbours(my_triangles)
然后附加原始数据帧中的点ID,以便您几乎拥有所需的列表,除了它包含邻居ID而不是距离:
names(neiblist) <- my.data$id #append names for later reference
然后用所有点计算欧氏距离矩阵:
euc_dist <- as.matrix(dist(cbind(x=my_triangles$x, y=my_triangles$y)))
#Append dimnames for reference
colnames(euc_dist) <- my.data$id
rownames(euc_dist) <- my.data$id
查找一个点可能具有的最大邻居:需要内存预分配。
max_n <- max(unlist(lapply(neiblist, length)))
npoints <- length(my.data$id) # This is just the total number of points
预分配收集结果的内存,计算效率和速度的重要性:
dist_2neigh_mat <- matrix(nrow=npoints, ncol=max_n) #Create results matrix
rownames(dist_2neigh_mat) <- my.data$id
colnames(dist_2neigh_mat) <- colnames(data.frame(dist=matrix(data=1:6, nrow=1)))
获取并收集所有点的距离向量。
for (i in my.data$id){
neighbors_i <- neiblist[[i]]
dist2neighbours_i <- euc_dist[,i][neighbors_i]
#Append vector with NAs to match ncol of results matrix
dist2neighbours_i <- c(dist2neighbours_i, rep(NA,
times=(max_n-length(dist2neighbours_i))))
dist_2neigh_mat[i,] <- dist2neighbours_i #Update results matrix with i'th distances
}
dist_2neigh_mat
包含您的搜索结果。如果您坚持将结果完全按照问题中的说明列入清单,那么您只需将结果矩阵转换为如下列表:
results_list <- as.list(data.frame(t(dist_2neigh_mat)))
然后,出于矩阵完整性原因,您可以删除之前生成的NA:
#Function to remove NA's
fun_NA <- function(x){x=x[!is.na(x)]
return(x)}
从结果
中删除NA&#39results_list <- lapply(results_list, FUN=fun_NA)
我的想法是,即使有很多很多分数,这也会非常迅速。但有人可能会有不同的看法: - )
干杯。
答案 1 :(得分:1)
连接到'A'的所有段的端点之一等于'A'的坐标。找到那些坐标:
xy<- c(x-coor[id=='A'],y_coor[id=='A'])
如果您这样做,例如,print.tri(my.triangles)
,您将获得邻接打印输出:
#partial result
triangulation nodes with neigbours:
node: (x,y): neighbours
1: (0.5,5.5) [4]: 2 3 4 5
2: (1,3) [6]: 1 5 6 7 8 9
3: (1,7) [3]: 1 4 14
通过观察xy
值与此打印输出中的第一个坐标匹配,您可以抓取相邻顶点并查找其坐标。它可能更容易执行
my_neighbor<-neighbours(my.triangles)
# partial result:
[[1]]
[1] 2 3 4 5
[[2]]
[1] 1 5 6 7 8 9
[[3]]
[1] 1 4 14
[[4]]
[1] 1 3 5 12 14
然后抓住坐标。例如。对于第一个顶点,邻居是2,3,4,5。抓住坐标xtmp<- my.triangles$x[c(1,2:5)]
和ytmp<-my.triangles$y[c(1,2:5)]
,构建矩阵并生成距离:
dist(cbind(xtmp,ytmp))
第一列的结果是您想要my.list$A