Search code examples
rvariadic-functions

base R — how to detect if var-args (...) had key names (named parameters) assigned?


I’d like to detect if the given var-args (...) to some function blah(...) has keys (named parameters) assigned by the caller:

blah = function(...) {
   # detect if key-names were given to ‘...’
   args = list(...)  #  seems to always have:  length(names(args)) == 2
}

# example calls:
blah(key1=someList1, userAssignedKeyName=someList2)
blah(someList1,someList2)   
  1. length(names(list(...))) == 0 doesn’t seem possible—R seems to default to some internal toString() representation for the name of key; ie, length(names(...)) == 2 always.

  2. I can’t declare function blah(...) as blah(key1=“”, key2=“”) and then detect by equality with “” because:

    i. This loses the var-args property

In base-R, how do I detect if the user has passed key-names (named their parameters) to ... above?

(It doesn’t seem possible to me since the R language spec seems to assume no ordering guarantees on named parameters; and also that the naming of parameters is done by the coder, not the caller; and that no such syntax for ... is supported).

Thanks!

EDIT: I think a kwargs named-list like Python is the way to go? So I’d drop the ‘...’ and use a named-list like a kwargs in Python.


Solution

  • I'm not sure if I understand what you mean here. If you want to know whether the user called the function using parameter names you can do:

    blah <- function(...) names(list(...))
    

    So, in your set-up we might have:

    someList1 <- list(a = "foo")
    someList2 <- list(a = "bar")
    
    blah(key1 = someList1, userAssignedKeyName = someList2)
    #> [1] "key1"                "userAssignedKeyName"
    
    blah(someList1, someList2) 
    #> NULL
    

    And contrary to what your question implies, if we have:

    blah <- function(...) length(names(list(...)))
    

    Then we get:

    blah(key1 = someList1, userAssignedKeyName = someList2)
    #> [1] 2
    
    blah(someList1, someList2) 
    #> [1] 0
    

    Or am I misunderstanding you?