Страницы

Поиск по вопросам

среда, 12 февраля 2020 г.

синхронизация трех датафреймов по времени

#r


Есть три датафрейма немного разной длинны потому что наблюдения велись начиная с
разного времени,

как их можно синхронизировать по времени чтоб оставить только те наблюдения которые
есть во всех трех фреймах и выкинуть те которые попадаются только в отдельных фреймах 

вот сами дата фреймы

> head(sec1)
        date  time   open   high    low  close vol
1 2016.09.06 08:45 3081.5 3082.5 3080.5 3080.5   6
2 2016.09.06 08:50 3081.5 3081.5 3079.5 3080.5   6
3 2016.09.06 08:55 3081.5 3082.5 3081.5 3082.5  19
4 2016.09.06 09:00 3083.5 3083.5 3081.5 3082.5  19
5 2016.09.06 09:05 3083.5 3085.5 3082.5 3085.5   8
6 2016.09.06 09:10 3086.5 3086.5 3084.5 3086.5  15
> head(sec2)
        date  time  open  high   low close vol
1 2016.09.13 13:00 95.34 95.40 95.33 95.39  36
2 2016.09.13 13:05 95.40 95.43 95.39 95.41  40
3 2016.09.13 13:10 95.42 95.44 95.40 95.42  37
4 2016.09.13 13:15 95.41 95.42 95.39 95.39  25
5 2016.09.13 13:20 95.40 95.41 95.38 95.38  21
6 2016.09.13 13:25 95.39 95.42 95.38 95.42  32
> head(sec3)
        date  time    open    high     low   close vol
1 2016.09.14 18:10 1.12433 1.12456 1.12431 1.12450 137
2 2016.09.14 18:15 1.12444 1.12459 1.12424 1.12455 139
3 2016.09.14 18:20 1.12454 1.12477 1.12446 1.12469 148
4 2016.09.14 18:25 1.12468 1.12474 1.12442 1.12453 120
5 2016.09.14 18:30 1.12452 1.12483 1.12442 1.12482 156
6 2016.09.14 18:35 1.12481 1.12499 1.12472 1.12474 126


Те на выходе должно получиться три датафрейма одинаковой длинны (nrow) и все строчки
датафреймов должны иметь одинаковую дату и время
    


Ответы

Ответ 1



Если я правильно понял задачу, то нужно определить пересекающиеся интервалы дат и времени и отфильтровать наблюдения, попадающие в эти интервалы. Омечу, что приведённые в качестве примера данные не пересекаются по датам. Определим границы для дат: min_date <- list(df1, df2, df3) %>% sapply(. %>% .subset2("date") %>% as.Date(format = "%Y.%m.%d") %>% min()) %>% max() max_date <- list(df1, df2, df3) %>% sapply(. %>% .subset2("date") %>% as.Date(format = "%Y.%m.%d") %>% max()) %>% min() Теперь то же самое для времени: min_time <- list(df1, df2, df3) %>% sapply(. %>% .subset2("time") %>% as.POSIXct(format = "%H:%M") %>% min()) %>% max() max_time <- list(df1, df2, df3) %>% sapply(. %>% .subset2("time") %>% as.POSIXct(format = "%H:%M") %>% min()) %>% min() Теперь можно отфильтровать наблюдения: df1 <- df1 %>% mutate(date = as.Date(date, format = "%Y.%m.%d")) %>% filter(date >= min_date & date <= max_date) %>% mutate(time = as.POSIXct(time, format = "%H:%M")) %>% filter(time >= min_time & time <= max_time) Чтобы код работал, нужно загрузить пакет dplyr.

Ответ 2



Насколько я понимаю, задача сводится к тому, чтобы оставить в каждом датасете только те наблюдения, для которых есть наблюдения с аналогичными значениями date и time в двух других датасетах. Мне видится самым простым решением такое: слить вместе все три датасета сгруппировать наблюдения по переменным date и time посчитать количество наблюдений в группах оставить только те сочетания date и time, которые встречаются 3 раза отфильтровать исходные датасеты по датасету пересекающихся наблюдений Код (не проверял - лень генерировать исходные датасеты; напишите, если где-то что-то упустил, и не работает) library(tidyverse) df_cross <- bind_rows(df1, df2, df3) %>% group_by(date,time) %>% summarise(occurance = n()) %>% ungroup() %>% filter(occurance == 3) %>% select(-occurance) df1_refined <- left_join(df_cross, df1, by = c('date', 'time')) UPD все оказалось еще проще df_cross <- intersect(df1 %>% select(date,time), df2 %>% select(date,time), df3 %>% select(date,time)) df1_refined <- left_join(df_cross, df1, by = c('date', 'time'))

Комментариев нет:

Отправить комментарий