[R] Confusion with sapply

Patnaik, Tirthankar tirthankar.patnaik at citi.com
Wed Jun 13 11:30:55 CEST 2007


Hi,
	Many thanks for this Hadley, and Uwe, the packages I used were
chron, and zoo. Later I'm also using Hadley's reshape.

I was able to run the code for a vector thus:

> 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"
> as.Date(sapply(dc,function(x)Set2March(as.Date(x))))
 [1] "2006-01-31" "2006-02-28" "2006-03-31" "2006-04-30" "2006-05-31"
"2006-03-31" "2006-07-31" "2006-08-31"
 [9] "2006-03-31" "2006-10-31"
Warning messages:
1: No Changes made to the month, since month is not one of (6,9,12) in:
Set2March(as.Date(x)) 
2: No Changes made to the month, since month is not one of (6,9,12) in:
Set2March(as.Date(x)) 
3: No Changes made to the month, since month is not one of (6,9,12) in:
Set2March(as.Date(x)) 
4: No Changes made to the month, since month is not one of (6,9,12) in:
Set2March(as.Date(x)) 
5: No Changes made to the month, since month is not one of (6,9,12) in:
Set2March(as.Date(x)) 
6: No Changes made to the month, since month is not one of (6,9,12) in:
Set2March(as.Date(x)) 
7: No Changes made to the month, since month is not one of (6,9,12) in:
Set2March(as.Date(x)) 
8: No Changes made to the month, since month is not one of (6,9,12) in:
Set2March(as.Date(x)) 
> 

Basically I ran as.Date on the vector elements (Why?, since the elements
are dates anyway?), and then afterwards use as.Date again on the
returned vector. Got the answer, but it would be great if I could
understand exactly how.

TIA and Best,
-Tir



> -----Original Message-----
> From: hadley wickham [mailto:h.wickham at gmail.com] 
> Sent: Wednesday, June 13, 2007 2:35 PM
> To: Patnaik, Tirthankar [GWM-CIR]
> Cc: r-help at stat.math.ethz.ch
> Subject: Re: [R] Confusion with sapply
> 
> 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