Tag Archives: R package

Working with Date Objects in R

Learn how to work with date objects in R in this tutorial by Kuntal Ganguly, a big data analytics engineer focused on building large-scale, data-driven systems using big data frameworks and machine learning.

The base R package provides date functionality. This article will show you several date-related operations in R. You’ll only be using features from the base package and not from any external data. Therefore, you do not need to perform any preparatory steps.

R internally represents dates as the number of days from January 1, 1970. It represents dates as Unix time or epoch time, which is defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970. So, zero corresponds to January 1, 1970 and so on. You can convert positive and negative numbers to dates. Negative numbers give dates before January 1, 1970.

  1. Get started with today’s date:
> Sys.Date()
  1. Create a date object from a string:
# Supply year as two digits 

# Note correspondence between separators in the date string and the format string 

as.Date("1/1/80", format = "%m/%d/%y")  
[1] "1980-01-01"  

# Supply year as 4 digits 

# Note uppercase Y below instead of lowercase y as above 

as.Date("1/1/1980", format = "%m/%d/%Y") 
[1] "1980-01-01" 

# If you omit format string, you must give date as "yyyy/mm/dd" or as "yyyy-mm-dd" 

as.Date("1970/1/1") [1] "1970-01-01"  > as.Date("70/1/1") 
[1] "0070-01-01"
  1. Use other options for separators (this example uses hyphens) in the format string, and also see the underlying numericvalue:
> dt <- as.Date("1-1-70", format = "%m-%d-%y") 
> as.numeric(dt)   
[1] 0
  1. Explore other format string options:
> as.Date("Jan 15, 2015", format = "%b %d, %Y") 
[1] "2015-01-15"  
> as.Date("January 15, 15", format = "%B %d, %y") 
[1] "2015-01-15"
  1. Create dates from numbers by typecasting:
>dt <- 1000 
> class(dt) <- "Date" 
> dt                 # 1000 days from 1/1/70 
[1] "1972-09-27"  
dt <- -1000 
> class(dt) <- "Date" 
dt                 # 1000 days before 1/1/70 
[1] "1967-04-07"
  1. Create dates directly from numbers by setting the origin date:
> as.Date(1000, origin = as.Date("1980-03-31")) 
[1] "1982-12-26"  
> as.Date(-1000, origin = as.Date("1980-03-31")) 
[1] "1977-07-05"
  1. Examine the date components:
> dt <- as.Date(1000, origin = as.Date("1980-03-31/")) 
> dt 
[1] "1982-12-26"  
> # Get year as four digits 
> format(dt, "%Y") 
[1] "1982"  
> # Get the year as a number rather than as character string 
> as.numeric(format(dt, "%Y")) 
[1] 1982  
> # Get year as two digits 
> format(dt, "%y") 
[1] "82"  
> # Get month 
> format(dt, "%m")  
[1] "12"  
> as.numeric(format(dt, "%m"))  
[1] 12  
> # Get month as string 
> format(dt, "%b") 
[1] "Dec"  
> format(dt, "%B") 
[1] "December"  
> months(dt)  
[1] "December"  
> weekdays(dt) 
[1] "Sunday"  
> quarters(dt) 
[1] "Q4"  
> julian(dt) 
[1] 4742 
attr(,"origin") 
[1] "1970-01-01"  
> julian(dt, origin = as.Date("1980-03-31/")) 
[1] 1000 
attr(,"origin") 
[1] "1980-03-31"

How this works

Step 1 shows how to get the system date. Steps 2 through 4 show how to create dates from strings. You can see that by specifying the format string appropriately, you can read dates from almost any string representation. You can use any separator as long as you mimic them in the format string. The following table summarizes the formatting options for the components of the date:

Format Specifier Description
%d Day of month as a number, for example, 15
%m Month as a number, for example, 10
%b Abbreviated string representation of a month, for example, Jan
%B Complete string representation of a month, for example, January
%y Year as two digits, for example, 87
%Y Year as four digits, for example, 2001

Step 5 shows how an integer can be typecast as a date. Step 6 shows how to find the date with a specific offset from a given date (origin). Finally, step 7 shows how to examine the individual components of a date object using the format function along with the appropriate format specification (refer to the preceding table) for the desired component.

Step 6 also shows the use of the months, weekdays, and julian functions for getting the month, day of the week, and the Julian date corresponding to a date. If you omit the origin in the julian function, R assumes January 1, 1970, as the origin.

Operating on date objects

R supports many useful manipulations with date objects, such as date addition and subtraction, and the creation of date sequences. This example shows many of these operations in action. The base R package provides the date functionality, and you do not need any preparatory steps.

  1. Perform addition and subtraction of days from date objects:
> dt <- as.Date("1/1/2001", format = "%m/%d/%Y") 
> dt 
[1] "2001-01-01"  

> dt + 100                 # Date 100 days from dt
[1] "2001-04-11"  

> dt + 31 
[1] "2001-02-01"
  1. Subtract date objects to find the number of days between two dates:
> dt1 <- as.Date("1/1/2001", format = "%m/%d/%Y") 
> dt2 <- as.Date("2/1/2001", format = "%m/%d/%Y") 
> dt1-dt1  Time difference of 0 days  > dt2-dt1  

Time difference of 31 days 
> dt1-dt2  

Time difference of -31 days 
> as.numeric(dt2-dt1) 
[1] 31
  1. Compare the date objects:
> dt2 > dt1 
[1] TRUE  

> dt2 == dt1 
[1] FALSE
  1. Create date sequences:
> d1 <- as.Date("1980/1/1") 
> d2 <- as.Date("1982/1/1") 
> # Specify start date, end date and interval 
> seq(d1, d2, "month")  
[1] "1980-01-01" "1980-02-01" "1980-03-01" "1980-04-01"  
[5] "1980-05-01" "1980-06-01" "1980-07-01" "1980-08-01"  
[9] "1980-09-01" "1980-10-01" "1980-11-01" "1980-12-01" 
[13] "1981-01-01" "1981-02-01" "1981-03-01" "1981-04-01" 
[17] "1981-05-01" "1981-06-01" "1981-07-01" "1981-08-01" 
[21] "1981-09-01" "1981-10-01" "1981-11-01" "1981-12-01" 
[25] "1982-01-01"  

> d3 <- as.Date("1980/1/5") 
> seq(d1, d3, "day") 
[1] "1980-01-01" "1980-01-02" "1980-01-03" "1980-01-04" 
[5] "1980-01-05"  

> # more interval options 
> seq(d1, d2, "2 months")  
[1] "1980-01-01" "1980-03-01" "1980-05-01" "1980-07-01"  
[5] "1980-09-01" "1980-11-01" "1981-01-01" "1981-03-01"  
[9] "1981-05-01" "1981-07-01" "1981-09-01" "1981-11-01" 
[13] "1982-01-01"  

> # Specify start date, interval and sequence length 
> seq(from = d1, by = "4 months", length.out = 4 ) 
[1] "1980-01-01" "1980-05-01" "1980-09-01" "1981-01-01"
  1. Find a future or past date from a given date, based on an interval:
> seq(from = d1, by = "3 weeks", length.out = 2)
[2] [1] "1980-01-22"

How this works

Step 1 shows how you can add and subtract days from a date to get the resulting date. Step 2 shows how you can find the number of days between two dates through subtraction. The result is a difftime object that you can convert into a number if needed.

Step 3 shows the logical comparison of dates and step 4 shows two different ways of creating sequences of dates. In one, you specify the from date, the to date, and the fixed interval by between the sequence elements as a string. In the other, you specify the from date, the interval, and the number of sequence elements you want. If you’re using the latter approach, you have to name the arguments.

Finally, Step 5 shows how you can create sequences by specifying the intervals in a flexible manner.

If you found this article interesting, you can explore Kuntal Ganguly’s R Data Analysis Cookbook – Second Edition to put your data analysis skills in R to practical use, with recipes catering to the basic as well as advanced data analysis tasks. This book has over 80 recipes to help you breeze through your data analysis projects using R.