我想计算(lat,lon)坐标之间的距离,如下例所示: Calculating distances from latitude and longitude coordinates in R
但是使用dplyr来加速这个过程,并使用geosphere的distCosine函数。
这个函数只接受大小为2的向量,我找到的唯一方法是:
p <- data.frame(lat=runif(6,-90,90), lon=runif(6,-180,180),lat2=runif(6,-90,90), lon2=runif(6,-180,180) )
p$dist <- sapply(1:nrow(p), function(x) distCosine(c(p$lon[x], p$lat[x]), c(p$lon2[x], p$lat2[x]) ) )
使用dplyr我尝试过:
p %>% rowwise() %>% mutate(dist2prev = distCosine(c(lon, lat), c(lon2, lat2)))
p %>% group_by(1:n()) %>% mutate(dist2prev = distCosine(c(lon, lat), c(lon2, lat2)))
但错误始终相同:
Wrong length for a vector, should be 2
知道为什么dplyr在那里没有成功?
答案 0 :(得分:1)
不确定您的代码为什么不起作用。使用do.call
似乎比您的vanilla实现或dplyr
快几个数量级:
library(geosphere)
library(dplyr)
N <- 100
p <- data.frame(lat=runif(N,-90,90), lon=runif(N,-180,180),
lat2=runif(N,-90,90), lon2=runif(N,-180,180) )
f1 <- function() {
sapply(1:nrow(p), function(x) distCosine(c(p$lon[x], p$lat[x]),
c(p$lon2[x], p$lat2[x]) ) )
}
pts <- list(p1=p[2:1], p2=p[4:3])
f2 <- function() {
do.call(distCosine, pts)
}
f3 <- function() {
p %>% rowwise() %>% mutate(dist2prev = distCosine(c(lon, lat), c(lon2, lat2)))
}
geosphere::distCosine
的帮助(您没有提及您正在使用的库)暗示该功能是矢量化的。这比执行逐行操作要快得多。
> microbenchmark::microbenchmark(vanilla=f1(), do.call=f2(), dplyr=f3())
Unit: microseconds
expr min lq mean median uq max neval
vanilla 21342.53 32076.194 39113.213 40463.300 45340.3695 80332.304 100
do.call 371.34 444.391 617.022 562.337 772.5475 1228.161 100
dplyr 19800.10 27304.895 35627.085 34618.692 42531.5415 66111.814 100
答案 1 :(得分:1)
如果我放弃使用distCosine并自行实现该功能,我也会得到快速响应:
dist <- function(lat1, lon1, lat2, lon2){
r <- acos(sin(lat1) * sin(lat2) + cos(lat1)*cos(lat2) * cos(abs(lon2-lon1))) * 6378137
}
deg2rad <- function(deg) {(deg * pi) / (180)}
p %>% mutate(x = dist(deg2rad(lat1),deg2rad(lon1),deg2rad(lat2),deg2rad(lon2)))