Я пытаюсь создать сводную статистику для набора фильтров, которые работают в режиме опережения/отставания.
Краткое описание опережения/отставания:
Когда новый фильтр подключается к сети, он помещается в запаздывающее положение, что означает, что вода проходит через него после того, как она проходит через первичный (он же ведущий) фильтр. Когда опережающий фильтр засорен, текущий запаздывающий фильтр перемещается в лидирующее положение. Подводя итог, фильтр начинает с отставания, а затем переходит в опережение.
Визуально это можно представить так:
Что мне нужно сделать, так это суммировать все время, пока один фильтр был в сети, как в опережающей, так и в отстающей позиции.
Вот пример данных:
structure(list(record_timestamp = structure(c(1608192000, 1608192060,1608192120, 1608192180, 1608192240, 1608192300, 1608192360, 1608192420,1608192480, 1608192540, 1608192600, 1608192660, 1608192720, 1608192780,1608192840, 1608192900, 1608192960, 1608193020, 1608193080, 1608193140,1608193200, 1608193260, 1608193320, 1608193380, 1608193440, 1608193500,1608193560, 1608193620, 1608193680, 1608193740, 1608193800), class = c("POSIXct","POSIXt"), tzone = "UTC"), flow = c(20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10), lag_start = structure(c(1608192000,1608192000, 1608192000, 1608192000, 1608192000, 1608192000, 1608192000,1608192000, 1608192000, 1608192000, 1608192000, 1608192660, 1608192660,1608192660, 1608192660, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, 1608192660, 1608193260, 1608193260, 1608193260, 1608193260,1608193260, 1608193260, 1608193260, 1608193260, 1608193260, 1608193260), class = c("POSIXct", "POSIXt"), tzone = "UTC"), lead_start = c("#N/A","#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A", "#N/A","#N/A", "#N/A", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11","12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11","12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:11", "12/17/2020 8:21","12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21","12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21", "12/17/2020 8:21","12/17/2020 8:21")), class = c("spec_tbl_df", "tbl_df", "tbl","data.frame"), row.names = c(NA, -31L), spec = structure(list(cols = list(record_timestamp = structure(list(), class = c("collector_character","collector")), flow = structure(list(), class = c("collector_double","collector")), polish_start = structure(list(), class = c("collector_character", "collector")), lead_start = structure(list(), class = c("collector_character","collector"))), default = structure(list(), class = c("collector_guess","collector")), skip = 1), class = "col_spec"))
Моя идея состоит в том, чтобы «разложить» их и просто принять, что будут повторяющиеся временные метки, но каждая строка будет связана только с одним фильтром. Любые мысли о том, как это сделать? Невложенный DF будет выглядеть так:
structure(list(record_timestamp = structure(c(1608192000, 1608192060,1608192120, 1608192180, 1608192240, 1608192300, 1608192360, 1608192420,1608192480, 1608192540, 1608192600, 1608192660, 1608192720, 1608192780,1608192840, 1608192900, 1608192960, 1608193020, 1608193080, 1608193140,1608193200, 1608192660, 1608192720, 1608192780, 1608192840, 1608192900,1608192960, 1608193020, 1608193080, 1608193140, 1608193200, 1608193260,1608193320, 1608193380, 1608193440, 1608193500, 1608193560,1608193620,1608193680, 1608193740, 1608193800), class = c("POSIXct", "POSIXt"), tzone = "UTC"), flow = c(20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), lag_start = structure(c(1608192000, 1608192000, 1608192000,1608192000, 1608192000, 1608192000, 1608192000, 1608192000,1608192000,1608192000, 1608192000, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1608192660, 1608192660, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, 1608192660, 1608192660, 1608192660, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), class = c("POSIXct", "POSIXt"), tzone = "UTC"), lead_start = structure(c(NA, NA, NA, NA, NA, NA, NA, NA,NA, NA, NA, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, 1608192660, 1608192660, 1608192660, 1608192660,1608192660, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1608193260,1608193260, 1608193260, 1608193260, 1608193260, 1608193260,1608193260, 1608193260, 1608193260, 1608193260), class = c("POSIXct","POSIXt"), tzone = "UTC"), filter_id = c(1, 1, 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2)), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -41L), spec = structure(list(cols = list(record_timestamp = structure(list(), class = c("collector_character","collector")), flow = structure(list(), class = c("collector_double","collector")), polish_start = structure(list(), class = c("collector_character","collector")), lead_start = structure(list(), class = c("collector_character", "collector")), filter_id = structure(list(), class = c("collector_double","collector"))), default = structure(list(), class = c("collector_guess","collector")), skip = 1), class = "col_spec"))
Однако я понимаю, что это удвоит размер данных, с которыми я работаю, а это уже несколько лет одноминутных данных. Поэтому, если есть способ сделать это без удвоения меток времени, это было бы предпочтительнее.
Наконец, конечная цель состоит в том, чтобы иметь небольшой итоговый DF, который выглядит так:
Filter ID | Total Flow
----------------------------
1 | 370
2 | 250
... | ...
При этом вы получаете время начала и окончания для каждого фильтра или NA для фильтра, который используется в данный момент. Я предполагаю, что текущая дата-время может быть использована в качестве конечной точки для этих фильтров. Это помогает?
Спасибо за подробности. Пожалуйста, смотрите ответ ниже. Дает ли это желаемый результат? Или, пожалуйста, дайте мне знать, если я упустил некоторые другие детали.
Благодарим за предоставление дополнительной информации. Кажется, что вы могли бы group_by lag_start время в одиночестве. Затем вы можете рассчитать общее количество flow, находясь в этой позиции (с опережением или отставанием). После этого вы можете последовательно назначать номера фильтров, и тогда общий фильтр flow будет суммой flow как в текущей строке, так и в следующей строке. Дает ли это желаемый результат?
df %>%
group_by(lag_start) %>%
summarise(flow_per_position = sum(flow)) %>%
mutate(filter_id = row_number(),
total_filter_flow = flow_per_position + lead(flow_per_position, default = 0))
Выход
lag_start flow_per_position filter_id total_filter_flow
<dttm> <dbl> <int> <dbl>
1 2020-12-17 08:00:00 220 1 370
2 2020-12-17 08:11:00 150 2 250
3 2020-12-17 08:21:00 100 3 100
Спасибо! Это отвечает на главный вопрос, который мне был нужен. Однако теперь я понимаю, что мне может понадобиться «отключить» фильтры для упрощения построения графика, но это отдельный вопрос.
Изменены столбцы на POSIXct вместо chr. Для этого нет столбца. Что я могу сделать, так это вывести все интервалы для каждого фильтра. Например: данные %>% отличные(lag_start, .keep_all = TRUE) %>% mutate(changeout_interval = interval(lag_start, lead(lead_start)))