【问题标题】:S3: Modify default argument before calling NextMethod()S3:在调用 NextMethod() 之前修改默认参数
【发布时间】:2020-07-14 21:08:04
【问题描述】:

在 S3 通用函数中,我想在调用 NextMethod() 之前修改函数参数。作为起点,我浏览了 Henrik Bengtsson 的“R 愿望清单”中的 #44。以下 sn-p 取自那里,对应于他关于如何在调用 NextMethod() 之前修改参数的建议。

x <- structure(NA, class = "A")
expected <- list(x = x, a = 3)

foo <- function(x, a) UseMethod("foo")

foo.A <- function(x, a) {
  a <- a + 1
  NextMethod()
}

foo.default <- function(x, a) {
  list(x = x, a = a)
}

identical(foo(x, a = 2), expected)
#> [1] TRUE
identical(foo(x, 2), expected)
#> [1] TRUE

现在让我难过的是以下行为,其中要修改的参数具有默认值。

bar <- function(x, a) UseMethod("bar")

bar.A <- function(x, a = 2) {
  a <- a + 1
  NextMethod()
}

bar.default <- function(x, a = 2) {
  list(x = x, a = a)
}

identical(bar(x, a = 2), expected)
#> [1] TRUE
identical(bar(x, 2), expected)
#> [1] TRUE
identical(bar(x), expected)
#> [1] FALSE

有人可以帮我理解这里发生了什么吗?关于如何使默认参数案例起作用的任何想法(除了显式调用bar.default())?

【问题讨论】:

    标签: r oop generics parameter-passing


    【解决方案1】:

    我不确定这个设置有多现实,但它的问题是调用bar(x)意味着你调用bar.A(x),然后(通过NextMethod())你调用bar.default(x),而不是您所期望的bar.default(x, a = 3)

    解决方法是专门将a 作为NextMethod 中的参数传递。您将遇到的问题是,如果用户没有命名第二个参数,那么bar.default 将抛出,因为它被赋予了 3 个参数而不是两个(x2a = 3)。您可以通过在bar.default 中包含... 参数来解决此问题,以便忽略未命名的参数。

    x <- structure(NA, class = "A")
    expected <- list(x = x, a = 3)
    
    bar <- function(x, ...) UseMethod("bar")
    
    bar.A <- function(x, a = 2) {
      a <- a + 1
      NextMethod("bar", x, a = a)
    }
    
    bar.default <- function(x, ..., a = 2) {
      list(x = x, a = a)
    }
    
    identical(bar(x, a = 2), expected)
    #> [1] TRUE
    identical(bar(x, 2), expected)
    #> [1] TRUE
    identical(bar(x), expected)
    #> [1] TRUE
    

    reprex package (v0.3.0) 于 2020 年 4 月 2 日创建

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-13
      • 2017-10-23
      • 2012-07-25
      • 1970-01-01
      • 2019-10-10
      • 1970-01-01
      • 2018-01-10
      • 1970-01-01
      相关资源
      最近更新 更多