首页 文章

在两个数据帧之间从lat和long创建R中的距离矩阵

提问于
浏览
0

我有两个数据帧,每个数据帧由纬度,经度和相应的ID组合而成 .

我本想做的就是:

for each_ID in df1:
     for each_ID in df2: 
          calculate distance in miles
 result_df = df1 x df2

     df=data.frame(id  = c('row1','row2','row3'), lat = c(47,57,67), long = c(-80,-80,-80))
     df2 = data.frame(id  = c('col1','col2','col3'), lat = c(47,57,67), long = c(-83,-84,-85))

我想计算df1和df2之间每个点的距离 . 我不需要计算df1中各点之间的距离 . 我希望所有内容都包含相应列名的行和列名称的矩阵 .

我环顾四周,并没有看到一个简单的方法 . 有人提供一些帮助吗?

2 回答

  • 0
    library(generator)
    
    df1 <- data.frame(id=seq(1:10), lat=r_latitudes(10), lon=r_longitudes(10))
    df2 <- data.frame(id=seq(1:10), lat=r_latitudes(10), lon=r_longitudes(10))
    

    enter image description here

    Grab a function for calculating distance between longs and lats:

    lat_lon_dist <- function(long1, lat1, long2, lat2) {
        rad <- pi/180
        a1 <- lat1 * rad
        a2 <- long1 * rad
        b1 <- lat2 * rad
        b2 <- long2 * rad
        dlon <- b2 - a2
        dlat <- b1 - a1
        a <- (sin(dlat/2))^2 + cos(a1) * cos(b1) * (sin(dlon/2))^2
        c <- 2 * atan2(sqrt(a), sqrt(1 - a))
        R <- 6378.145
        d <- R * c
        return(d)
    }
    

    Calculate all distances between data frames, and set to new data frame:

    distances = NULL
    for(i in 1:nrow(df1)) {
        labels = paste('DF1_long=', df1[i,3], 'DF1_lat=', df1[i,2], 'DF2_long=', df2[i,3], 'DF1_lat=', df2[i,2])
        distances[i] <- lat_lon_dist(df1[i,3], df1[i,2], df2[i,3], df2[i,2])
        }
    
    data.frame(labels, distances)
    

    enter image description here

    可能有更准确的距离计算,例如geosphere包中提供的距离计算 . 不确定您是否希望在最终帧中使用这些标签,而是根据需要进行更改此外,如果这是您想要的最终结果,您可以将此帧转换为矩阵 .

  • 0

    您可以使用 geosphere 包中的 distm 函数,该函数默认情况下会计算Haversine距离,但如果需要,您还可以精确控制其他距离函数 . 默认情况下,距离以米为单位,但您可以通过乘以转换常数将其转换为英里 .

    library(geosphere)
    res = distm(df1[c("long","lat")],df2[c("long","lat")])*0.0006213712
    rownames(res) = df1$id
    colnames(res) = df2$id
             col1     col2      col3
    row1  141.5143 712.0616 1395.1172
    row2  703.2304 150.6708  709.9512
    row3 1387.6401 703.4400  135.0994
    

相关问题