[R] Confusion with sapply

hadley wickham h.wickham at gmail.com
Wed Jun 13 11:05:00 CEST 2007


On 6/13/07, Patnaik, Tirthankar <tirthankar.patnaik at citi.com> wrote:
> Hi,
>  I have some confusion in applying a function over a column.
>
> Here's my function. I just need to shift non-March month-ends to March
> month-ends. Initially I tried seq.dates, but one cannot give a negative
> increment (decrement) here.
>
> return(as.Date(seq.dates(format(xdate,"%m/%d/%Y"),by="months",len=4)[4])
> )
>
> Hence this simple function:
>
> > mydate <- as.Date("2006-01-01")
> >
> > # Function to shift non-March company-reporting dates to March.
> > Set2March <- function(xdate){
> + # Combines non-March months into March months:
> + # Dec2006 -> Mar2007
> + # Mar2006 -> Mar2006
> + # Jun2006 -> Mar2006
> + # Sep2006 -> Mar2006
> + # VERY Specific code.
> +     Month <- format(xdate,"%m")
> +     wDate <- month.day.year(julian(xdate))
> +     if (Month=="12"){
> +         wDate$year <- wDate$year + 1
> +         wDate$month <- 3
> +     }else
> +     if (Month=="06"){
> +         wDate$month <- 3
> +     }else
> +     if (Month=="09"){
> +         wDate$month <- 3
> +         wDate$day <- wDate$day + 1
> +     }else warning ("No Changes made to the month, since month is not
> one of (6,9,12)")
> +     cDate <- chron(paste(wDate$month,wDate$day,wDate$year,sep="/"))
> +     return(as.Date(as.yearmon(as.Date(cDate,"%m/%d/%y")),frac=1))
> + }
> > Set2March(as.Date("2006-06-30"))
> [1] "2006-03-31"
> > Set2March(mydate)
> [1] "2006-01-31"
> Warning message:
> No Changes made to the month, since month is not one of (6,9,12) in:
> Set2March(mydate)
> >
>
> Works well when I use it on a single date. Then I try it on a vector:
>
>
> > dc <- seq(as.Date("2006-01-01"),len=10, by="month")
> > dc
>  [1] "2006-01-01" "2006-02-01" "2006-03-01" "2006-04-01" "2006-05-01"
> "2006-06-01" "2006-07-01" "2006-08-01"
>  [9] "2006-09-01" "2006-10-01"
>
>
> > sapply(as.vector(dc),Set2March)
> Error in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3,
> :
>         unimplemented type 'character' in 'asLogical'
> >
>
> What am I missing here? Shouldn't the function work with the sapply
> working on each entry?

You can considerable simplify your code with some helper functions:

month <- function(x) as.POSIXlt(x)$mon + 1
"month<-" <- function(x, value) {
	ISOdatetime(year(x) + (value - 1) %/% 12,  (value - 1) %% 12 + 1 ,
mday(x), hour(x), minute(x), second(x), tz(x))
}
year <- function(x) as.POSIXlt(x)$year + 1900
"year<-" <- function(x, value) {
	ISOdatetime(value,  month(x), mday(x), hour(x), minute(x), second(x), tz(x))
}

marchise <- function(x) {
	if (month(x) == 12) year(x) <- year(x)
	if (month(x) %in% c(6, 9, 12)) month(x) <- 3
	x
}

dc <- seq(as.Date("2006-01-01"),len=10, by="month")
marchise(dc[[1]])


However, that doesn't work with sapply because the date class seems to
get stripped off - I'm not completely why, but perhaps because the
date class is a property of the entire vector not the individual
values:

sapply(marchise, dc)

Hadley



More information about the R-help mailing list