2
\$\begingroup\$
library(tidyr)
d = seq(as.Date("2018-01-01"),Sys.Date()+365,by='day')
saturdayList = d[weekdays(d)=='Saturday']

altSaturdayList = data.frame(lapply(split(saturdayList, format(saturdayList, "%Y-%m")), function(x)
  na.omit(x[c(2,4)])))

altSaturdayList = subset(gather(altSaturdayList),select = c(value))
HolidayList = rbind(HolidayList, setNames(altSaturdayList, "Holidays"))
HolidayList = rbind(HolidayList, setNames(as.data.frame(as.Date("2018-11-06")), "Holidays"))
HolidayList = arrange(unique(HolidayList),Holidays)

rm(d)
rm(saturdayList)
rm(altSaturdayList)

The above code generates a list of dates which contain 2nd and 4th saturday of every month within that date range.

As you can tell I have generated and deleted intermediate variables like d, saturdayList and altSaturdayList. I was wondering how I can make this code better and efficient?

I learned about %>% operator but I don't know how I can do it with no input.

Any tips to improve the code is welcomed. Thanks

\$\endgroup\$
3
\$\begingroup\$

A pipe (%>%) solution is the following. I also use the dplyr-package, which you are probably already using as you have the arrange-function in your code. First I create a tibble with the days as input and then we can pipe ahead ;)

library(tidyr)
library(dplyr)

dates <- tibble(days = seq(as.Date("2018-01-01"), Sys.Date() + 365, by = 'day'))

HolidayList <- dates %>% 
  # Only keep Saturdays
  filter(weekdays(days) == 'Saturday') %>% 
  # Create a group variable (year_month) within we want to select the 2nd and 4th value
  group_by(year_month = format(days, "%Y-%m")) %>% 
  # Only keep the 2nd and 4th value in each year_month
  slice(c(2, 4)) %>% 
  # Get rid of the grouping 
  ungroup() %>% 
  # Only select the days column and rename it to Holidays
  select(Holidays = days) %>% 
  # Add the extra holiday 2018-11-06
  add_row(Holidays = as.Date("2018-11-06")) %>% 
  # similar to unique.data.frame(), but considerably faster:
  distinct() %>% 
  # Arrange ascending by Holidays
  arrange(Holidays)

HolidayList
# A tibble: 54 x 1
#      Holidays  
#        <date>    
#  1 2018-01-13
#  2 2018-01-27
#  3 2018-02-10
#  4 2018-02-24
#  5 2018-03-10
#  6 2018-03-24
#  7 2018-04-14
#  8 2018-04-28
#  9 2018-05-12
# 10 2018-05-26
# ... with 44 more rows
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.