The interface for dates in R is a little confusing to me. I want to create a vector of Date objects from vectors of years, months, and days. One solution I found is: years <- c(1991, 1992) months <- c(1, 10) days <- c(1, 2) dates <- as.Date(ISOdate(years, months, days)) But, in this solution the ISOdate function converts the vectors into characters, which can cause serious performance and memory loss when the vectors of years, months, and days are huge. I am quite sure there is much better solution for it. What is it? Thanks. Daehyok Shin
On Mon, 7 Jun 2004, Shin, Daehyok wrote:> The interface for dates in R is a little confusing to me. > I want to create a vector of Date objects from vectors of years, months, and > days. > One solution I found is: > > years <- c(1991, 1992) > months <- c(1, 10) > days <- c(1, 2) > > dates <- as.Date(ISOdate(years, months, days)) > > But, in this solution the ISOdate function converts the vectors into > characters, > which can cause serious performance and memory loss > when the vectors of years, months, and days are huge.Really? You have measured the loss? A million causes no problem for example, and what are you going to do with a million dates that is instantaneous and worthwhile? And a million dates are hardly going to be unique so you only need to convert the unique values.> I am quite sure there is much better solution for it. What is it?Write your own C code, or make a POSIXlt object directly from the numbers and convert that. -- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
How can I create POSIXlt directly from the numbers? I failed to find the solution from help documents. Daehyok --On Monday, June 07, 2004 4:44 PM +0100 Prof Brian Ripley <ripley at stats.ox.ac.uk> wrote:> On Mon, 7 Jun 2004, Shin, Daehyok wrote: > >> The interface for dates in R is a little confusing to me. >> I want to create a vector of Date objects from vectors of years, months, >> and days. >> One solution I found is: >> >> years <- c(1991, 1992) >> months <- c(1, 10) >> days <- c(1, 2) >> >> dates <- as.Date(ISOdate(years, months, days)) >> >> But, in this solution the ISOdate function converts the vectors into >> characters, >> which can cause serious performance and memory loss >> when the vectors of years, months, and days are huge. > > Really? You have measured the loss? A million causes no problem for > example, and what are you going to do with a million dates that is > instantaneous and worthwhile? And a million dates are hardly going to be > unique so you only need to convert the unique values. > >> I am quite sure there is much better solution for it. What is it? > > Write your own C code, or make a POSIXlt object directly from the numbers > and convert that. > > -- > Brian D. Ripley, ripley at stats.ox.ac.uk > Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ > University of Oxford, Tel: +44 1865 272861 (self) > 1 South Parks Road, +44 1865 272866 (PA) > Oxford OX1 3TG, UK Fax: +44 1865 272595 >
Thanks, but, what I want is to convert three vectors of years, months, and days directly into POSIXlt or Date objects without creating character vectors. Daehyok Shin (Peter) Terrestrial Hydrological Ecosystem Modellers Geography Department University of North Carolina-Chapel Hill sdhyok at email.unc.edu "We can do no great things, only small things with great love." - Mother Teresa> -----Original Message----- > From: james.holtman at convergys.com [mailto:james.holtman at convergys.com] > Sent: Monday, June 07, 2004 PM 12:15 > To: sdhyok at email.unc.edu > Subject: Re: [R] Vectors of years, months, and days to dates? > > > > > > > If you 'unclass' dates you will get a numeric vector that just > has the days > since the epoch. Is this what you want? > > > years <- c(1991, 1992) > > months <- c(1, 10) > > days <- c(1, 2) > > > > dates <- as.Date(ISOdate(years, months, days)) > > dates > [1] "1991-01-01" "1992-10-02" > > str(dates) > Class 'Date' num [1:2] 7670 8310 > > unclass(dates) > [1] 7670 8310 > > > __________________________________________________________ > James Holtman "What is the problem you are trying to solve?" > Executive Technical Consultant -- Office of Technology, Convergys > james.holtman at convergys.com > +1 (513) 723-2929 > > > > > "Shin, Daehyok" > > <sdhyok at email.unc.edu To: "R, > Help" <r-help at stat.math.ethz.ch> > > cc: > > Sent by: Subject: [R] > Vectors of years, months, and days to dates? > r-help-bounces at stat.m > > ath.ethz.ch > > > > > > 06/07/2004 11:16 > > Please respond to > > sdhyok > > > > > > > > > > The interface for dates in R is a little confusing to me. > I want to create a vector of Date objects from vectors of years, months, > and > days. > One solution I found is: > > years <- c(1991, 1992) > months <- c(1, 10) > days <- c(1, 2) > > dates <- as.Date(ISOdate(years, months, days)) > > But, in this solution the ISOdate function converts the vectors into > characters, > which can cause serious performance and memory loss > when the vectors of years, months, and days are huge. > I am quite sure there is much better solution for it. What is it? > > Thanks. > > Daehyok Shin > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html > > > >
Shin, Daehyok <sdhyok <at> email.unc.edu> writes:> > Thanks, but, what I want is to convert three vectors of years, months, and > days directly into POSIXlt or Date objects > without creating character vectors.I would probably just convert it to character using paste and from that to Date as others have already suggested but if it is really important to you for some reason not to use character variables as intermediates try this: require(chron) z <- structure(julian(months, days, years), class="Date") Note that when you print it out it may look like its character but its not. Try class(z) is.character(z) str(z) dput(z) to convince yourself.
Daehyok Shin (Peter) wrote:> Is what I asked such an exceptional case?Apparently.> A lot of data I am dealing with (usually hydrologic data) are > recorded with three columns of years, months, and days. In my > opinion, the direct conversion from numeric vectors of years, months > and days into some internal representation of date is widely > supported in most matrix oriented languages (ex. datenum() in > MATLAB). Am I really asking an odd operation for date conversion?Apparently. You still haven't given any indication of what's wrong with the way R does things, which is perfectly transparent and user friendly. If other packages do things in a slightly different way, so what?> For performance, you are right. The loss of performance is negligible > when users call it directly. But, what happens when it is called in > an iterative loop? How can we assume some functions are only called > directly by users in an interactive shell?Have you ***any*** evidence that R's procedure degrades performance, under any circumstances? (Apparently not.) In that case why are you going on and on about it?> Please consider positively this kind of simple interface for as.Date. > [as.Date(c(years, months, days))]The standard response to this kind of request is ``R is a cooperative endeavour. Feel free to contribute.''> I am quite sure this operation will be used widely once implemented.Have you ***any*** evidence for this assertion?> Is there no one supporting my idea?Apparently not. cheers, Rolf Turner rolf at math.unb.ca
Rolf Turner <rolf at math.unb.ca> attacked: Have you ***any*** evidence that R's procedure degrades performance, under any circumstances? (Apparently not.) In that case why are you going on and on about it? I did the following: library(chron) ymd.to.POSIXlt <- function (y, m, d) as.POSIXlt(chron(julian(y=y, x=m, d=d))) n <- 100000 y <- sample(1970:2004, n, replace=TRUE) m <- sample(1:12, n, replace=TRUE) d <- sample(1:28, n, replace=TRUE) system.time(ymd.to.POSIXlt(y, m, d)) [1] 8.78 0.10 31.76 0.00 0.00 system.time(as.POSIXlt(paste(y,m,d, sep="-"))) [1] 14.64 0.13 53.30 0.00 0.00 This was on a 500MHz SunBlade100, a slow machine by today's standards, using R 1.9.0. There is all the evidence one could reasonably ask for that going through paste() instead of providing y, m, d as numeric vectors *does* degrade performance under at least some circumstances. The cost is less than a factor of 2, but not negligible either. The standard response to this kind of request is ``R is a cooperative endeavour. Feel free to contribute.'' Well, ymd.to.POSIXlt is my contribution. > Is there no one supporting my idea? Apparently not. Wrong: the idea *is* already supported (all except for one trivial line of code) by the chron package.
Thanks, Richard. This is what I was looking for. As you said, the chron package seems so useful that I will use it a lot. I don't think the performance gain (53:31) is not what we can neglect. Still, I am wondering why this kind of intuitive interface is not supported through the base package. Daehyok Shin (Peter)> -----Original Message----- > From: Richard A. O'Keefe [mailto:ok at cs.otago.ac.nz] > Sent: Monday, June 07, 2004 PM 10:50 > To: sdhyok at email.unc.edu > Subject: RE: [R] Vectors of years, months, and days to dates? > > > as.Date(c(years, months, days)) > > That would put all the years, followed by all the months, > followed by all the days, in one vector. > > Try the chron package, where you can use > julian(y=years, x=months, d=days) > # vectors => vector of day numbers (I really mean 'x', not 'm') > chron(julian(...)) > # vector of day numbers => vector of chron objects > as.POSIXlt(chron(...)) > # vector of chron objects => vector of POSIXlt objects > > So: > ymd.to.POSIXlt <- > function (y, m, d) as.POSIXlt(chron(julian(y=y, x=m, d=d))) > > Now, > > n <- 100000 > > y <- sample(1970:2004, n, replace=TRUE) > > m <- sample(1:12, n, replace=TRUE) > > d <- sample(1:28, n, replace=TRUE) > > system.time(ymd.to.POSIXlt(y, m, d)) > [1] 8.78 0.10 31.76 0.00 0.00 # user cpu, system cpu, elapsed > > system.time(as.POSIXlt(paste(y,m,d, sep="-"))) > [1] 14.64 0.13 53.30 0.00 0.00 > > This was on a 500MHz SunBlade100, a slow machine by today's standards. > There *is* a time advantage for the approach you prefer, but it's less > than a factor of 2. > > Is there no one supporting my idea? > > It _is_ supported, via the chron() package. Just add ymd.to.POSIXlt > to your .Rprofile > > It may even be that chron objects do everything you need. >