【问题标题】:Running a function with multiple arguments when an argument is not used在不使用参数时运行具有多个参数的函数
【发布时间】:2020-06-10 06:09:50
【问题描述】:

我认为我的问题可以变得非常笼统和简单,因此我不会给出我正在尝试制作的具体功能。

我有一个函数可以根据它的第一个参数改变它的行为:

example <- function(arg1 = T,
                    arg2 = NULL,
                    arg3,
                    ...) {
  if (arg1 != T) {

    final <- bind_rows(arg2)

  } else{
    list1 <- list(...)
    final <- bind_rows(list1, arg3)

  }


  return(final)
}

我的问题是,如果我运行 example(arg1 = T, arg3 = x, c(A,B), c(C,D)),考虑到我的函数的用户可能不会为 arg2 写出任何内容,我就有问题了。 c(A,B) 最终不被视为list1 的第一个元素(我猜它被分配给arg2 然后在函数中未使用)并且我有bind_rows(c(C,D), x) 作为输出,而不是bind_rows(c(A,B), c(C,D), x)

考虑到该功能不是供个人使用,而是用于更大的包装,如何解决此问题?

【问题讨论】:

  • 不幸的是,我认为arg2 的编写方式不能跳过。不过,我认为example(arg1 = T, arg3 = x, ,c(A,B), c(C,D)) 可能会起作用。
  • 请考虑省略号不需要是函数的最后一个参数。如果用户需要使用arg2,则可以命名。
  • 顺便说一句:最好写TRUE而不是T,然后写if(!arg1) ...

标签: r function


【解决方案1】:

将 arg2 放入...

example <- function(arg1 = T,
                    arg3,
                    ...) {
  args <- list(...)
  if (is.null(args$arg2) & arg1==F) {stop("arg2 needed when arg1==F")}

  if (arg1 != T) {

    final <- list(arg2)

  } else{
    list1 <- list(...)
    final <- list(list1, arg3)

  }


  return(final)
}

【讨论】:

  • 但这可能会让用户感到困惑,因为... 将包含 arg2 和具有完全不同性质的向量列表,不是吗?我
  • 用户应该在函数调用中命名为 arg2 = val :example(T, arg2 =1,c(5,4,3))
  • 它会起作用,我的观点是,在函数的主要参数中使用... 并且没有明确的arg2,用户不会知道如果 arg1 != F,则需要一些东西在名为 arg2
  • 查看我的编辑:在这种情况下我添加了一条错误消息
【解决方案2】:

奇怪的是,您可以切换参数的顺序,然后将这些点放在首位。

library(dplyr)
#> Warning: package 'dplyr' was built under R version 3.6.3
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

ex <- function(...,
               arg1 = T,
               arg2 = NULL,
               arg3) {
  if (arg1 != T) {
    final <- bind_rows(arg2)
  } else{
    list1 <- list(...)
    final <- bind_rows(list1, arg3)
  }
  return(final)
}

ex(arg1 = T, arg3 = iris[1, ], iris[2, ], iris[3, ])
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          4.9         3.0          1.4         0.2  setosa
#> 2          4.7         3.2          1.3         0.2  setosa
#> 3          5.1         3.5          1.4         0.2  setosa

reprex package (v0.3.0) 于 2020-06-10 创建

我不知道是否建议这样做(我很犹豫是否建议这样做),但它确实使用您提供的代码解决了您的问题。 @Waldi 提出的答案对您的问题是一个更好的解决方案。

【讨论】:

    猜你喜欢
    • 2019-07-18
    • 1970-01-01
    • 2021-11-20
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    相关资源
    最近更新 更多