Как написать функцию для сопоставления значений в двух кадрах данных (сделать более быструю версию)

#r #performance

Вопрос:

У меня есть фрейм данных с координатами интересующих областей и другой фрейм данных с показаниями температуры (bio1), полученными на исследовательских станциях, и их координатами.

Я хотел бы создать новую колонку, чтобы сопоставить интересующую область с температурой ближайшей исследовательской станции.

Мне удалось сделать это со следующим кодом (вот упрощенная пара поддельных фреймов данных).

 df1 lt;- data.frame(latitude = c(10.5,6,2), longitude = c(18,9,4)) df2 lt;- data.frame(vy = c(10,5,3), vx = c(20,10,3), bio1 = c('a','b','c'))   for(i in 1:nrow(df1)){  df1$temperature[i] lt;- df2$bio1[which(abs(df2$vx - df1$longitude[i])    abs(df2$vy - df1$latitude[i]) ==   min(abs(df2$vx - df1$longitude[i])     abs(df2$vy - df1$latitude[i])))]  }  

Итак, этот код проверяет все комбинации и выбирает ту, у которой наименьшее расстояние между широтой и долготой в каждой строке.

Я проверил, и, похоже, это работает, но его очень медленно использовать на больших кадрах данных.

Можете ли вы решить эту проблему более быстрым методом?

Ответ №1:

Что — то вроде этого может сработать

 library(tidyverse) library(sf) # put some id's in df1 df1$id lt;- LETTERS[1:3] # make df1 and df2 simple objects sf1 lt;- df1 %gt;%  st_as_sf(coords = c("longitude", "latitude"), crs = 4326) sf2 lt;- df2 %gt;%  st_as_sf(coords = c("vy", "vx"), crs = 4326) # find nearest sf2 in sf1 sf1 %gt;%  mutate(nearest_bio = sf2$bio1[st_nearest_feature(sf2)])  # Simple feature collection with 3 features and 2 fields # Geometry type: POINT # Dimension: XY # Bounding box: xmin: 4 ymin: 2 xmax: 18 ymax: 10.5 # Geodetic CRS: WGS 84 # id geometry nearest_bio # 1 A POINT (18 10.5) b # 2 B POINT (9 6) c # 3 C POINT (4 2) b  

Комментарии:

1. На самом деле это не работает, результат должен был быть в том же порядке a,b,c. Однако я не знаком с библиотекой sf, поэтому я не совсем уверен, что могло пойти не так

2. нанесите точки на карту, и вы будете удивлены..