使用OOP和S3方法进行检测,然后对单个向量或data.frame的所有列进行操作

时间:2014-01-24 19:33:01

标签: r r-s3

我编写了一个对单个向量进行操作的函数。有时我想在整个data.frame上使用该函数。我可以通过在相关变量中使用sapply来实现这一点,但现在我想使用S3方法包含和指导函数。

首先,设置:

df_test <- data.frame(x = c(1, 2, 3, 4, 5), 
                      y = c(6, 7, 8, 9, 10), 
                      z = c(11, 12, 13, 14, 15))

adder <- function(x, from, to) {
  if(is.null(ncol(x))) {
    x <- structure(list(x = x, from = from, to = to), class = "single")
  } else {
    x <- structure(list(x = x, from = from, to = to), class = "multiple")
  }
  UseMethod("adder", x)
}

adder.single <- function(x, from, to) {
  x <- x + (from - to) # just some random operation here - the real function does more
  x
}

adder.multiple <- function(x, from, to) {
  x <- sapply(x, function(y) { 
    y <- structure(list(x = y, from = from, to = to), class = "single"); 
    UseMethod("adder", y) })
  x
}

因此,在单个向量上,该函数有效:

> adder(df_test[,1], 2, 4)
[1] -1  0  1  2  3

但是传递整个data.frame不会:

> adder(df_test, 2, 4)
Error in from - to : 'from' is missing

我很清楚问题是什么 - adder检测到我们正在查看整个data.frame,使用“multiple”方法,然后调用“single”方法和参数{ {1}}和from未被传递。

我读过尼古拉斯·克里斯蒂安的Hadley Wickham的OOP Field GuideAdvanced Programming,但这并不适合我。我欢迎一种完全不同的方法,只要它使用S3方法,因为这个练习的一部分是让我学习如何使用它们。

1 个答案:

答案 0 :(得分:2)

只需拨打adder,S3调度将正确执行并调用正确的功能。

adder.multiple <- function(x, from, to) {
  sapply(x,  adder,from,to)
}

您不应该两次定义通用adder(对UseMethod的调用)。