5

我有一个关于在 R 中使用 S3 类做某事的“正确”方法的问题。我想做的是有一个方法来更改类,然后在新类上调用相同的方法。像这样的东西:

my_func <- function(.x, ...) {
  UseMethod("my_func")
}

my_func.character <- function(.x, ...) {
  return(paste(".x is", .x, "of class", class(.x)))
}

my_func.numeric <- function(.x, ...) {
  .x <- as.character(.x)
  res <- my_func(.x) # this should call my_func.character
  return(res)
}

这有效。当我执行以下操作时,我都可以character上课

> my_func("hello")
[1] ".x is hello of class character"
> my_func(1)
[1] ".x is 1 of class character"

我的问题是:这是正确的方法吗?在我转换类之后(这一行res <- my_func(.x))重新调用相同的方法感觉很奇怪。

我觉得NextMethod()必须以某种方式成为答案,但我已经阅读了一堆关于它的文档(例如thisthis)但他们都在谈论这件事,它正在跳到类列表中的下一个类,比如从例如data.frame,直到matrix您拥有class(df)并获得c("data.frame", "matrix")

但是他们都没有谈论这种情况,即您将其转换为不在原始层次结构中的完全不同的类。所以也许NextMethod() 不是正确的使用方法,但还有其他东西,还是我应该像拥有​​它一样离开它?

谢谢!

4

2 回答 2

2

1)如果想法是 my_func.numeric 进行额外的处理,但也想使用 my_func.character 而不重复,那么在func.numericset中.Class然后NextMethod像这样调用:

my_func.numeric <- function(.x, ...) {
  .Class <- "character"
  .x <- as.character(.x)
  NextMethod()
}

NextMethod返回一个结果,并且可以选择在它之后进行其他处理。可以通过?NextMethod在 R 中发布来找到更多信息。

2)如果想法是可以组合数字和字符方法,那么:

my.func.character <- my.func.numeric <- function(.x, ...) {
    .x <- as.character(.x)
    paste(".x is", .x, "of class", class(.x))
}

如果尚未将默认方法用于其他用途,也可以为此使用默认方法。

3)如果想法只是有共享功能,但您不一定要在数字方法中使用所有字符方法处理,反之亦然,那么定义一个由每个方法调用的函数:

my_func_impl <- function(.x, ...) paste(".x is", .x, "of class", class(.x))

my_func.character <- function(.x, ...) {
  # some procesing unique to this method
  my_func_impl(.x, ...)
}

my_func.numeric <- function(.x, ...) {
  # some procesing unique to this method
  my_func_impl(.x, ...)
}
于 2020-03-11T17:23:33.460 回答
0

最标准的方法是创建一个默认方法,例如:

my_func.default <- function(.x, ...) {
  stopifnot(is.atomic(.x)) # throw an error if .x isn't an atomic vector
  .x <- as.character(.x)
  paste(".x is", .x, "of class", class(.x))
}
my_func("hello")
#> [1] ".x is hello of class character"
my_func(1)
#> [1] ".x is 1 of class character"
于 2020-03-11T17:22:37.917 回答