Skip to content

(Newbie) Functions on vectors

4 messages · Vivek Satsangi, Gabor Grothendieck, Brian Ripley +1 more

#
Folks,

I want to make the following function more efficient, by vectorizing it:

getCriterionDecisionDate <- function (quarter , year)
{
  if (length(quarter) != length(year)) stop ("Quarter and year vectors
of unequal length!");
  ret <- character(0);

  for (i in 1:length(quarter)) {
    currQuarter <- quarter[i];
    currYear <- year[i];

    if ((currQuarter < 1) | (currQuarter > 4)) stop ("Invalid quarter!");
    if ((currYear < 1986) | (currYear > 2004)) stop ("Invalid year!");

    # If the criterion date is 1Q2004, then the reports were for periods
    # ending in Feb, March and April 2004 and the decision date is July 1, 2004.
    if (currQuarter == 1) {
      ret <- c(ret,paste("06/30/",currYear,sep=""));
    } else if (currQuarter == 2) {
      ret <- c(ret,paste("09/30/",currYear,sep=""));
    } else if (currQuarter == 3) {
      ret <- c(ret,paste("12/31/",currYear,sep=""));
    } else if (currQuarter == 4) {
      ret <- c(ret,paste("3/31/",currYear+1,sep=""));
    }
  }

  ret;
}


How can I make the 'if' statements work on vectors rather than using
one value at a time? (sorry, my copy of MASS is at home).

--
-- Vivek Satsangi
Student, Rochester, NY USA
#
You can use ifelse but even better note that
the zoo package has the yearqtr class which represents years
and quarters internally as years + (qtr-1)/4 where qtr is 0,1,2,3
so as to be consistent with ts class.   It also
has an as.Date.yearqtr method which will convert them
to class Date.  Using these the code is really just one line:


# test data
year <- 2001:2004
qtr  <- 1:4

library(zoo)
as.Date(as.yearqtr(year + qtr/4), frac = 1)
On 2/17/06, Vivek Satsangi <vivek.satsangi at gmail.com> wrote:
#
Something like

Qs <- c("30/6", "30/9", "31/12", "31/3")
paste(Qs[quarter], year + (quarter==4), sep="")

(no trailing semicolons are necessary)
On Fri, 17 Feb 2006, Vivek Satsangi wrote:

            

  
    
#
Vivek,

For the tests you can do, for example:

if(any(quarter < 1 | quarter > 4)) stop('invalid quarter(s)')

For the dates you can do:

ret <- paste(c('6/30', '9/30', '12/31', '3/31')[quarter],
    year + quarter == 4, sep='/')

Patrick Burns
patrick at burns-stat.com
+44 (0)20 8525 0696
http://www.burns-stat.com
(home of S Poetry and "A Guide for the Unwilling S User")
Vivek Satsangi wrote: