简体   繁体   中英

R passing missing arguments through functions

I can't seem to find an SO post that helps me solve this problem. My minimally reproducible example is:

bigfn <- function(x) {
  smallfn(x)
}

smallfn <- function(y) {
  y <- rlang::enquo(y)
  print(y)
  print(rlang::quo_is_missing(y))
}

The output of bigfn() is:

<quosure>
expr: ^x
env:  0x7fc93fc0f8c8
[1] FALSE

But I would like the quosure to be an empty quosure and FALSE to be TRUE to reflect the fact that bigfn propagated down a missing value through smallfn .

Additionally, I don't want to just move the enquo into bigfn because I would still like to be able to use smallfn independent of bigfn .

Perhaps a pattern called "forwarding the dots" may be useful here. It preserves missing arguments and behaves well in the context of non-standard evaluation:

bigfn <- function(...) {
  smallfn(...)
}

bigfn()
# <quosure>
# expr: ^
# env:  empty
# [1] TRUE

However, if you do need to have specific arguments referenced by name, you will need to "tunnel" them with {{ (which is shorthand for !!enquo ) to smallfn() :

bigfn <- function(x) {
  smallfn({{x}})
}

bigfn()
# <quosure>
# expr: ^
# env:  empty
# [1] TRUE

bigfn(42)
# <quosure>
# expr: ^42
# env:  empty
# [1] FALSE

Why not do:

bigfn <- function(x) {
  if(missing(x)) smallfn()
  else smallfn(x)
}

Then, without changing smallfn you have:

bigfn()
#> <quosure>
#> expr: ^
#> env:  empty
#> [1] TRUE

bigfn(2)
#> <quosure>
#> expr: ^x
#> env:  00000000119E8FD0
#> [1] FALSE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM