计算多组坐标之间的距离
Compute distance between multiple sets of coordinates
我有一个坐标数据集,这些坐标按时间合并到一个数据框中,每个 ID 都在 header 中。例如:
> Date_time<-c("2015/03/04 01:00:00","2015/03/04 02:00:00","2015/03/04 03:00:00","2015/03/04 04:00:00")
> lat.1<-c(63.81310,63.83336,63.83250,63.82237)
> long.1<-c(-149.1176,-149.0193,-149.0249,-149.0408)
> lat.2<-c(63.85893 ,63.85885,63.86108,63.86357)
> long.2<-c(-151.1336,-151.1336,-151.1236,-151.1238)
> lat.3<-c(63.87627,63.87670, 63.85044,63.85052)
> long.3<-c(-149.5029,-149.5021,-149.5199,-149.5199)
>
> data<-data.frame(Date_time,lat.1,long.1,lat.2,long.2,lat.3,long.3)
> data
Date_time lat.1 long.1 lat.2 long.2 lat.3 long.3
1 2015/03/04 01:00:00 63.8131 -149.1176 63.85893 -151.1336 63.87627 -149.5029
2 2015/03/04 02:00:00 63.8131 -149.1176 63.85893 -151.1336 63.87627 -149.5029
3 2015/03/04 03:00:00 63.8131 -149.1176 63.85893 -151.1336 63.87627 -149.5029
4 2015/03/04 04:00:00 63.8131 -149.1176 63.85893 -151.1336 63.87627 -149.5029
我想计算每个个体之间的距离,例如 1 和 2、1 和 3 以及 2 和 3 之间的距离。我的数据框有比这更多的个体,所以我希望应用循环函数。
我可以单独使用
> data$distbetween12<-distHaversine(cbind(data$long.1,data$lat.1), cbind(data$long.2,data$lat.2))
> data$distbetween12
[1] 99083.48 99083.48 99083.48 99083.48
但是我可以在不输入每对组合的情况下计算所有成对距离吗?
谢谢!
这是一个依赖 combn
函数生成必要组合的解决方案。如果您有 3 对以上的 lat
、long
列,只需将 combn
函数中的第一个数字更改为正确的对数。
请注意,此解决方案还要求您的列严格遵守命名 lat.1
long.1
、lat.2
、long.2
等
combos <- combn(3, 2)
cbind(data, as.data.frame(`colnames<-`(apply(combos, 2, function(x) {
lats <- paste0("lat.", x)
lons <- paste0("long.", x)
geosphere::distHaversine(cbind(data[[lons[1]]], data[[lats[1]]]),
cbind(data[[lons[2]]], data[[lats[2]]]))
}), apply(combos, 2, paste, collapse = " v "))))
#> Date_time lat.1 long.1 lat.2 long.2 lat.3 long.3
#> 1 2015/03/04 01:00:00 63.81310 -149.1176 63.85893 -151.1336 63.87627 -149.5029
#> 2 2015/03/04 02:00:00 63.83336 -149.0193 63.85885 -151.1336 63.87670 -149.5021
#> 3 2015/03/04 03:00:00 63.83250 -149.0249 63.86108 -151.1236 63.85044 -149.5199
#> 4 2015/03/04 04:00:00 63.82237 -149.0408 63.86357 -151.1238 63.85052 -149.5199
#> 1 v 2 1 v 3 2 v 3
#> 1 99083.48 20172.13 79974.87
#> 2 103778.13 24168.80 80014.97
#> 3 103020.61 24374.46 78669.90
#> 4 102317.93 23724.27 78680.61
我有一个坐标数据集,这些坐标按时间合并到一个数据框中,每个 ID 都在 header 中。例如:
> Date_time<-c("2015/03/04 01:00:00","2015/03/04 02:00:00","2015/03/04 03:00:00","2015/03/04 04:00:00")
> lat.1<-c(63.81310,63.83336,63.83250,63.82237)
> long.1<-c(-149.1176,-149.0193,-149.0249,-149.0408)
> lat.2<-c(63.85893 ,63.85885,63.86108,63.86357)
> long.2<-c(-151.1336,-151.1336,-151.1236,-151.1238)
> lat.3<-c(63.87627,63.87670, 63.85044,63.85052)
> long.3<-c(-149.5029,-149.5021,-149.5199,-149.5199)
>
> data<-data.frame(Date_time,lat.1,long.1,lat.2,long.2,lat.3,long.3)
> data
Date_time lat.1 long.1 lat.2 long.2 lat.3 long.3
1 2015/03/04 01:00:00 63.8131 -149.1176 63.85893 -151.1336 63.87627 -149.5029
2 2015/03/04 02:00:00 63.8131 -149.1176 63.85893 -151.1336 63.87627 -149.5029
3 2015/03/04 03:00:00 63.8131 -149.1176 63.85893 -151.1336 63.87627 -149.5029
4 2015/03/04 04:00:00 63.8131 -149.1176 63.85893 -151.1336 63.87627 -149.5029
我想计算每个个体之间的距离,例如 1 和 2、1 和 3 以及 2 和 3 之间的距离。我的数据框有比这更多的个体,所以我希望应用循环函数。
我可以单独使用
> data$distbetween12<-distHaversine(cbind(data$long.1,data$lat.1), cbind(data$long.2,data$lat.2))
> data$distbetween12
[1] 99083.48 99083.48 99083.48 99083.48
但是我可以在不输入每对组合的情况下计算所有成对距离吗?
谢谢!
这是一个依赖 combn
函数生成必要组合的解决方案。如果您有 3 对以上的 lat
、long
列,只需将 combn
函数中的第一个数字更改为正确的对数。
请注意,此解决方案还要求您的列严格遵守命名 lat.1
long.1
、lat.2
、long.2
等
combos <- combn(3, 2)
cbind(data, as.data.frame(`colnames<-`(apply(combos, 2, function(x) {
lats <- paste0("lat.", x)
lons <- paste0("long.", x)
geosphere::distHaversine(cbind(data[[lons[1]]], data[[lats[1]]]),
cbind(data[[lons[2]]], data[[lats[2]]]))
}), apply(combos, 2, paste, collapse = " v "))))
#> Date_time lat.1 long.1 lat.2 long.2 lat.3 long.3
#> 1 2015/03/04 01:00:00 63.81310 -149.1176 63.85893 -151.1336 63.87627 -149.5029
#> 2 2015/03/04 02:00:00 63.83336 -149.0193 63.85885 -151.1336 63.87670 -149.5021
#> 3 2015/03/04 03:00:00 63.83250 -149.0249 63.86108 -151.1236 63.85044 -149.5199
#> 4 2015/03/04 04:00:00 63.82237 -149.0408 63.86357 -151.1238 63.85052 -149.5199
#> 1 v 2 1 v 3 2 v 3
#> 1 99083.48 20172.13 79974.87
#> 2 103778.13 24168.80 80014.97
#> 3 103020.61 24374.46 78669.90
#> 4 102317.93 23724.27 78680.61