首页 > 解决方案 > R:根据每行中两个值的最接近匹配和精确匹配合并查找表中的行

问题描述

我有一张表格,上面有lat lon我所在州高速公路路线上的里程碑坐标。我想将此表用作查找表。我有第二张桌子,上面有里程碑和高速公路路线栏。我想lat lon根据高速公路路线上最近的里程碑将列分配给第二个表。

在这两个表中,highway-route 列被命名routeID,milepost 列被命名为milePost

(我通常使用 node.js,所以请原谅我对 R 命名法和语法的有限知识。)

我已经尝试以多种方式做到这一点,但我似乎无法得到我想要的结果。例如,下面是我构建的用于迭代每个里程碑值的函数。我试图通过过滤表来缩小我循环的值routeID

以下代码非常缺乏。我正在分享它,以便您了解我是如何解决这个问题的,但我想就如何改变我的方法获得建议。最好的方法是什么?我一直在使用这个dplyr包。

控制台中的表格:

> lookup
     routeID1 milePost1   lon      lat      tz              routeID milePost
      <chr>    <fctr>    <dbl>    <dbl>    <chr>             <dbl>   <dbl>
1:    I 019    102.08 -110.9789 32.19912 America/Phoenix      19   102.08
2:    I 019    000.00 -110.9412 31.33468 America/Phoenix      19     0.00
3:    I 019    069.69 -110.9835 31.90669 America/Phoenix      19    69.69
4:    I 019    042.43 -111.0628 31.67479 America/Phoenix      19    42.43
  ---                                                                       
8684: S 064    280    -111.6610 35.93829 America/Phoenix      64   280.00
8685: S 064    200    -112.1715 35.46088 America/Phoenix      64   200.00

> dataTable 
         date        time       routeID milePost     county_name
        <date>     <S3: hms>     <dbl>   <dbl>        <chr>
1:      2015-04-01 07:25:00       93       33         Mohave County
  ---   
450040: 2015-09-30 12:55:00       353      80         Cochise County               
450041: 2015-09-30 21:10:00       NA       NA         Maricopa County               
450042: 2015-09-30 22:55:00       17      204         Maricopa County                  

功能:

loop <- function(x,y){
  i<-0
  for(mile in x){

    i<-i+1

# filter to only rows that match dataTable$routeID 
  filt_Lookup <- lookup%>%filter(routeID == y[i])

# find index of closest matching milepost in filt_Lookup 
  index <-  which.min(abs(filt_Lookup$milePost - mile))

#use that index to find the corresponding lat coordinate 
  w<-filt_Lookup[index]$lat

  w
  } 
}

q <- dataTable%>%mutate(lat=loop(milePost, routeID))

目前,我的函数没有添加与每行dataTable$routeID和最接近的dataTable$milePost值对应的纬度值的新列。

我的预期结果将通过添加一lat列来实现,如下所示:

> q 
         date        time       routeID milePost     county_name        lat
        <date>     <S3: hms>     <dbl>   <dbl>        <chr>            <dbl>
1:      2015-04-01 07:25:00       93       33         Mohave County   31.67479
  ---   
450040: 2015-09-30 12:55:00       353      80         Cochise County  35.46088             
450041: 2015-09-30 21:10:00       NA       NA         Maricopa County    NA             
450042: 2015-09-30 22:55:00       17      204         Maricopa County 35.46088

注意:以上lat值只是占位符,不一定对应。我也需要添加相应的lon值。

重复的问题响应:它是独一无二的,因为我需要将行与完全routeID匹配和最接近的milePost匹配合并。

标签: rdplyrdata.table

解决方案


样本数据

取自评论,略有改动

library(data.table)
lookup <- data.table(routeID = c( 19,19,64,64), milePost = c( 102,0,69.69,42.43), lat = c( 32.19912,31.33468,35.93829,35.46088), lon = c( -110.9789,-110.9412,-111.6610,-112.1715) ) 
dataTable <- data.table( date = c("2015-04-01", "2015-09-30", "2015-09-30","2015-09-30", "2015-10-03", "2015-11-03"), 
                         time = c("05:25:00","07:25:00","07:25:45","04:4:00","02:29:00","07:25:44"), 
                         routeID = c( 19,19,64,64,NA,64), 
                         milePost = c( 100,1,70,40,NA,70) )

代码

对连接的 data.tables 的最后一个键执行滚动连接。因此将 RouteId 设置为第一个键,将 milePost 设置为第二个

setkey( lookup, routeID, milePost )
setkey( dataTable, routeID, milePost )

然后执行滚动 gupdate 连接,将 -table 中的 lat、lon 和 Milepost 列连接lookupdataTable表中。

#rolling update join on dataTable
dataTable[ lookup, 
           `:=`( lat = i.lat, 
                 lon = i.lon, 
                 milePost.lookup = i.milePost), 
           roll = "nearest" ][]

输出

#          date     time routeID milePost      lat       lon milePost.lookup
# 1: 2015-10-03 02:29:00      NA       NA       NA        NA              NA
# 2: 2015-09-30 07:25:00      19        1 31.33468 -110.9412            0.00
# 3: 2015-04-01 05:25:00      19      100 32.19912 -110.9789          102.00
# 4: 2015-09-30  04:4:00      64       40 35.46088 -112.1715           42.43
# 5: 2015-09-30 07:25:45      64       70 35.93829 -111.6610           69.69
# 6: 2015-11-03 07:25:44      64       70       NA        NA              NA

推荐阅读