返回两个数据帧中两个长lat坐标的每一行和每一列之间的最小距离

时间:2018-04-29 15:30:50

标签: r distance geo

我想计算每行与两个数据帧的列之间的最小地理距离。 DF1有很多机构,DF2有很多活动。喜欢,所以:

DateTime.Now

我希望返回DF1中每个机构距离最小的事件,并将距离和ID从DF2添加到DF1。虽然我知道如何计算成对距离,但我无法计算从DF [1,]到DF2的所有距离并返回最小值,依此类推。

这是我尝试过的(并且失败了)。

#DF1 (institutions)
 DF1 <- data.frame(latitude=c(41.49532, 36.26906, 40.06599), 
 longitude=c(-98.77298, -101.40585, -80.72291))
 DF1$institution <- letters[seq( from = 1, to = nrow(DF1))] 

#DF2 (events)
 DF2 <- data.frame(latitude=c(32.05, 32.62, 30.23), longitude=c(-86.82,   
 -87.67, -88.02))
 DF2$ID <- seq_len(nrow(DF1)

现在,我的尝试是向DF1的row1和矢量化事件提供distanceCALC。

  library(geosphere)

  #Define a function
   distanceCALC <- function(x, y) { distm(x = x, y = y, 
    fun = distHaversine)}

  #Define vector of events 
   DF2_vec <- DF2[, c('longitude', 'latitude')]

  #Define df to hold distances
   shrtdist <- data.frame()

我的猜测是,解决方案需要对数据进行重新整理和提供。此外,循环是非常糟糕的做法,并且考虑到观察次数太慢。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

这是使用outer函数

解决此问题的简单方法
squared_distance <- function(x, y ) (x - y)^2

lat <- outer(DF1$latitude, DF2$latitude, squared_distance)
long <- outer(DF1$longitude, DF2$longitude, squared_distance)

pairwise_dist <- sqrt(lat + long)

rownames(pairwise_dist) <- DF1$institution
colnames(pairwise_dist) <- DF2$ID

pairwise_dist

这为您提供了每个机构(行)和事件(列)之间距离的矩阵。为了获得df1中的距离和事件,我们可以做到

df1$min_dist <- apply(pairwise_dist, 1, min)
df1$min_inst <- apply(pairwise_dist, 1, min)

请注意,在这种情况下第二个工作的原因是因为事件用数字标记。如果您的真实数据没有那么方便的功能,我们需要做

df1$min_inst <- colnames(pairwise_dist)[apply(pairwise_dist, 1, which.min)]

使用替代距离函数更新

我没有对此进行测试,但我认为这应该可行。同样,输出将是一个矩阵。

gcd.hf <- function(DF1, DF2) {
  sin2.long <- sin(outer(DF1$longitude, DF2$longitude, "-") / 2)^2
  sin2.lat  <- outer(DF1$latitude, DF2$latitude, "-")
  cos.lat <- outer(cos(DF1$latitude), cos(DF2$latitude), "*")

  a <- sin2.long + sin2.lat * cos.lat # we do this cell-wise
  cir <- 2 * asin(pmin(1, sqrt(a))) # I never assign anything to "c" since that's concatenate.  Rename this variable as appropriate (I have no idea if it's related to the circumference or not.)
  cir * 6371
}

pairwise_dist <- gcd.hf(DF1, DF2)