Running a function with multiple arguments when an argument is not used

試著忘記壹切 提交于 2020-06-17 09:42:28

问题


I think my question can be made quite generic and simple, so that I will not give the concrete function that I am trying to make.

I have a function that changes its behaviour according to its first argument:

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

    final <- bind_rows(arg2)

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

  }


  return(final)
}

My issue is that if I run example(arg1 = T, arg3 = x, c(A,B), c(C,D)), considering that the user of my function probably won't write out anything for arg2, I have a problem. c(A,B) ends up not being considered the first element of list1 (I guess it is assigned to arg2 and then goes unused in the function) and I have bind_rows(c(C,D), x) as the output, instead of bind_rows(c(A,B), c(C,D), x).

How can this be fixed, considering that the function is not for personal use, but for a larger package?


回答1:


put arg2 in ...

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)
}



回答2:


Weirdly enough, you can switch the order of your arguments and have those dots first.

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

Created on 2020-06-10 by the reprex package (v0.3.0)

I don't know if this is advised (and I'm hesitant to suggest this), but it does solve your issue using the code you've provided. The answer proposed by @Waldi is a much better solution to your problem.



来源:https://stackoverflow.com/questions/62296913/running-a-function-with-multiple-arguments-when-an-argument-is-not-used

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!