Возможный подход с data.table
(адаптация из моего ответа здесь ):
# load packages
library(data.table)
# create a function which calculates match-score with 'df2$Value'
maxscore <- function(x, y) {
m <- mapply('==', shift(x, type = 'lead', n = 0:(length(y) - 1)), y)
max(rowSums(m, na.rm = TRUE))
}
# calculate the match-score for each group
# and filter out the other groups
setDT(df1)[, score := maxscore(Value, df2$Value), by = ID
][score == max(score)][, score := NULL][]
, что дает:
ID Value
1: 1 apples
2: 1 apples
3: 1 bananas
4: 1 grapes
5: 1 mangoes
6: 1 oranges
7: 1 grapes
8: 1 apples
9: 1 grapes
Вы также можете использовать эту функцию в dplyr
-цепи (но вам все равно понадобится пакет data.table
для shift
-функции):
library(dplyr)
df1 %>%
group_by(ID) %>%
mutate(m = maxscore(Value, df2$Value)) %>%
ungroup() %>%
filter(m == max(m)) %>%
select(-m)
Альтернативная реализация maxscore
-функции (вдохновленный ответом @ doscendo здесь ):
maxscore2 <- function(x, y) {
w <- which(x == y[1])
v <- sapply(w, function(i) sum(x[i:(i+(length(y)-1))] == y, na.rm = TRUE))
max(v)
}