<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/easily-converting-strings-to-times-and-dates-in-r-with-fliptime/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://www.displayr.com/r-date-conversion/?utm_medium=Feed&utm_source=Syndication"> R – Displayr</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Date conversion in R can be a real pain. However, it is a very important initial step when you first get your data into R to ensure that it has the correct type (e.g. <code><em>Date</em></code>). This gives you the the correct functionality for working with data of that type. R provides a number of handy features for working with date-time data. However, the sheer number of options/packages available can make things seem overwhelming at first. There are <a rel="nofollow" href="https://cran.r-project.org/web/views/TimeSeries.html" target="_blank">more than 10 packages</a> providing support for working with date-time data in R. In this post, I will provide an introduction to the functionality R offers for converting <a rel="nofollow" href="https://www.tutorialspoint.com/r/r_strings.htm" target="_blank"><em>strings</em></a> to dates. In doing so, I discuss common pitfalls and give helpful tips to make working with dates in R less painful. Finally, I introduce some code that my colleagues and I wrote to make things a bit easier (with the <code>flipTime</code> package).</p>
<hr>
<h2>Background</h2>
<p>When dates are provided in the format of year followed by month followed by day, such as <code>2017-12-02</code>, you can use the <code>as.Date</code> function. This tells R to think of them as being dates. For example:</p>
<ul>
<li><code>months(as.Date(&quot;2017-12-02&quot;))</code> returns a value of <code>December</code></li>
<li><code>weekdays(as.Date(&quot;2017-12-02&quot;))</code> returns a value of <code>Saturday</code></li>
<li><code>as.Date(&quot;2017-06-09&quot;) - as.Date(&quot;2016-05-01&quot;)</code> returns a value of of <code>404 </code>and prints on the screen <code><code>Time difference of 404 days.</code></code></li>
<li><code>difftime(as.Date(&quot;2017-06-09&quot;), as.Date(&quot;2016-05-01&quot;), units = &quot;hours&quot;)</code> returns a value of <code>9696</code> and prints on the screen <code>Time difference of 9696</code><code> hours</code>.</li>
<li><code>format(as.Date(&quot;2017-01-02&quot;), &quot;%A, %d-%b. %Y&quot;)</code> prints <code>&quot;Monday, 02-Jan. 2017&quot;</code></li>
</ul>
<p>Unfortunately, more often than not, we have dates in some other format. As a result, <code><span>as.Date</span></code> does not work. For example, <span><code>as.Date(&quot;17-12-2010&quot;)</code></span> returns <span><code>0017-12-20</code>.</span></p>
<p>Things get even more complicated when input data contain times, as then we need to handle issues like time zones and leap seconds. R provides the <em>classes</em> <code>POSIXct</code> and <code>POSIXlt</code> for working with date-time data. <code>POSIXct</code> corresponds to the POSIX standard for calendar time and <code>POSIXlt</code> corresponds to the POSIX standard for local time. Also, the <code>POSIXct</code> class is more convenient for inclusion in R data frames.</p>
<p>I am now going to review some of the more useful packages. However, if you are a bit of a guru, just skip to the section on <code>flipTime</code>, where I have documented the stuff we have done.</p>
<hr>
<h2><code>lubridate</code></h2>
<p>The <code>lubridate</code> package provides a number of useful functions for reading, manipulating, and doing arithmetic with dates in R. It provides the functions <code>parse_date_time()</code> and <code>parse_date_time2()</code>, which can be used to quickly convert strings to date-time objects.Their convenience stems from allowing the user to specify <em>orders</em>  to convert the strings, but without the need to specify how to separate the different components.</p>
<p>The <code>parse_date_time()</code> function allows the user to specify multiple orders at once. Additionally, it determines internally which is best to use to convert the input strings. It does this by training itself on a subset of the input strings and ranking the supplied orders. (The ranking is based on how often they successfully convert the strings in the subset). By contrast, the <code>parse_date_time2()</code> function does not allow multiple orders to be specified at once since it supports fewer orders overall. However, it is faster when you need to convert a large number of strings.</p>
<p>For example, if we use:</p>
<pre> 
parse_date_time(&quot;10-31/2010&quot;, orders = c(&quot;ymd&quot;, &quot;dmy&quot;, &quot;mdy&quot;))
</pre>
<p>As a result, we get <code>2010-10-31 UTC</code></p>
<p>For shorter input vectors, <code>lubridate</code> can give strange results because it is so “aggressive” when performing the conversion. (Because I want to make things easier for skim reading, for the rest of the post I will put the output immediately beneath the code, with <code>##</code> indicating it is the result of running the code.)</p>
<pre> 
parse_date_time(&quot;July/1998&quot;, orders = c(&quot;bdy&quot;, &quot;bY&quot;))

## [1] &quot;1998-07-19 UTC&quot;
</pre>
<pre> 
parse_date_time2(&quot;Jan 128&quot;, orders = &quot;mdy&quot;)

## [1] &quot;2008-01-12 UTC&quot;
</pre>
<pre> 
parse_date_time2(&quot;3.122&quot;, orders = &quot;ymd&quot;)

## [1] &quot;2003-12-02 UTC&quot;
</pre>
<hr>
<h2><code>anytime</code></h2>
<p>Another popular package for reading date strings into R is <a rel="nofollow" href="https://github.com/eddelbuettel/anytime" target="_blank">anytime</a>, which uses the <a rel="nofollow" href="http://www.boost.org/doc/libs/1_61_0/doc/html/date_time.html" target="_blank"><code>Boost date_time</code></a> C++ library. It provides functions <code>anytime()</code> and <code>anydate()</code> for date conversion. The package supports converting other R classes such as <em>integer </em>and <em>factor </em>to dates in addition to converting character strings. The user does not need to specify any orders or formats, as <code>anytime()</code> and <code>anydate()</code> will guess the format (from a default list of supported formats). Furthermore, you have the possibility of including additional formats using the <code>addFormats()</code> function.</p>
<p>As with <code>lubridate</code>, <code>anytime</code> can give strange results because of how aggressive it is with trying to convert the strings. For example, it does not support formats with two-digit years by default. Furthermore, it does not support at all strings containing “AM/PM” indicators. It is inconvenient, sometimes impossible, in some situations to specify whether a numeric month comes before or after the day in a date string.</p>
<p>Additionally, there may be situations where there is ambiguity (eg: is “01/02” January 2nd or February 1st?). In these situations, we’d like to be able to tell the function whether day comes before month or not. Where we are not sure, it’s helpful to have a warning. Unfortunately we don’t get that here.</p>
<pre> 
library(anytime) 
anydate(&quot;3.145&quot;)

## [1] &quot;1400-03-14&quot;
</pre>
<pre> 
anydate(3.145)

## [1] &quot;1970-01-04&quot;
</pre>
<pre> 
anytime(c(&quot;10-11-2011 5:30AM&quot;, &quot;16-10-2011 10:10pm&quot;))

## [1] &quot;2011-10-10 23:00:00 AEDT&quot; NA
</pre>
<hr>
<h2><code>flipTime</code></h2>
<p>The package <code>flipTime</code> provides utilities for working with time series and date-time data. The package can be installed from <code>GitHub</code> using</p>
<pre> 
require(devtools)
install_github(&quot;Displayr/flipTime&quot;)
</pre>
<p>I will discuss only two functions from the package in this post, <code>AsDate()</code> and <code>AsDateTime().</code> These are used for the conversion of date and date-time strings, respectively. These functions build on the convenience and speed of the <code>lubridate</code> function. Furthermore, the <code>flipTime</code> functions provide additional functionality (making them easier to use). The functions are smart about identifying the proper format to use. So the user doesn’t need to specify the format(s) as inputs. At the same time, both <code>AsDate()</code> and <code>AsDateTime()</code> are careful to not convert any strings to dates when they are not formatted as dates. Additionally, it will also warn the user when the dates are not in an unambiguous format.</p>
<p><code>AsDate()</code> and <code>AsDateTime()</code> are very flexible with respect to what they permit as characters to separate the components of the date strings.</p>
<pre> 
library(flipTime)
AsDate(&quot;Jan. 10, 2016&quot;)

## [1] &quot;2016-01-10&quot;
</pre>
<pre> 
AsDate(&quot;Jan/10 - 2016&quot;)

## [1] &quot;2016-01-10&quot;
</pre>
<p>However, they are also careful to not convert strings to dates that are clearly not dates:</p>
<pre> 
AsDate(&quot;Jan 128&quot;)

## Error in AsDate(&quot;Jan 128&quot;): Could not parse &quot;Jan 128&quot; into a valid
## date in any format.

AsDate(&quot;3.122&quot;)

## Error in AsDate(&quot;3.122&quot;): Could not parse &quot;3.122&quot; into a valid date in 
## any format.
</pre>
<p>The above example also demonstrates the default behaviour of the functions to throw an error. This occurs when the date strings cannot be interpreted as dates. Both functions have an argument <code>on.parse.failure</code>, which is used to control this behaviour.</p>
<pre> 
AsDate(&quot;foo&quot;, on.parse.failure = &quot;warn&quot;)

## Warning in AsDate(&quot;foo&quot;, on.parse.failure = &quot;warn&quot;): Could not parse 
## &quot;foo&quot; into a valid date in any format.

## [1] NA
</pre>
<pre> 
AsDateTime(&quot;foo&quot;, on.parse.failure = &quot;silent&quot;)

## [1] NA
</pre>
<p>Both functions provide an argument <code>us.format</code>, to allow the user to specify whether the date strings are in a U.S. or international format. U.S. format is with the month coming before the day, such as <code>Jan.</code> 2, 1988. By contrast, international format, has the day before the month, such as <code>21-10-1999</code>. The default behaviour is to check both formats. In this case, if the format is ambiguous, the date strings will be converted assuming the U.S. format. The user will also receive a warning.</p>
<pre> 
AsDateTime(&quot;9/10/2010 10:20PM&quot;)

## Warning: Date formats are ambiguous, US format has been used.

## [1] &quot;2010-09-10 22:20:00 UTC&quot;
</pre>
<pre> 
AsDateTime(&quot;9/10/2010 10:20PM&quot;, us.format = FALSE)

## [1] &quot;2010-10-09 22:20:00 UTC&quot;
</pre>
<p>We can also combine the <code>flipTime</code> functions with functions from <code>lubridate</code> (By the way, due to a WordPress bug, I am using = instead of a more righteous assignment operator; please write to them rather than me, as I am a good guy.)</p>
<pre> 
library(lubridate)
dt = AsDateTime(&quot;10/30/08 11:10AM&quot;)
dt + dminutes(6)

## [1] &quot;2008-10-30 11:16:00 UTC&quot;
</pre>
<pre> 
birthday = &quot;Dec. 8, 86&quot;
days.alive = (AsDate(Sys.time()) - AsDate(birthday)) / ddays(1)
days.alive

## [1] 11322
</pre>
<p>The function <code>AsDate()</code> is also able to interpret date intervals or <em>periods</em>, which can be useful when working with aggregated data. If the function encounters date periods, it will convert the start of the period to a date and return it.</p>
<pre> 
AsDate(&quot;10/20/2015-12/02/2016&quot;)
## [1] &quot;2015-10-20&quot;

AsDate(&quot;may 2017-september 2017&quot;)
## [1] &quot;2017-05-01&quot;

AsDate(&quot;Dec/Apr 16&quot;)
## [1] &quot;2015-12-01&quot;
</pre>
<p>The following example shows how <code>AsDate()</code> can be useful when working with dates inside a custom function. Say we have the following data on monthly returns of Apple and Yahoo. (A full copy of the dataframe can be found on this Displayr page <a rel="nofollow" href="https://app.displayr.com/Try/Convert%20Strings%20to%20Date-Time" target="_blank">here</a>).</p>
<pre> 
head(df)

##                        YHOO         AAPL
## 01/2007-02/2007  0.09516441 -0.006488240
## 02/2007-03/2007  0.09007418 -0.013061224
## 03/2007-04/2007  0.01393390  0.097601323
## 04/2007-05/2007 -0.10386705  0.074604371
## 05/2007-06/2007  0.02353780  0.213884993
## 06/2007-07/2007 -0.05470383  0.006932409
</pre>
<p>We can plot this data as time series with formatted axis labels. For instance, we might write the following function and it produces the plot below.</p>
<pre> 
PlotSeries = function(data, max.labels = 20, ...){
    n = nrow(data)
    xlabs = AsDate(rownames(data), on.parse.failure = &quot;silent&quot;)
    if (any(is.na(xlabs)))  # no dates present, use original rownames
        xlabs = rownames(data)[seq.int(1, n, length.out = max.labels)]
    else{  # dates, present; format for pretty labels
        xlabs = seq(xlabs[1L], xlabs[n], length.out = max.labels)
        xlabs = format(xlabs, &quot;%b, %Y&quot;)
    }
    matplot(data, type = &quot;l&quot;, xaxt = &quot;n&quot;, ...)
    axis(1, labels = xlabs, at = seq.int(1, n, length.out = max.labels),
         las = 2)
    legend(&quot;bottomright&quot;, names(data), lty = 1:ncol(data), 
           col = 1:ncol(data))
}
PlotSeries(df, lwd = 2, ylab = &quot;Return&quot;)
</pre>
<p><iframe width="450" src="https://embedded.azureedge.net/75668/248427/d039517e-b022-4fb1-a242-91edb635195d.html?v=29946-1051b90c4e2013340294"></iframe></p>
<hr>
<h2>References</h2>
<p>The source code for <span>flipTime</span> can be viewed and downloaded <a rel="nofollow" href="https://github.com/Displayr/flipTime" target="_blank">here</a>.<br>
More information about working with dates and times in R can be found in the following sources.</p>
<ol>
<li><a rel="nofollow" href="http://www.noamross.net/blog/2014/2/10/using-times-and-dates-in-r---presentation-code.html" target="_blank">Bonnie Ross – Using Dates and Times in R</a></li>
<li><a rel="nofollow" href="https://statistics.berkeley.edu/computing/r-dates-times" target="_blank">Phil Spector – Dates and Times in R</a></li>
<li><a rel="nofollow" href="http://biostat.mc.vanderbilt.edu/wiki/pub/Main/ColeBeck/datestimes.pdf" target="_blank">Cole Beck – Handling date-times in R</a></li>
<li>For an introduction to <code>lubridate</code>, see <a rel="nofollow" href="http://r4ds.had.co.nz/dates-and-times.html" target="_blank">Garrett Grolemund and Hadley Wickham: R for Data Science</a></li>
<li>For an introduction to <code>anytime</code>, see <a rel="nofollow" href="http://dirk.eddelbuettel.com/code/anytime.html" target="_blank">Dirk Eddelbuettel’s blog</a></li>
</ol>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://www.displayr.com/r-date-conversion/?utm_medium=Feed&utm_source=Syndication"> R – Displayr</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/xU-NVHcoRMc" height="1"></a></div>