Учитывая представленные образцы данных и пример для воспроизведения, решение может быть дано следующим образом:
require(dplyr)
df2$val_1 <- left_join(df2,
df1 %>% mutate(x = round(x,0), y = round(y,0)),
by = c("x" = "x", "y" = "y")) %>%
pull(val)
Вместо этого, если вы хотитеподходить к нему, используя более обобщенный подход, основанный на расстоянии .Я бы предложил следующее:
Прежде всего, важно присвоить primary key
обоим data.frame
df1
и df2
:
df1 <- data.frame(
ID = seq.int(1:100),
x = c(1.25:10.25),
y = c(1.25:10.25),
val = sample(50:150, 100, replace = FALSE)
)
df2 <- data.frame(
ID = seq.int(1:100),
x = c(1:10),
y = c(1:10),
val_2 = sample(50:150, 100, replace = FALSE)
)
Нам нужноустановить пакет pdist
, поскольку он позволяет вычислять матрицу расстояний, в этом решении используется евклидово расстояние с учетом переменных x
и y
require(pdist)
dists <- pdist(df2[c("x", "y")],
df1[c("x", "y")])
Давайте преобразуем вывод функции pdist()
в матрицу
dists <- as.matrix(dists)
Теперь, исходя из полученной матрицы, мы хотим получить data.frame
, что для каждого элемента df2
дает нам идентификатор ближайшего элемента df1
assign_value <- data.frame(ID_df2 = df2$ID,
ID_df1 = apply(dists, 1, which.min))
Нам нужно объединить полученный 2-столбец data.frame
с val
функцией df1
:
assign_value <- left_join(assign_value,
df1[c("ID", "val")],
by = c("ID_df1" = "ID"))
Наконец, мы получили данные.frame со следующей структурой: « каждая строка относится к уникальному элементу df2
и связана с ID
ближайшего элемента в df1
и его val
":
ID_df2 ID_df1 val
1 1 1 70
2 2 2 132
Для получения окончательного data.frame нам просто нужно выполнить простой left_присоединяйтесь, используя нужные функции.
alternative_solution <- dplyr::left_join(df2,
assign_value[c("ID_df2", "val")],
by = c("ID" = "ID_df2"))
> identical(df2$val_2, alternative_solution$val)
[1] TRUE