【问题标题】:Default argument depending of the function matched in R默认参数取决于 R 中匹配的函数
【发布时间】:2022-01-02 21:59:15
【问题描述】:

目前,我在 tablextabs 周围有两个非常相似的包装器:

mytable <- function(..., useNA = "ifany") {
  tab <- table(..., useNA = useNA)
  # additional manipulations
  tab
}

mytable(warpbreaks[-1])

myxtabs <- function(..., na.action = NULL, addNA = TRUE) {
  tab <- xtabs(..., na.action = na.action, addNA = addNA)
  # same manipulations as in mytable
  tab
}

myxtabs(breaks ~ ., warpbreaks)

由于大多数代码都是重复的,我希望将两个包装器合并为一个。一个简单的解决方案是:

newfun <- function(..., fun) {
  fun <- match.fun(fun)
  tab <- fun(...)
  # same manipulations as in mytable
  tab
}

newfun(warpbreaks[-1], fun = table)
newfun(breaks ~ ., warpbreaks, fun = xtabs)

但是,我可以根据匹配的函数指定默认参数吗?即:

  • 如果fun = table,则设置useNA = "ifany"
  • 或者如果fun = xtabs,设置na.action = NULLaddNA = TRUE

此外,将fun 限制为仅tablextabs 的“推荐”方式是什么?我想我有很多方法可以实现这一点(stopifnotif/elseswitchmatch.arg),但我在这里寻找好的做法。

【问题讨论】:

    标签: r function default-value


    【解决方案1】:

    1) 尝试在 newfun 中重新定义 table 和 xtabs。确保 fun 通过将其转换为字符并使用 do.call 来调用本地版本。

    newfun <- function(..., fun) {
      table <- function(x, ..., useNA = "ifany") base::table(x, ..., useNA = useNA)
      xtabs <- function(x, ..., na.action = NULL, addNA = NULL)
          stats::xtabs(x, ..., na.action = na.action, addNA = addNA)
      fun <- deparse(substitute(fun))
      do.call(fun, list(...))
    }
    
    newfun(warpbreaks[-1], fun = table)
    newfun(breaks ~ ., warpbreaks, fun = xtabs)
    

    2) 另一种方法是使用 3 个函数,一个用于您的 table 版本,一个用于您的 xtabs 版本,然后一个包含其他每个人都会调用的公共代码。这可能比 (1) 更直接。

    mytable <- function(..., useNA = "ifany") {
      tab <- table(..., useNA = useNA)
      other(tab)
      tab
    }
      
    myxtabs <- function(..., na.action = NULL, addNA = TRUE) {
      tab <- xtabs(..., na.action = na.action, addNA = addNA)
      other(tab)
      tab
    }
    
    other <- function(x) {
      # code
    }
    

    【讨论】:

    • 非常感谢,完美运行!小错字:addNA = NULL 应该是addNA = TRUE。另外,您对如何将fun 仅限制为tablextabs 有什么建议吗? stopifnot(identical(fun, table) | identical(fun, xtabs)) 够好吗?最后,deparse(substitute(fun))match.fun 有什么好处吗?
    • 试试stopfinot(fun %in% c("table", "xtabs"))。 match.fun(fun) 不起作用,因为它将使用原始功能。我们要使用同名的本地函数。
    • 再次非常感谢您!但是,我得到Error in match(x, table, nomatch = 0L) : 'match' requires vector arguments。你有别的想法吗?理想情况下,我不希望提供 fun 作为名称。
    • 必须在乐趣转换为角色之后放置。已添加 (2)。
    猜你喜欢
    • 2014-07-18
    • 2022-07-20
    • 1970-01-01
    • 2021-05-04
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多