R带有match.arg的enum-like参数:如何选择非第一个元素作为默认值?

R带有match.arg的enum-like参数:如何选择非第一个元素作为默认值?,r,function,enums,arguments,R,Function,Enums,Arguments,如何将多个允许参数值中第一个以外的值声明为默认值(如果没有传入值) 库(stats) 居中您可以修改match.arg以获取第二个arg值,而不是第一个值。这只是在函数体中查找并替换该行的问题 matchArg <- base::match.arg body(matchArg)[[c(4, 3, 2, 3)]] <- quote(return(arg[2L])) 当然,这不符合您的可见性要求。但是这是一个想法。多亏@RichScriven的公认答案,他展示了如何修改匹配。arg我找

如何将多个允许参数值中第一个以外的值声明为默认值(如果没有传入值)

库(stats)

居中您可以修改
match.arg
以获取第二个
arg
值,而不是第一个值。这只是在函数体中查找并替换该行的问题

matchArg <- base::match.arg
body(matchArg)[[c(4, 3, 2, 3)]] <- quote(return(arg[2L]))

当然,这不符合您的可见性要求。但是这是一个想法。

多亏@RichScriven的公认答案,他展示了如何修改
匹配。arg
我找到了一种方法,可以同时注释函数签名中的默认值(这是我问题中的一个可选愿望)

诀窍是使用向量元素的名称“注释”默认值:

matchArg <- base::match.arg
body(matchArg)[[c(4, 3, 2, 3)]] <- quote(
  return(
    if ("default" %in% names(arg)) {
      arg[["default"]] }
    else {
      arg[[1L]]
    })
)

center <- function(x, type = c("mean", default = "median", "trimmed")) {
  type <- matchArg(type)
  switch(type,
         mean = mean(x),
         median = median(x),
         trimmed = mean(x, trim = .1))
}

matchArg@RichScriven:我想调用中心(值),但想在函数声明(而不是调用)中指定第二个值作为默认值。可见性是一个可选的愿望,我最喜欢的是修改
match.arg
,并添加一个参数来指定默认值,使默认值至少在函数体中可见。THX展示了如此复杂的编程方式(修改函数体的解析树:-)@ALL:要查看函数体的AST,您可以使用
pryr::call_tree(body(matchArg))
@rich scriven。这很酷。作为次要的编码点,您可以在第二行中使用递归索引,将
body(matchArg)[[4]][[3]][[2]][[3]]
替换为
body(matchArg)[[c(4,3,2,3)]
。当然,这是一个品味的问题,但角色较少。@lmo-不错的角色!添加到帖子中。非常感谢。真是太棒了,R也允许这样。
matchArg <- base::match.arg
body(matchArg)[[c(4, 3, 2, 3)]] <- quote(return(arg[2L]))
center <- function(x, type = c("mean", "median", "trimmed")) {
  type <- matchArg(type)
  switch(type,
         mean = mean(x),
         median = median(x),
         trimmed = mean(x, trim = .1))
}

values <- c(100, 120, 200)

center(values)  
# [1] 120
center(values, "mean")
# [1] 140
matchArg <- base::match.arg
body(matchArg)[[c(4, 3, 2, 3)]] <- quote(
  return(
    if ("default" %in% names(arg)) {
      arg[["default"]] }
    else {
      arg[[1L]]
    })
)

center <- function(x, type = c("mean", default = "median", "trimmed")) {
  type <- matchArg(type)
  switch(type,
         mean = mean(x),
         median = median(x),
         trimmed = mean(x, trim = .1))
}
> values <- c(100, 120, 200)
> center(values, "median")
[1] 120
> center(values, "mean")
[1] 140
> center(values)
[1] 120