0

我正在研究一组脚本并使用 s3 类和方法来使事情变得更简洁。

班级结构分为三个层次。

  • 级别 1:data.frame
  • 级别 2:sample_report 或 fix_report
  • 第 3 级:stim_report

我想编写一个函数,它只接受 stim_report 类的数据帧,然后根据 stim_report 是从 sample_report 继承还是从 fix_report 继承来调度不同的方法。

显然,我可以做类似的事情

myfunction.stim_report(df)

if ("sample_report" %in% class(df)) {
% do something 
} else if ("fix_report" %in% class(df)) {
% do something 
}

但这违背了方法调度的目的。

请注意,如果数据框的类不是 stim_report,我需要一些东西才能工作,以便函数返回错误。所以我想我也可以这样做:

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")
}

但同样,这感觉与 S3 方法的全部要点背道而驰。

有正确的方法吗?

4

1 回答 1

1

像这样的东西怎么办——

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"

你会在哪里改变他们的身体foo.sample_reportfoo.fix_report做任何你想让他们做的事情。对象的类被分配为c("stim_report","sub_class", "data.frame")而不是仅仅c("stim_report","sub_class")为了它们可以继承其他 S3 泛型,例如nrow.

于 2014-08-30T17:06:42.377 回答