Как агрегировать неполные недели в R - PullRequest
0 голосов
/ 31 октября 2018

Существует множество отличных способов объединить данные, основанные на отметках времени, в недели. Но у меня очень сложный вопрос, сводящий неполную неделю. Я погуглил это в течение нескольких дней, ломал голову и находил некоторые действительно трудные и уродливые способы решить это с помощью программирования для цикла. Должно быть элегантное решение с использованием Tidyverse.

Допустим, у меня есть журналы наблюдений за птицами в формате отметки времени. Два столбца: отметка времени, имя птицы

Подсчет по неделям легко агрегировать, как

birds_per_week<- data %>%  group_by(week = cut(timestamp, "week", start.on.monday = TRUE)) %>%   summarise(n())

Но у меня очень сложный вопрос, я хочу узнать количество неполных недель 1009 *. Допустим, сегодня в понедельник 10:00, и я хочу знать все еженедельные подсчеты с 10:00 до 12:00 по средам. Это окно 2 дня 2 часа. В моей проблеме конечной точкой всегда является среда в полдень, но исходная точка меняется.

Ответы [ 2 ]

0 голосов
/ 31 октября 2018
library(lubridate)
library(tidyverse)

df1 <- data.frame(timestamp = structure(c(1540505400, 1539802080, 1538778660, 1538417640, 1538691660, 
1538790780, 1538705100, 1539614520, 1539893280, 1539455520, 1540343580, 
1540178220, 1538628960, 1539533280, 1539572700, 1538823480, 1538967480, 
1538468400, 1540425600, 1539809880), class = c("POSIXct", "POSIXt"
), tzone = ""))

Первая часть дня и часа:

df1$day <- weekdays(df1$timestamp)
df1$hour <- hour(df1$timestamp)

Затем отфильтруйте наши три дня, затем исключите часы начала и окончания понедельника / среды:

df1 <- df1 %>% filter(day %in% c("Monday", "Tuesday", "Wednesday")) %>% 
  filter(!(day == "Monday" & hour < 10)) %>% 
  filter(!(day == "Wednesday" & hour > 12))

df1$week <- week(df1$timestamp)

Затем используйте week в качестве группы:

df1 %>% group_by(week) %>% summarize(count = n())

# A tibble: 3 x 2
   week count
  <int> <int>
1    40     2
2    42     1
3    43     1
0 голосов
/ 31 октября 2018

Кажется, один из подходов - записать «полдень следующей среды» для каждой строки, а затем подсчитать их.

library(lubridate); library(dplyr)

times_to_test <- data.frame(times = seq.POSIXt(from = ymd_h(2018102400),
                            to   = ymd_h(2018110123), by = "hour"))

times_to_test %>%
  # For checking, helps to see which days are wednesdays
  mutate(weekday = wday(times, label = T)) %>%
  # Wednesday noon is 3.5 days (84 hours) into the week
  mutate(next_Wed_noon = floor_date(times + dhours(84), "1 week") + 
           dhours(84)) %>%
  count(next_Wed_noon)

# A tibble: 3 x 2
  next_Wed_noon           n
  <dttm>              <int>
1 2018-10-24 12:00:00    12
2 2018-10-31 12:00:00   168
3 2018-11-07 12:00:00    36
...