DeduciveR
DeduciveR

Reputation: 1702

Calculating first and last day of month from a yearmon object

I have a simple df with a column of dates in yearmon class:

df <- structure(list(year_mon = structure(c(2015.58333333333, 2015.66666666667, 
                                  2015.75, 2015.83333333333, 2015.91666666667, 2016, 2016.08333333333, 
                                  2016.16666666667, 2016.25, 2016.33333333333), class = "yearmon")), class = c("tbl_df", 
                                                                                                               "tbl", "data.frame"), row.names = c(NA, -10L))

I'd like a simple way, preferably using base R, lubridate or xts / zoo to calculate the first and last days of each month.

I've seen other packages that do this, but I'd like to stick with the aforementioned if possible.

Upvotes: 1

Views: 640

Answers (3)

G. Grothendieck
G. Grothendieck

Reputation: 269654

Use as.Date.yearmon from zoo as shown. frac specifies the fractional amount through the month to use so that 0 is beginning of the month and 1 is the end. The default value of frac is 0.

You must already be using zoo if you are using yearmon (since that is where the yearmon methods are defined) so this does not involve using any additional packages beyond what you are already using.

If you are using dplyr, optionally replace transform with mutate.

transform(df, first = as.Date(year_mon), last = as.Date(year_mon, frac = 1))

gives:

   year_mon      first       last
1  Aug 2015 2015-08-01 2015-08-31
2  Sep 2015 2015-09-01 2015-09-30
3  Oct 2015 2015-10-01 2015-10-31
4  Nov 2015 2015-11-01 2015-11-30
5  Dec 2015 2015-12-01 2015-12-31
6  Jan 2016 2016-01-01 2016-01-31
7  Feb 2016 2016-02-01 2016-02-29
8  Mar 2016 2016-03-01 2016-03-31
9  Apr 2016 2016-04-01 2016-04-30
10 May 2016 2016-05-01 2016-05-31

Upvotes: 1

akrun
akrun

Reputation: 887148

We can use

library(dplyr)
library(lubridate)
library(zoo)
df %>% 
   mutate(firstday = day(year_mon), last = day(as.Date(year_mon, frac = 1)))

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 388982

Using base R, you could convert the yearmon object to date using as.Date which would give you the first day of the month. For the last day, we could increment the date by a month (1/12) and subtract 1 day from it.

df$first_day <- as.Date(df$year_mon)
df$last_day <- as.Date(df$year_mon + 1/12) - 1
df  

#   year_mon      first_day  last_day  
#   <S3: yearmon> <date>     <date>    
# 1 Aug 2015      2015-08-01 2015-08-31
# 2 Sep 2015      2015-09-01 2015-09-30
# 3 Oct 2015      2015-10-01 2015-10-31
# 4 Nov 2015      2015-11-01 2015-11-30
# 5 Dec 2015      2015-12-01 2015-12-31
# 6 Jan 2016      2016-01-01 2016-01-31
# 7 Feb 2016      2016-02-01 2016-02-29
# 8 Mar 2016      2016-03-01 2016-03-31
# 9 Apr 2016      2016-04-01 2016-04-30
#10 May 2016      2016-05-01 2016-05-31

Upvotes: 2

Related Questions