1

I am trying to write a function that can return which arguments from the calling function are missing.

find_missing_args <- function(...) {
  args <- rlang::enquos(...)
  lapply(args, rlang::is_missing)
}

func <- function(x, y, z) {
  find_missing_args(x, y, z)
}

However, the functionality is not as expected:

func(x = 1, y = 2)

Returns

[[1]]
[1] FALSE

[[2]]
[1] FALSE

[[3]]
[1] FALSE

It should return:

[[1]]
[1] FALSE

[[2]]
[1] FALSE

[[3]]
[1] TRUE

Because z was not supplied in the calling function. I would also like to be able to pass which arguments I care about to find_missing_args, so for example:

find_missing_args <- function(...) {
  args <- rlang::enquos(...)
  lapply(args, rlang::is_missing)
}

func <- function(x, y, z, a, b, c) {
  find_missing_args(x, y, z)
}

func(x = 1, y = 2, a = 3, b = 4) will return:

[[1]]
[1] FALSE

[[2]]
[1] FALSE

[[3]]
[1] TRUE

but ignore a, b, c.

UPDATE WITH ANSWER:

find_missing_args <- function(args) {
  supplied <- rlang::call_args_names(rlang::caller_call(n = 1))
  setdiff(args, supplied)
}

func <- function(x, y, z, a, b, d) {  
  find_missing_args(c("x","y","z"))
}

func(x = 1, y = 2)

[1] "z"

Interestingly,

find_missing_args <- function(args) {
  supplied <- rlang::call_args_names(rlang::caller_call(n = 1))
  setdiff(args, supplied)
}

func <- function(x, y, z, a, b, c) {  
  find_missing_args(c("x","y","z"))
}

func(x = 1, y = 2)

Error in c("x", "y", "z") : argument "c" is missing, with no default

I have not figured out why it interprets c() to be the argument c and not the function c().

Dylan Russell
  • 936
  • 1
  • 10
  • 29

1 Answers1

2

I don't delve into these sorts of mechanics often, so I'm not sure how robust or "idiomatic" this is, but I think this gets at what you want?

find_missing_args <- function(...) {
  a1 <- rlang::call_args_names(rlang::caller_call(n = 1))
  a2 <- rlang::fn_fmls_names(rlang::caller_fn(n = 1))
  setdiff(a2,a1)
}

func <- function(x, y, z) {
  find_missing_args()
}

func(x = 1,y = 2)
joran
  • 169,992
  • 32
  • 429
  • 468
  • This is close to the functionality I wanted, the issue is I want to be able to select which arguments I pass to `find_missing_args`. See my addendum. – Dylan Russell Mar 09 '23 at 21:26
  • @DylanRussell In that case couldn't you simply pass them as a character vector and use that in `setdiff()` instead of the full list in `a2`? – joran Mar 09 '23 at 21:49