Слияние df2
с df1
на group
дает все возможные комбинации -
x = merge(df2, df1, all.x = TRUE, by = "group")
Тогда совпадения могут характеризоваться разностью и направлением (выше или ниже) -
x$diff = x$value.x - x$value.y
x$type = ifelse(x$diff < 0, "high", "low")
Упорядочение по абсолютная разница и удаление дубликатов по «направлению» сохраняет только самые близкие значения «максимум» и «минимум» -
x = x[order(x$group, abs(x$diff)), ]
x = x[!duplicated(x[, c("group", "value.x", "type")]), ]
Таблица с результатами выглядит следующим образомэто -
## group value.x value.y diff type
## 19 A 81360 81353 7 low
## 20 A 81360 81367 -7 high
## 1 A 30000 24163 5837 low
## 8 A 40000 24163 15837 low
## 9 A 40000 80991 -40991 high
## 2 A 30000 80991 -50991 high
## 23 B 75000 76038 -1038 high
## 38 B 130000 126748 3252 low
## 22 B 75000 71721 3279 low
## 29 B 90000 76038 13962 low
## 30 B 90000 113186 -23186 high
## 39 B 130000 155556 -25556 high
Осталось сделать некоторые изменения формы и переименования, чтобы соответствовать формату ожидаемого результата df
-
library(reshape2)
x = dcast(x, group + value.x ~ type, value.var = "value.y")
names(x) = gsub(".x", "", names(x))
x = x[, c("group", "value", "low", "high")]
all.equal(x, df)
## [1] TRUE