I'm working on a collection of scripts and using s3 classes and methods to keep things a little cleaner.
The class structure has three levels.
I want to write a function that ONLY takes data frames of class stim_report, then dispatches a different method depending on whether the stim_report inherits from sample_report or inherits from fix_report.
Obviously, I could do something like
myfunction.stim_report(df)
if ("sample_report" %in% class(df)) {
% do something
} else if ("fix_report" %in% class(df)) {
% do something
}
But that kind of defeats the purpose of methods dispatching.
Note that I need things to work so that the function will return an error if the class of the data frame isn't stim_report. So I suppose I could also do:
myfunction.fix_report(df)
if ("stim_report" %in% class(df)) {
% do something
} else {
stop("No method found")
}
myfunction.sample_report(df)
if ("stim_report" %in% class(df)) {
% do something
} else {
stop("No method found")
}
But again, this feels like it goes against the whole point of the S3 methods.
Is there a right way to do this?
What about something like this -
Df1 <- data.frame(
x = 1:5,
y = rexp(5))
##
Df2 <- data.frame(
x = 6:10,
y = rexp(5))
##
Df3 <- data.frame(
x = 11:15,
y = rexp(5))
##
class(Df1) <- c("stim_report","sample_report","data.frame")
class(Df2) <- c("stim_report","fix_report", "data.frame")
##
foo <- function(x){
UseMethod("foo",x)
}
foo.sample_report <- function(x){
x[sample(1:nrow(x),3),]
}
foo.fix_report <- function(x){
x[,2] <- cumsum(x[,2])
x
}
##
> foo(Df1)
x y
3 3 0.9400994
5 5 0.3708902
1 1 0.7521028
> foo(Df2)
x y
1 6 2.408421
2 7 2.637971
3 8 3.465672
4 9 3.571835
5 10 5.468710
> foo(Df3)
Error in UseMethod("foo", x) :
no applicable method for 'foo' applied to an object of class "data.frame"
Where you would change the bodies of foo.sample_report
and foo.fix_report
to do whatever it is you want them to do. The objects' classes were assigned as c("stim_report","sub_class", "data.frame")
rather than just c("stim_report","sub_class")
so that they can inherit other S3 generics, like nrow
.