R 使用ggmap、geom_点和循环映射长lat数据集的最近邻

R 使用ggmap、geom_点和循环映射长lat数据集的最近邻,r,ggplot2,geospatial,subset,ggmap,R,Ggplot2,Geospatial,Subset,Ggmap,我的最终目标是使用ggplot2包中的geom_路径在ggmap上连接一组建筑物(基于欧几里得距离)的所有最近邻居。我需要一个循环的帮助,这个循环可以让我尽可能容易地画出所有的邻居 我创建了北京三种建筑类型之间的距离矩阵(称为“kmnew”),单位为公里:B(x2)、D(x2)和L(x1): 我通过声明一个矩阵并使用循环来确定最近邻建筑,尝试按行识别每个建筑的最近邻: nn <- matrix(NA,nrow=5,ncol=1) for (i in 1:nrow(kmnew)){

我的最终目标是使用ggplot2包中的geom_路径在ggmap上连接一组建筑物(基于欧几里得距离)的所有最近邻居。我需要一个循环的帮助,这个循环可以让我尽可能容易地画出所有的邻居

我创建了北京三种建筑类型之间的距离矩阵(称为“kmnew”),单位为公里:B(x2)、D(x2)和L(x1):

我通过声明一个矩阵并使用循环来确定最近邻建筑,尝试按行识别每个建筑的最近邻:

nn <- matrix(NA,nrow=5,ncol=1)


for (i in 1:nrow(kmnew)){
  nn[i,] <- which.min(kmnew[i,]) 
}
我将其附加到名为newbjdata的原始数据帧:

colbj <- cbind(newbjdata,nn)
然后,我通过ggmap检索我的地图:

bjgmap <- get_map(location = c(lon = 116.407395,lat = 39.904211),
                  zoom = 13, scale = "auto",
                  maptype = "roadmap",
                  messaging = FALSE, urlonly = FALSE,
                  filename = "ggmaptemp", crop = TRUE,
                  color = "bw",
                  source = "google", api_key)

然而,我需要一个像循环一样工作的解决方案,我不知道如何实现这一点,因为我需要引用nn列并将其引用回长lat数据n次。我完全可以相信,我并没有使用最有效的方法,所以我愿意接受其他方法。非常感谢您的帮助。

这是我的尝试。我使用
geosphere
包中的
gcIntermediate()
来设置行。首先,我需要重新整理你的数据。当您使用
gcIntermediate()
时,您需要离开和到达long/lat。也就是说,您需要四列。为了以这种方式排列数据,我使用了
dplyr
包<代码>变异(colbj,funs([nn]),vars=long:lat)用于获取所需的到达时间long/lat.
表示“long”和“lat”
[nn]
是变量的向量索引。然后,我使用了
gcIntermediate()
。这将创建空间线。您需要将对象设置为SpatialLinesDataFrame。然后,需要将输出转换为“正常”data.frame。此步骤非常重要,以便
ggplot
可以读取您的数据<代码>强化()正在执行此任务

library(ggmap)
library(geosphere)
library(dplyr)
library(ggplot2)

### Arrange the data: set up departure and arrival long/lat

mutate_each(colbj, funs(.[nn]), vars = long:lat) %>%
rename(arr_long = vars1, arr_lat = vars2) %>%
filter(complete.cases(nn)) -> mydf

### Get line information

rts <- gcIntermediate(mydf[,c("long", "lat")],
                      mydf[,c("arr_long", "arr_lat")],
                      50,
                      breakAtDateLine = FALSE,
                      addStartEnd = TRUE,
                      sp = TRUE)

### Convert the routes to a data frame for ggplot use

rts <- as(rts, "SpatialLinesDataFrame")
rts.df <- fortify(rts)


### Get a map (borrowing the OP's code)                   
bjgmap <- get_map(location = c(lon = 116.407395,lat = 39.904211),
                  zoom = 13, scale = "auto",
                  maptype = "roadmap",
                  messaging = FALSE, urlonly = FALSE,
                  filename = "ggmaptemp", crop = TRUE,
                  color = "bw",
                  source = "google", api_key)

# Draw the map
ggmap(bjgmap) +
geom_point(data = colbj,aes(x = long, y = lat, fill = factor(Name)),
           size = 10,pch = 21, col = "white") +
geom_path(data = rts.df, aes(x = long, y = lat, group = group),
          col = "black")
资料


colbj您能解释一下“B型第一栋建筑(第1排)的nn是L型第一栋建筑(第5排)”的意思吗?我不明白这一点。你想怎样画线?这是你地图上的5个点。您最终想要什么?我的数据帧的最近邻(nn)列表示最近邻所在的行。因此,第1行(B存储1)的nn(最近邻)是第5行(L存储1)。我的目标是通过一条线(geom_路径)连接所有最近的邻居,因为在最小的示例中,我已经手动连接了这两个邻居,除了使用比使用“子集”更自动化的方式之外。非常感谢!这意味着从每个数据点到某处有一条线。对吗?完成了。希望以下是你想要的。这正是我想要的结果。非常感谢,爵士。我不熟悉gcIntermediate,但看起来应该熟悉。我需要一段时间才能理解它,但这再一次非常有帮助,超出了我的预期。谢谢大家!@RichS我很高兴听到这是你想要的。可能还有其他方法来做同样的工作。但是,这是我根据我的经验所知道的。我通常用这种方式处理在两点之间画线的任务。看一看地球圈的CRAN手册。或者搜索其他软件包。您可以找到较短的解决方案。:)
colbj <- cbind(newbjdata,nn)
  Name Store sqft     long      lat nn
1    B     1 1200 116.4579 39.93921  5
2    B     2  750 116.3811 39.93312  4
3    D     1  550 116.4417 39.88882  5
4    D     2  600 116.4022 39.90222  5
5    L     1 1000 116.4333 39.91100 NA
bjgmap <- get_map(location = c(lon = 116.407395,lat = 39.904211),
                  zoom = 13, scale = "auto",
                  maptype = "roadmap",
                  messaging = FALSE, urlonly = FALSE,
                  filename = "ggmaptemp", crop = TRUE,
                  color = "bw",
                  source = "google", api_key)
ggmap(bjgmap) +
geom_point(data = colbj, aes(x = long,y = lat, fill = factor(Name)),
           size =10, pch = 21, col = "white") +
geom_path(data = subset(colbj[c(1,5),]), aes(x = long,y = lat),col = "black")
library(ggmap)
library(geosphere)
library(dplyr)
library(ggplot2)

### Arrange the data: set up departure and arrival long/lat

mutate_each(colbj, funs(.[nn]), vars = long:lat) %>%
rename(arr_long = vars1, arr_lat = vars2) %>%
filter(complete.cases(nn)) -> mydf

### Get line information

rts <- gcIntermediate(mydf[,c("long", "lat")],
                      mydf[,c("arr_long", "arr_lat")],
                      50,
                      breakAtDateLine = FALSE,
                      addStartEnd = TRUE,
                      sp = TRUE)

### Convert the routes to a data frame for ggplot use

rts <- as(rts, "SpatialLinesDataFrame")
rts.df <- fortify(rts)


### Get a map (borrowing the OP's code)                   
bjgmap <- get_map(location = c(lon = 116.407395,lat = 39.904211),
                  zoom = 13, scale = "auto",
                  maptype = "roadmap",
                  messaging = FALSE, urlonly = FALSE,
                  filename = "ggmaptemp", crop = TRUE,
                  color = "bw",
                  source = "google", api_key)

# Draw the map
ggmap(bjgmap) +
geom_point(data = colbj,aes(x = long, y = lat, fill = factor(Name)),
           size = 10,pch = 21, col = "white") +
geom_path(data = rts.df, aes(x = long, y = lat, group = group),
          col = "black")
mutate_each(colbj, funs(.[nn]), vars = long:lat) %>%
rename(arr_long = vars1, arr_lat = vars2) %>%
filter(complete.cases(nn)) %>%
do(fortify(as(gcIntermediate(.[,c("long", "lat")],
                          .[,c("arr_long", "arr_lat")],
                          50,
                          breakAtDateLine = FALSE,
                          addStartEnd = TRUE,
                          sp = TRUE), "SpatialLinesDataFrame"))) -> foo

identical(rts.df, foo)
#[1] TRUE
colbj <- structure(list(Name = structure(c(1L, 1L, 2L, 2L, 3L), .Label = c("B", 
"D", "L"), class = "factor"), Store = c(1L, 2L, 1L, 2L, 1L), 
sqft = c(1200L, 750L, 550L, 600L, 1000L), long = c(116.4579, 
116.3811, 116.4417, 116.4022, 116.4333), lat = c(39.93921, 
39.93312, 39.88882, 39.90222, 39.911), nn = c(5L, 4L, 5L, 
5L, NA)), .Names = c("Name", "Store", "sqft", "long", "lat", 
"nn"), class = "data.frame", row.names = c("1", "2", "3", "4", 
"5"))