[R] Generic Functions and Dates

2011-01-31 Thread Elliot Joel Bernstein
I'm trying to write a generic function that calls different methods depending 
on the structure of the argument, but not the exact type of its contents. For 
example, the function 'nan2last' below works for a numeric vector but not for a 
vector of Date objects. Is there any way to make it work on any vector?


setGeneric(nan2last, function(x) { standardGeneric(nan2last) }) 

   


   
setMethod(nan2last, vector,   

   
  function(x) { 

   


   
naLocs - (1:length(x))[is.na(x)]   

   


   
if (length(naLocs) == 0)

   
  return (x)

   


   
naLocs - naLocs[naLocs1]  

   


   
for (i in 1:length(naLocs)) {   

   
  x[naLocs[i]] - x[naLocs[i]-1]

   
}   

   


   
return(x)   

   
  })

   


   
## Works

   
x - 1:10;  

   
x[sample(10,3)] - NA   

   
print(cbind(x, nan2last(x)))

   


   
## Doesn't work 

   
x - seq(as.Date(2011-01-01), as.Date(2011-01-31), days)  
  

Re: [R] Generic Functions and Dates

2011-01-31 Thread Martin Morgan
On 01/31/2011 12:15 PM, Elliot Joel Bernstein wrote:
 I'm trying to write a generic function that calls different methods
 depending on the structure of the argument, but not the exact type of
 its contents. For example, the function 'nan2last' below works for a
 numeric vector but not for a vector of Date objects. Is there any way
 to make it work on any vector?

Hi Elliot --

In principle one could write a method that advertises that it operates
on signature ANY

setMethod(nan2last, ANY, function(x) ...)

but in practice it's unlikely that one could do something useful on
_any_ object.

If I

 getClass(Date)
Virtual Class Date [package methods]

Slots:

Name:   .S3Class
Class: character

Extends: oldClass

I see that Date does not extend vector, so I'd write a method that
delegates as appropriate, along the lines of

.nan2last - function(x) { general implementation }

setMethod(foo, vector, .na2last)
setMethod(foo, Date, .na2last)

 setGeneric(nan2last, function(x) { standardGeneric(nan2last) })   
   

   
   

 setMethod(nan2last, vector, 
   

   function(x) {   
   

   
   

 naLocs - (1:length(x))[is.na(x)]  

probably naLocs - which(is.na(x))


   
   

 if (length(naLocs) == 0)  
   

   return (x)  
   

   
   

 naLocs - naLocs[naLocs1]
   

   
   

 for (i in 1:length(naLocs)) {

seq_along(naLocs), otherwise you'll surprise yourself with
1:length(integer(0))


   x[naLocs[i]] - x[naLocs[i]-1]  
   

 } 

just x[naLocs] - x[naLocs - 1], outside the loop (so no seq_along)

Martin



   
   

 return(x) 
   

   })  
   

   
   

 ## Works  
   

 x - 1:10;
   

 x[sample(10,3)] - NA 
   

 print(cbind(x, nan2last(x)))