r - 根据地理距离矩阵的结果更改列
问题描述
我有一个看起来像这样的数据框:
long lat site
-141.37 61.13 x1
-149.1833 66.7333 x2
-149.667 67.667 x3
-141.3667 61.1157 x4
我想计算所有site
's using之间的距离distVincentyEllipsoid
。然后对于那些彼此相距 5 公里以内的站点,我想修改site
名称以包含两个站点。所以,在这个例子中x1
,x4
彼此之间的距离在 5 公里以内,所以它会是这样的:
long lat site
-141.37 61.13 x1_x4
-149.1833 66.7333 x2
-149.667 67.667 x3
-141.3667 61.1157 x1_x4
我知道我可以通过site
这种方式计算 all 之间的矩阵:
df %>% dplyr::select('long', 'lat')
distm(df, fun = distVincentyEllipsoid)
但我不知道如何从那里拿走它。
解决方案
如果您将示例数据提供为 R 代码,这将很有帮助,如下所示
x <- matrix(c(-141.37, 61.13, -149.1833, 66.7333, -149.667, 67.667, -141.3667, 61.1157), ncol=2, byrow=TRUE)
colnames(x) <- c("lon", "lat")
x <- data.frame(site=paste0("x", 1:4), x)
但感谢您显示预期的输出
解决方案:
正如你所建议的,首先制作一个距离矩阵。然后将其分类为是否在阈值距离内,然后使用行来选择记录。请注意,我使用distGeo
--- 这是比distVincentyEllipsoid
.
library(geosphere)
m <- distm(x[, c("lon", "lat")], fun=distGeo)
m <- m < 5000
x$name <- apply(m, 1, function(i) paste(x$site[i], collapse="_"))
x
# site lon lat name
#1 x1 -141.3700 61.1300 x1_x4
#2 x2 -149.1833 66.7333 x2
#3 x3 -149.6670 67.6670 x3
#4 x4 -141.3667 61.1157 x1_x4
如果你有很多点,距离矩阵可能会变得太大。在那种情况下,你可以做
y <- x[, c("lon", "lat")]
for (i in 1:nrow(y)) {
j <- distGeo(y[i, ], y) < 5000
x$name[i] <- paste(x$site[j], collapse="_")
}
或者像这样
y <- x[, c("lon", "lat")]
x$name <- x$site
for (i in 1:nrow(y)) {
j <- distGeo(y[i, ], y) < 5000
if (any(j)) {
x$name[i] <- paste(x$site[j], collapse="_")
}
}
推荐阅读
- python - 如何加快 postgresql 中的 copy_expert?
- mongodb - 如何使用 for-loop 构建 Spring Data Mongo 聚合操作
- java - 使用 TimerGraphStageLogic 进行 Akka 流监督
- python - Python 正则表达式和在行中找到的几个命名组
- postgresql - 如何通过传递一周中的任何日期来仅检索星期四的日期
- r - R 不能识别循环中的日期
- oracle - 如何过滤 obiee 分析但小计值?
- android - 使按钮在子句上可用
- c++ - 使用指令可见的声明的名称隐藏
- ssh - 如何在 Ubuntu 服务器上安装 Terraria TShock 服务器?