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:> 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 > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html >
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:> 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 > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html >-- 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
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:>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 > >______________________________________________ >R-help at stat.math.ethz.ch mailing list >https://stat.ethz.ch/mailman/listinfo/r-help >PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html > > > > >