Как связать все случаи определенного дня недели в данном году-месяце в набор данных R - PullRequest
0 голосов
/ 07 мая 2020

У меня есть данные, которые включают дату и день недели.

  • Я хотел бы идентифицировать все экземпляры определенного дня недели, которые соответствуют данному году / месяцу / дню недели в исходных данных. Например, если первая запись имеет дату «2010-07-05», то есть четверг, я хочу привязать все четверги, которые происходят в июле 2010 года, к моему исходному набору данных.
  • При добавлении этих новых строк Я также хочу заполнить эти новые строки значениями из исходных данных для всех столбцов, кроме одного. Исключением является переменная, которая указывает, была ли эта строка в исходном наборе данных или нет.

Пример данных:

(1) всегда - эти данные включают все даты и будние дни для соответствующих лет.

(2) dt1 - это пример набора данных, который включает дату Adate и день недели dow, который будет использоваться для определения года / месяца / дня недели а затем найдите все даты в том же месяце для данного дня недели. Например, по всем четвергам в июле 2017 года необходимо будет привязать строку к исходным данным.

library(data.table)
library(tidyverse)
library(lubridate)

alldays <- data.table (date = seq(as.Date("2010-01-01"),
                                  as.Date("2011-12-31"), by="days"))
alldays <- alldays %>%
  dplyr::mutate(year = lubridate::year(date), 
                month = lubridate::month(date), 
                day = lubridate::day(date),
                dow = weekdays(date))
setDT(alldays)
head(alldays)
        date year month day       dow
1 2010-01-01 2010     1   1    Friday
2 2010-01-02 2010     1   2  Saturday
3 2010-01-03 2010     1   3    Sunday
4 2010-01-04 2010     1   4    Monday
5 2010-01-05 2010     1   5   Tuesday
6 2010-01-06 2010     1   6 Wednesday

Вот пример основного набора данных

id <- seq(1:2)
admit <- rep(1,2)
zip <- c(54123, 54789)
Adate <- as.Date(c("2010-07-15","2011-03-14"))
year <- c(2010, 2011)
month <- c(7,3)
day <- c(15,14)
dow <- c("Thursday","Monday")
dt1 <- data.table(id, admit, zip, Adate, year, month, day, dow)
dt1
#>    id admit   zip      Adate year month day      dow
#> 1:  1     1 54123 2010-07-15 2010     7  15 Thursday
#> 2:  2     1 54789 2011-03-14 2011     3  14   Monday

Результирующий набор данных должен быть :

   id admit   zip      Adate year month day      dow
1:  1     0 54123 2010-07-01 2010     7   1 Thursday
2:  1     0 54123 2010-07-08 2010     7   8 Thursday
3:  1     1 54123 2010-07-15 2010     7  15 Thursday
4:  1     0 54123 2010-07-22 2010     7  22 Thursday
5:  1     0 54123 2010-07-29 2010     7  29 Thursday
6:  2     0 54789 2011-03-07 2011     3   7   Monday
7:  2     1 54789 2011-03-14 2011     3  14   Monday
8:  2     0 54789 2011-03-21 2011     3  21   Monday
9:  2     0 54789 2011-03-28 2011     3  28   Monday

Итак, мы видим, что первая дата dt1 2010-07-15, связанная с id = 1, который был четвергом, выпал на месяц с 4 дополнительными четвергами в этом месяце, которые были добавлены к набору данных. Переменная admit является индикатором того, была ли эта строка в оригинале или добавлена ​​впоследствии в силу сопоставления.

Я попытался сначала выбрать дополнительные даты из alldays с соответствующими днями недели, но я возникли проблемы с тем, как связать их обратно в исходный набор данных при правильном заполнении других значений. В конце концов я буду запускать это с набором данных примерно из 300 000 строк.

1 Ответ

0 голосов
/ 07 мая 2020

Вот вариант:

alldays[dt1[, .(id, zip, admit=0L, year, month, dow)], 
    on=.(year, month, dow), allow.cartesian=TRUE][
        dt1, on=.(id, date=Adate), admit := i.admit][]

вывод:

         date year month day      dow id   zip admit
1: 2010-07-01 2010     7   1 Thursday  1 54123     0
2: 2010-07-08 2010     7   8 Thursday  1 54123     0
3: 2010-07-15 2010     7  15 Thursday  1 54123     1
4: 2010-07-22 2010     7  22 Thursday  1 54123     0
5: 2010-07-29 2010     7  29 Thursday  1 54123     0
6: 2011-03-07 2011     3   7   Monday  2 54789     0
7: 2011-03-14 2011     3  14   Monday  2 54789     1
8: 2011-03-21 2011     3  21   Monday  2 54789     0
9: 2011-03-28 2011     3  28   Monday  2 54789     0
...