4

This question may sound silly for the toy example I provide but it actually make sense in the real situation I'm facing.

Assume function f such as:

f <- function(x) {
    if (missing(x)) 
        "something very nice happens if x is missing" 
    else 
        "something else that is also very nice happens if x not missing"
}

Sometimes I need to call f just as f() but sometimes with specified arguments.

One way to do it (based on some condition cond):

if (cond) f(1) else f()

But such construction will grow in complexity (like a cartesian product) with the need of additional arguments. I would therefore like to call f this way:

f(if (cond) 1 else *)

where * is supposed to be "nothing".

If I were the owner of f I could rewrite it as:

 f <- function(x = NULL) {
    if (null(x)) 
        "something very nice happens if x is null" 
    else 
        "something else that is also very nice happens if x not null"
}

and use * = NULL. Unfortunately I can not do this so another way would be much appreciated!

P.S. This is my first question on StackOverflow :-) D.S.

3
  • 2
    @Frank I think it's not a duplicate. OP is asking for functions he can't change easily (e.g., from packages). Commented Sep 24, 2015 at 15:44
  • Btw., welcome to Stack Overflow! That's a very nice first question. Commented Sep 24, 2015 at 15:50
  • Thank you very much @Roland! This was a very nice experience :-) Commented Sep 25, 2015 at 7:40

2 Answers 2

2

You could use do.call with an alist:

f <- function(x, y) {
  if (missing(x)) 
    "something very nice happens if x is missing" 
  else 
    "something else that is also very nice happens if x not missing"
}

helper <- function(x = NULL, y) {
  args <- alist(x = , y = y)
  if (!is.null(x)) args[["x"]] <- x
  do.call(f, args)
}

helper(1, 1)
#[1] "something else that is also very nice happens if x not missing"
helper(NULL, 1)
#[1] "something very nice happens if x is missing"
helper(if (1 > 2) 3, 1)
#[1] "something very nice happens if x is missing"
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! My first occurrence of alist. Nice!
0

Following @Roland's lead, I would do...

helper <- function(f, ..., ifmissing=NULL){
    lacked <- setdiff(names(formals(f)), names(list(...)))
    wanted <- names(ifmissing)

    missed <- intersect(lacked,wanted)    
    if (length(missed)){
        ifmissing[[ missed[1] ]]
    } else {
        f(...)
    }
}

Here is an example. g is a function you cannot modify, but you have a list of actions to follow when each of its arguments is missing. The first argument missing (if any) determines the value returned.

g <- function(x,y) x^y

helper_g <- function(...){
    cond <- list(
        x = "d'oh, base is missing",
        y = "gah, exponent is missing"
    )
    helper(g, ..., ifmissing=cond)
}

helper_g(x=2,y=3) # 8
helper_g(y=3)     # "d'oh, base is missing"
helper_g(x=2)     # "gah, exponent is missing"
helper_g()        # "d'oh, base is missing"

(I realize this isn't exactly the same problem the OP is facing, where f already has internal rules for handling missing arguments.)

1 Comment

Thank you very much for the effort and the fast response!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.