Раствор R.Все операторы merge
(и dplyr::*_join
) работают на равенстве, поэтому ваша первая проблема - преобразование вашего первого вектора в ближайший во втором.Функция findInterval
аналогична функции VLOOKUP
в Excel:
findInterval(v1df$v1, v2df$v2)
# [1] 0 1 1 1 1 1 2 2 2 2
. Здесь отображаются два артефакта:
- Первое значение имеет индекс
0
,указывая на то, что оно находится перед первым значением в v2
(ваш второй вектор). - Это не обеспечивает ближайший , оно является самым высоким без перехода.
Мы можем сдвинуть v2
для размещения.
d <- diff(v2df$v2)
units(d) <- "secs"
v2df$v2shift <- v2df$v2 - c(d[1], d)/2
v2df
# v2 v2shift
# 1 2016-01-01 05:07:00 2016-01-01 04:05:30
# 2 2016-01-01 07:10:00 2016-01-01 06:08:30
# 3 2016-01-01 08:19:00 2016-01-01 07:44:30
Теперь интервал работает:
findInterval(v1df$v1, v2df$v2shift)
# [1] 1 1 1 2 2 2 2 2 3 3
Теперь мы добавим это к первым данным:
v1df$closest <- v2df$v2[findInterval(v1df$v1, v2df$v2shift)]
v1df
# v1 closest
# 1 2016-01-01 05:00:00 2016-01-01 05:07:00
# 2 2016-01-01 05:10:00 2016-01-01 05:07:00
# 3 2016-01-01 05:20:00 2016-01-01 05:07:00
# 4 2016-01-01 06:40:00 2016-01-01 07:10:00
# 5 2016-01-01 06:50:00 2016-01-01 07:10:00
# 6 2016-01-01 07:00:00 2016-01-01 07:10:00
# 7 2016-01-01 07:10:00 2016-01-01 07:10:00
# 8 2016-01-01 07:20:00 2016-01-01 07:10:00
# 9 2016-01-01 08:00:00 2016-01-01 08:19:00
# 10 2016-01-01 08:10:00 2016-01-01 08:19:00
и объединим:
merge(v2df["v2"], v1df, by.x="v2", by.y="closest")
# v2 v1
# 1 2016-01-01 05:07:00 2016-01-01 05:00:00
# 2 2016-01-01 05:07:00 2016-01-01 05:10:00
# 3 2016-01-01 05:07:00 2016-01-01 05:20:00
# 4 2016-01-01 07:10:00 2016-01-01 06:40:00
# 5 2016-01-01 07:10:00 2016-01-01 06:50:00
# 6 2016-01-01 07:10:00 2016-01-01 07:00:00
# 7 2016-01-01 07:10:00 2016-01-01 07:10:00
# 8 2016-01-01 07:10:00 2016-01-01 07:20:00
# 9 2016-01-01 08:19:00 2016-01-01 08:00:00
# 10 2016-01-01 08:19:00 2016-01-01 08:10:00
Аналогично
dplyr::full_join(v2df["v2"], v1df, by=c("v2"="closest"))
Данные:
v1 <- as.POSIXct(c(
'01/01/2016 05:00',
'01/01/2016 05:10',
'01/01/2016 05:20',
'01/01/2016 06:40',
'01/01/2016 06:50',
'01/01/2016 07:00',
'01/01/2016 07:10',
'01/01/2016 07:20',
'01/01/2016 08:00',
'01/01/2016 08:10'), format='%m/%d/%Y %H:%M')
v2 <- as.POSIXct(c(
'01/01/2016 05:07',
'01/01/2016 07:10',
'01/01/2016 08:19'), format='%m/%d/%Y %H:%M')
v1df <- data.frame(v1 = v1)
v2df <- data.frame(v2 = v2)