Найдите ближайшую дату между набором данных1 и набором данных2

У меня есть два набора данных. Один собирается примерно каждые 5 дней, а другой — каждые 15 минут ежедневно. Мне нужен окончательный список, который соответствует ближайшей дате из менее частого набора данных к записи в более частом.

Например:

satDat <- c('2015-04-16', '2015-04-21', '2012-04-26') # collected every 5 days

stationDat <- sort(rep(seq(as.Date("2015-04-01"), as.Date("2015-04-20"), by='day'),2)) 
#collected multiple times a day

 [1] "2015-04-01" "2015-04-01" "2015-04-02" "2015-04-02" "2015-04-03"
 [6] "2015-04-03" "2015-04-04" "2015-04-04" "2015-04-05" "2015-04-05"
[11] "2015-04-06" "2015-04-06" "2015-04-07" "2015-04-07" "2015-04-08"
[16] "2015-04-08" "2015-04-09" "2015-04-09" "2015-04-10" "2015-04-10"
[21] "2015-04-11" "2015-04-11" "2015-04-12" "2015-04-12" "2015-04-13"
[26] "2015-04-13" "2015-04-14" "2015-04-14" "2015-04-15" "2015-04-15"
[31] "2015-04-16" "2015-04-16" "2015-04-17" "2015-04-17" "2015-04-18"
[36] "2015-04-18" "2015-04-19" "2015-04-19" "2015-04-20" "2015-04-20"

Я хочу, чтобы мои результаты выглядели так

[1] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
[6] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
[11] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
[16] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" 
[21] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
[26] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
[31] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
[36] "2015-04-16" "2015-04-21" "2015-04-21" "2015-04-21" "2015-04-21"

person Christiana A    schedule 12.02.2017    source источник
comment
Ответ на этот вопрос помощь?   -  person conrad-mac    schedule 12.02.2017
comment
satDat[apply(abs(outer(satDat, stationDat, difftime, units = 'days')), 2, which.min)], хотя я подозреваю, что есть более элегантный вариант   -  person alistaire    schedule 12.02.2017
comment
Поскольку один из векторов отсортирован, вы можете воспользоваться cut, чтобы сузить возможные даты для проверки, чтобы решение @alistaire не было таким взрывоопасным. (Конечно, это было бы больше кода, но очень полезно, если ваши данные достаточно велики.)   -  person r2evans    schedule 12.02.2017
comment
@alistaire Мне нравится ваше решение, однако, как только вы измените stationDat на более длинный временной ряд, скажем, stationDat ‹- sort (rep (seq (as.Date (2015-04-01), as.Date (2015-05-26) , by='day'),2)) Последние числа - это просто 2015-04-21, где мне нужно, чтобы они были 2015-04-26. Можете ли вы объяснить, что вы сделали?   -  person Christiana A    schedule 12.02.2017
comment
2015-04-26 нет в satDat; у него 2012-04-26, что будет далеко не все...опечатка? В любом случае, outer сравнивает каждую комбинацию двух векторов с предоставленной функцией, здесь difftime, и возвращает матрицу, на которой abs отбрасывает отрицательные значения. apply выполняет итерацию по столбцам (поле 2) и применяет which.min, который возвращает индекс наименьшего из них, которые используются для подмножества satDat. Если это была опечатка, я могу добавить ее в качестве ответа с полным объяснением, поскольку альтернативы не предвидится.   -  person alistaire    schedule 12.02.2017
comment
@alistaire Спасибо, что заметили это. Да, это была опечатка. Спасибо за ваше объяснение.   -  person Christiana A    schedule 12.02.2017


Ответы (2)


Вариант с использованием outer:

satDat[apply(abs(outer(satDat, stationDat, difftime, units = 'days')), 2, which.min)]

#>  [1] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#>  [6] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#> [11] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#> [16] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#> [21] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#> [26] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#> [31] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#> [36] "2015-04-16" "2015-04-21" "2015-04-21" "2015-04-21" "2015-04-21"

Как это работает:

  • outer принимает применение difftime к каждой паре элементов в двух векторах, возвращая матрицу,
  • над которым apply перебирает столбцы (MARGIN = 2), вызывая which.min для каждого, который возвращает индекс наименьшего,
  • который используется для подмножества satDat.

Обратите внимание, что outer выделяет матрицу размерами length(satDat) на length(stationDat), что может потребовать много памяти, если ваши данные уже велики.

person alistaire    schedule 13.02.2017

На ум приходит скользящее соединение, предлагаемое пакетом data.table.

library(data.table)
DT1 <- data.table(date = as.Date(satDat), date1 = as.Date(satDat))
DT2 <- data.table(date = stationDat)

DT1[DT2, date1, roll = "nearest", on = .(date)]
# [1] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
# [7] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#[13] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#[19] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#[25] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#[31] "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16" "2015-04-16"
#[37] "2015-04-21" "2015-04-21" "2015-04-21" "2015-04-21"

Это, вероятно, также полезно для любой вашей реальной задачи, потому что я подозреваю, что это выходит за рамки этого.

person Roland    schedule 12.02.2017