#r
#r
Вопрос:
У меня есть два больших набора данных, один из которых имеет пару значение / временная метка a на очень коротком временном интервале, а другой — та же пара, но на дневном таймфрейме. Что я хотел бы сделать, так это применить дневное значение предыдущего дня к текущему дню на более низком таймфрейме. Например:
установите 1:
timestamp value
2019-10-03 23:24:00 2
2019-10-03 23:27:00 2
2019-10-03 23:30:00 3
2019-10-03 23:33:00 4
2019-10-03 23:36:00 4
2019-10-03 23:39:00 5
2019-10-03 23:42:00 5
2019-10-03 23:45:00 5
2019-10-03 23:48:00 5
2019-10-03 23:51:00 5
2019-10-03 23:54:00 5
2019-10-03 23:57:00 8
2019-10-04 0:00:00 8
2019-10-04 0:03:00 8
2019-10-04 0:06:00 8
2019-10-04 0:09:00 5
2019-10-04 0:12:00 5
2019-10-04 0:15:00 8
2019-10-04 0:18:00 6
2019-10-04 0:21:00 6
2019-10-04 0:24:00 6
2019-10-04 0:27:00 6
2019-10-04 0:30:00 7
2019-10-04 0:33:00 7
2019-10-04 0:36:00 7
2019-10-04 0:39:00 7
2019-10-04 0:42:00 7
установите 2:
date value2
2019-10-01 20
2019-10-02 40
2019-10-03 35
2019-10-04 14
2019-10-05 99
2019-10-06 23
2019-10-07 11
2019-10-08 67
2019-10-09 44
2019-10-10 32
2019-10-11 78
Желаемый результат:
timestamp value value2
2019-10-03 23:24:00 2 40
2019-10-03 23:27:00 2 40
2019-10-03 23:30:00 3 40
2019-10-03 23:33:00 4 40
2019-10-03 23:36:00 4 40
2019-10-03 23:39:00 5 40
2019-10-03 23:42:00 5 40
2019-10-03 23:45:00 5 40
2019-10-03 23:48:00 5 40
2019-10-03 23:51:00 5 40
2019-10-03 23:54:00 5 40
2019-10-03 23:57:00 8 40
2019-10-04 0:00:00 8 35
2019-10-04 0:03:00 8 35
2019-10-04 0:06:00 8 35
2019-10-04 0:09:00 5 35
2019-10-04 0:12:00 5 35
2019-10-04 0:15:00 8 35
2019-10-04 0:18:00 6 35
2019-10-04 0:21:00 6 35
2019-10-04 0:24:00 6 35
2019-10-04 0:27:00 6 35
2019-10-04 0:30:00 7 35
2019-10-04 0:33:00 7 35
2019-10-04 0:36:00 7 35
2019-10-04 0:39:00 7 35
2019-10-04 0:42:00 7 35
И это будет продолжаться и продолжаться в остальной части набора данных. Я был сосредоточен на dplyr и пытался заставить это работать и с помощью lubridate, но я не совсем уверен, как заставить все работать. Я также пытался преобразовать временные метки в разные факторы, чтобы они хорошо сочетались друг с другом, но я действительно не добился прогресса ни в одном направлении.
Комментарии:
1. Верен ли ваш
value2
«желаемый результат»? Разве они не должны быть35
такими14
? Если это правильно, я не понимаю, как это работает.2. Кроме того, была ли опечатка в том, что дни не были заполнены нулем в вашем наборе 2? Если это не было опечаткой, и ваши даты имеют разные форматы, то мое решение ниже не будет работать, и вам придется столкнуться с проблемой преобразования в даты, как показывает Ronak.
Ответ №1:
Вы можете вычесть -1 из даты в df1
и объединить данные с df2
помощью by date
.
library(dplyr)
library(lubridate)
df1 %>%
mutate(timestamp = ymd_hms(timestamp),
date = as.Date(timestamp) - 1) %>%
left_join(df2 %>% mutate(date = ymd(date)), by ='date')
Это возвращает
# timestamp value date value2
#1 2019-10-03 23:24:00 2 2019-10-02 40
#2 2019-10-03 23:27:00 2 2019-10-02 40
#3 2019-10-03 23:30:00 3 2019-10-02 40
#4 2019-10-03 23:33:00 4 2019-10-02 40
#5 2019-10-03 23:36:00 4 2019-10-02 40
#6 2019-10-03 23:39:00 5 2019-10-02 40
#7 2019-10-03 23:42:00 5 2019-10-02 40
#8 2019-10-03 23:45:00 5 2019-10-02 40
#9 2019-10-03 23:48:00 5 2019-10-02 40
#10 2019-10-03 23:51:00 5 2019-10-02 40
#11 2019-10-03 23:54:00 5 2019-10-02 40
#12 2019-10-03 23:57:00 8 2019-10-02 40
#13 2019-10-04 00:00:00 8 2019-10-03 35
#14 2019-10-04 00:03:00 8 2019-10-03 35
#15 2019-10-04 00:06:00 8 2019-10-03 35
#16 2019-10-04 00:09:00 5 2019-10-03 35
#17 2019-10-04 00:12:00 5 2019-10-03 35
#18 2019-10-04 00:15:00 8 2019-10-03 35
#19 2019-10-04 00:18:00 6 2019-10-03 35
#20 2019-10-04 00:21:00 6 2019-10-03 35
#21 2019-10-04 00:24:00 6 2019-10-03 35
#22 2019-10-04 00:27:00 6 2019-10-03 35
#23 2019-10-04 00:30:00 7 2019-10-03 35
#24 2019-10-04 00:33:00 7 2019-10-03 35
#25 2019-10-04 00:36:00 7 2019-10-03 35
#26 2019-10-04 00:39:00 7 2019-10-03 35
#27 2019-10-04 00:42:00 7 2019-10-03 35
В базовом R вы можете написать тот же код, что и :
df1$timestamp <- as.POSIXct(df1$timestamp, format = '%Y-%m-%d %T', tz = 'UTC')
df1$date <- as.Date(df1$timestamp) - 1
df2$date <- as.Date(df2$date)
merge(df1, df2, by = 'date')
Комментарии:
1. Блестяще. Я сделал эту проблему намного сложнее, чем нужно. Спасибо за помощь!
Ответ №2:
Если вы не хотите утруждать себя преобразованием своих строк в даты, вы можете использовать регулярные выражения:
df1$date <- sub("(.*) .*", "\1", df1$timestamp)
result <- merge(df1, df2, by = "date")
result$date <- NULL
Демонстрация с минимальными данными:
df1 <- data.frame(
timestamp = c("2019-10-03 23:24:00", "2019-10-03 23:27:00", "2019-10-04 0:15:00"),
value = c(2, 2, 8)
)
df2 <- data.frame(
date = c("2019-10-01", "2019-10-03", "2019-10-04"),
value2 = c(20, 35, 14)
)
df1$date <- sub("(.*) .*", "\1", df1$timestamp)
result <- merge(df1, df2, by = 'date')
result$date <- NULL
Вывод:
> result
timestamp value value2
1 2019-10-03 23:24:00 2 35
2 2019-10-03 23:27:00 2 35
3 2019-10-04 0:15:00 8 14