Count the number of Fridays or Mondays in Month in R

1) Here d is the input, a Date class object, e.g. d <- Sys.Date(). The result gives the number of Fridays in the year/month that contains d. Replace 5 with 1 to get the number of Mondays:

first <- as.Date(cut(d, "month"))
last <- as.Date(cut(first + 31, "month")) - 1
sum(format(seq(first, last, "day"), "%w") == 5)

2) Alternately replace the last line with the following line. Here, the first term is the number of Fridays from the Epoch to the next Friday on or after the first of the next month and the second term is the number of Fridays from the Epoch to the next Friday on or after the first of d's month. Again, we replace all 5's with 1's to get the count of Mondays.

ceiling(as.numeric(last + 1 - 5 + 4) / 7) - ceiling(as.numeric(first - 5 + 4) / 7)

The second solution is slightly longer (although it has the same number of lines) but it has the advantage of being vectorized, i.e. d could be a vector of dates.

UPDATE: Added second solution.


There are a number of ways to do it. Here is one:

countFridays <- function(y, m) { 
    fr <- as.Date(paste(y, m, "01", sep="-")) 
    to <- fr + 31       
    dt <- seq(fr, to, by="1 day")      
    df <- data.frame(date=dt, mon=as.POSIXlt(dt)$mon, wday=as.POSIXlt(dt)$wday)  
    df <- subset(df, df$wday==5 & df$mon==df[1,"mon"])         
    return(nrow(df))     
}

It creates the first of the months, and a day in the next months.

It then creates a data frame of month index (on a 0 to 11 range, but we only use this for comparison) and weekday.

We then subset to a) be in the same month and b) on a Friday. That is your result set, and we return the number of rows as your anwser.

Note that this only uses base R code.


Without using lubridate -

#arguments to pass to function:
whichweekday <- 5
whichmonth <- 11
whichyear <- 2013

#function code:    
firstday <- as.Date(paste('01',whichmonth,whichyear,sep="-"),'%d-%m-%Y')
lastday <- if(whichmonth == 12) { '31-12-2013' } else {seq(as.Date(firstday,'%d-%m-%Y'), length=2, by="1 month")[2]-1}
sum(
  strftime(
seq.Date(
  from = firstday,
  to = lastday,
  by = "day"),
'%w'
) == whichweekday)

Tags:

R

Lubridate