【发布时间】:2015-02-12 12:00:56
【问题描述】:
我有两个数据框 ev1 和 ev2,描述了在许多测试中收集的两种类型事件的时间戳。因此,每个数据框都有“test_id”和“timestamp”列。我需要找到的是在同一个测试中,每个 ev2 的 ev1 的最小距离。
我有一个工作代码可以合并两个数据集,计算距离,然后使用 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)))
虽然这可行,但合并部分非常慢并且感觉效率低下 - 我正在生成一个巨大的表,其中包含相同 test_id 的所有 ev2->ev1 组合,只是将其过滤为一个。在合并期间,似乎应该有一种“动态过滤”的方法。有没有?
更新:当使用 akrun 概述的 data.table 方法时,以下带有两个“分组依据”列的情况会失败:
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”
【问题讨论】:
-
你试过
left_join(ev2,ev1, by=c("test_id") )而不是merge吗? -
@Khashaa 不,我没有。我现在试了一下,它的速度无限快。它只是对同一件事的更好实现,还是发生了其他事情?
-
@Stan 您是否尝试过
data.table方法。它应该很快。 -
@Stan 它是
merge(., all.x=TRUE)的dplyr类似物。