Найти минимальное расстояние между двумя фреймами данных для каждого элемента во втором фрейме данных

У меня есть два фрейма данных ev1 и ev2, описывающих временные метки двух типов событий, собранных во многих тестах. Итак, каждый фрейм данных имеет столбцы «test_id» и «timestamp». Мне нужно найти минимальное расстояние ev1 для каждого ev2 в том же тесте.

У меня есть рабочий код, который объединяет два набора данных, вычисляет расстояния, а затем использует dplyr для фильтрации минимального расстояния:

ev1 = data.frame(test_id = c(0, 0, 0, 1, 1, 1), time=c(1, 2, 3, 2, 3, 4))
ev2 = data.frame(test_id = c(0, 0, 0, 1, 1, 1), time=c(6, 1, 8, 4, 5, 11))

data <- merge(ev2, ev1, by=c("test_id"), suffixes=c(".ev2", ".ev1"))

data$distance <- data$time.ev2 - data$time.ev1

min_data <- data %>%
  group_by(test_id, time.ev2) %>%
  filter(abs(distance) == min(abs(distance)))

Хотя это работает, часть слияния очень медленная и чувствует себя неэффективно - я создаю огромную таблицу со всеми комбинациями ev2-> ev1 для того же test_id, только чтобы отфильтровать ее до одного. Кажется, должен быть способ «фильтровать на лету» во время слияния. Есть?

Обновить: В следующем случае с двумя столбцами «group by» происходит сбой при использовании подхода data.table, описанного akrun:

ev1 = data.frame(test_id = c(0, 0, 0, 1, 1, 1), time=c(1, 2, 3, 2, 3, 4), group_id=c(0, 0, 0, 1, 1, 1))
ev2 = data.frame(test_id = c(0, 0, 0, 1, 1, 1), time=c(5, 6, 7, 1, 2, 8), group_id=c(0, 0, 0, 1, 1, 1))
setkey(setDT(ev1), test_id, group_id)
DT <- ev1[ev2, allow.cartesian=TRUE][,distance:=abs(time-i.time)]

Ошибка в eval (expr, envir, enclos): объект 'i.time' не найден

Ответы на вопрос(2)

Ваш ответ на вопрос