Поиск диапазона для 2 кадров данных (с 2 входными векторами) - PullRequest
1 голос
/ 07 апреля 2020

может кто-нибудь мне помочь? Вот подробности ниже.

Пример кадра данных 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 dput:

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 dput:

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"))

Ответы [ 2 ]

2 голосов
/ 07 апреля 2020

Вот что я попробовал. Для долготы и широты в каждой строке в df1 вы хотите выполнить логические проверки, используя значения lon / lat в каждой строке в df2. Для каждой строки в df1 я создал фрейм данных, содержащий логические значения. Каждый фрейм данных имеет три строки и два столбца. Затем я определил, какая строка в каждом фрейме данных имеет значение ИСТИНА для долготы и широты. Используя этот индекс, я получил желаемое ID в df2

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 

Следующим шагом было объединение out с df1. Поскольку для третьего ряда совпадений нет, вы видите 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>
0 голосов
/ 08 апреля 2020

Спасибо тем, кто помог. Я попробовал другой подход, используя «SQLDF», и он работал отлично. Обратите внимание, что я сравниваю 2,4 миллиона строк данных с 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)
...