Если я правильно понимаю, ОП запросил сначала попытку сопоставления a
с x1
, а затем - если не удалось - попытаться сопоставить a
с x2
.Поэтому любое совпадение a
с x1
должно иметь приоритет над совпадением a
с x2
.
К сожалению, примерный набор данных, предоставленный OP, не не включить случай использования, чтобы доказать это.Поэтому я соответственно изменил образец набора данных (см. Раздел Данные ).
Предлагаемый здесь подход заключается в изменении формы df2
из широкого в длинный формат (аналогично ответу MrFlick), но для использования data.table
объединения с параметром mult = "first"
.
Столбцы df2
, которые следует рассматривать как ключевые столбцы , и приоритет можно контролировать с помощью параметра measure.vars
для melt()
.После изменения формы melt()
упорядочивает строки в порядке столбцов, заданном в measure.vars
:
library(data.table)
# define cols of df2 to use as key in order of
key_cols <- c("x1", "x2")
# reshape df2 from wide to long format
long <- melt(setDT(df2), measure.vars = key_cols, value.name = "a")
# join long with df1, pick first matches
result <- long[setDT(df1), on = "a", mult = "first"]
# clean up
setcolorder(result, names(df1))
result[, variable := NULL]
result
a b c x3
1: 5 T F w
2: 1 T T t
3: 7 T F g
4: 3 F F t
5: 0 F F <NA>
Обратите внимание, что исходный порядок строк df1
имеетбыли сохранены.
Также обратите внимание, что код работает для произвольного числа ключевых столбцов.Приоритет ключевых столбцов может быть легко изменен.Например, если порядок обратный, т. Е. Сначала будет выбрано key_cols <- c("x2", "x1")
совпадений a
с x2
.
Данные
Расширенные образцы наборов данных:
У df1
есть дополнительная строка без совпадения в df2
.
df1 <- data.frame(a=c(5,1,7,3,0),
b=c("T","T","T","F","F"),
c=c("F","T","F","F","F"))
df1
a b c
1: 5 T F
2: 1 T T
3: 7 T F
4: 3 F F
5: 0 F F
df2
имеет дополнительную строку, чтобы доказать, что совпадение в x1
имеет приоритет над совпадением в x2
.Значение 5
появляется дважды: в строке 2 столбца x1
и в строке 5 столбца x2
.
df2 <- data.frame(x1=c(4,5,3,9,6),
x2=c(7,8,1,2,5),
x3=c("g","w","t","o","n"))
df2
x1 x2 x3
1: 4 7 g
2: 5 8 w
3: 3 1 t
4: 9 2 o
5: 6 5 n