lubridate - 选择每周的第一个非星期一。

时间:2017-01-11 08:12:22

标签: r dplyr lubridate tidyverse

有一小部分财务数据,我想通过选择每周的第一个非星期一来过滤它。通常它将是星期二,但有时它可以是星期三,如果星期二是假日。

这是我的代码在大多数情况下都适用

XLF <- quantmod::getSymbols("XLF", from = "2000-01-01", auto.assign = FALSE)

library(tibble)
library(lubridate)
library(dplyr)
xlf <- as_tibble(XLF) %>% rownames_to_column(var = "date") %>% 
         select(date, XLF.Adjusted)  
xlf$date <- ymd(xlf$date)

# We create Month, Week number and Days of the week columns
# Then we remove all the Mondays
xlf <- xlf %>% mutate(Year = year(date), Month = month(date), 
                      IsoWeek = isoweek(date), WDay = wday(date)) %>% 
               filter(WDay != 2)

# Creating another tibble just for ease of comparison
xlf2 <- xlf %>% 
          group_by(Year, IsoWeek) %>% 
          filter(row_number() == 1) %>% 
          ungroup()

也就是说,到目前为止我还有一些问题无法解决。

问题是例如它正在跳过“2002-12-31”这是一个星期二,因为它被认为是2003年第一个ISO周的一部分。 还有一些类似的问题 我的问题是如何在停留在tidyverse(即不必使用xts / zoo类)时选择每周的第一个非星期一而没有这些问题?

1 个答案:

答案 0 :(得分:2)

您可以自己创建一个不断增加的周数。也许不是最优雅的解决方案,但它对我来说很好。

as_tibble(XLF) %>% 
  rownames_to_column(var = "date")%>% 
  select(date, XLF.Adjusted)%>%
  mutate(date = ymd(date),
         Year = year(date),
         Month = month(date),
         WDay = wday(date),
         WDay_label = wday(date, label = T))%>% 
  # if the weekday number is higher in the line above or 
  # if the date in the previous line is more than 6 days ago
  # the week number should be incremented
  mutate(week_increment  = (WDay < lag(WDay) | difftime(date, lag(date), unit = 'days') > 6))%>%
  # the previous line causes the first element to be NA due to 
  # the fact that the lag function can't find a line above
  # we correct this here by setting the first element to TRUE
  mutate(week_increment = ifelse(row_number() == 1,
                                 TRUE,
                                 week_increment))%>%
  # we can sum the boolean elements in a cumulative way to get a week number
  mutate(week_number = cumsum(week_increment))%>%
  filter(WDay != 2)%>%
  group_by(Year, week_number) %>% 
  filter(row_number() == 1)