【问题标题】:Range Lookup for 2 Dataframes (with 2 input vectors)2个数据帧的范围查找(带有2个输入向量)
【发布时间】:2020-07-19 14:51:11
【问题描述】:

有人可以帮助我吗?以下是详细信息。

示例数据框 1:

Latitude  Longitude
   12.10       4.10
   12.20       4.20
   12.30       4.50

数据框 2:

ID     Latitude1 Latitude2 Longitude1 Longitude2
ABC         11.5     12.15        3.9       4.15
DEF        12.17     12.25       4.17       4.25
GHI        12.27     12.45       4.45       4.48

所需的输出:

Latitude Longitude   ID
   12.10      4.10  ABC           
   12.20      4.20  DEF
   12.30      4.50   NA

输出中的第 3 行是 NA,因为它的经度值不在 dataframe2 给定的范围之间。

尝试的解决方案: 我创建了一个函数并使用了 DPLYR,但我只能对一个向量(纬度)进行范围查找。

getValue <- function(x,data) {
  tmp <- data %>%
    filter(Latitude1 <= x, x <= Latitude2) %>%
    filter(row_number() == 1)
  return(tmp$ID)
}
data_interval <- sapply(df1$Latitude, getValue, data=df2)

df1 输入:

df1 <- structure(list(Latitude = c(12.1, 12.2, 12.3), Longitude = c(4.1, 
4.2, 4.5)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", 
"data.frame"))

df2 输入:

df2 <- structure(list(ID = c("ABC", "DEF", "GHI"), Latitude1 = c(11.5, 
12.17, 12.27), Latitude2 = c(12.15, 12.25, 12.45), Longitude1 = c(3.9, 
4.17, 4.45), Longitude2 = c(4.15, 4.25, 4.48)), row.names = c(NA, 
-3L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

  • 感谢@Allan Cameron 的编辑,我是新成员。

标签: r dplyr data-science data-cleaning


【解决方案1】:

这是我尝试过的。对于df1 中每一行中的经度和纬度,您希望使用df2 中每一行中的 lon / lat 值运行逻辑检查。对于df1 中的每一行,我创建了一个包含逻辑值的数据框。每个数据框有三行两列。然后,我确定了每个数据框中的哪一行的经度和纬度都为 TRUE。使用这个索引,我在df2中得到了想要的ID

library(tidyverse)

map2_dfr(.x = df1$Latitude,
         .y = df1$Longitude,
         .f = function(x, y){
                tibble(lat = between(x, df2$Latitude1, df2$Latitude2),
                       lon = between(y, df2$Longitude1, df2$Longitude2)) %>% 
                mutate(subid = 1:n())},
         .id = "id") %>% 
group_by(id) %>% 
filter(lat == TRUE & lon == TRUE) %>% 
transmute(ID = df2$ID[subid]) -> out

out
#  id    ID   
#  <chr> <chr>
#1 1     ABC  
#2 2     DEF 

下一步是加入outdf1。由于第三行没有匹配项,因此您会看到 NA。

mutate(df1,
       id = as.character(1:n())) %>% 
left_join(out, by = "id") %>% 
select(-id)

  Latitude Longitude   ID
1     12.1       4.1  ABC
2     12.2       4.2  DEF
3     12.3       4.5 <NA>

【讨论】:

  • 嗨@jazzurro,感谢您的意见。但是,我在运行第一部分代码时遇到了这个错误:Error: Expecting a single value: [extent=43064]
  • @MarcAtanante 我没有你的实际数据。因此我不知道是什么导致了错误。
【解决方案2】:

感谢那些帮助过的人。我尝试了一种使用“SQLDF”的不同方法,并且效果很好。请注意,我将 240 万行数据帧与 43,000 行查找数据帧进行比较,因此我运行了 3 个小时。

sql_way_test <- function(data,lookup){
  data<-sqldf("select A.*,B.ID from
              data A left join lookup B 
              ON ((A.Latitude >= B.Latitude1 and A.Latitude < B.Latitude2) and
              (A.Longitude >= B.Longitude1 and A.Longitude < B.Longitude2))")
  data
}

df_SQLway <- sql_way_test(data = df1, df2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 2020-12-03
    相关资源
    最近更新 更多