In R, how do I define a function like f <- function(x){...}
which can only take the argument x
to be 'a'
or 'b'
?
[BTW, what is the current (as of 2020) best/easy/practical package for creating functions in R? Is it still roxygen?]
In R, how do I define a function like f <- function(x){...}
which can only take the argument x
to be 'a'
or 'b'
?
[BTW, what is the current (as of 2020) best/easy/practical package for creating functions in R? Is it still roxygen?]
One canonical (idiomatic) way in R to allow one of so many values for a function argument is to use match.arg
:
f <- function(x = c("a", "b")) {
x <- match.arg(x)
}
Since it defaults to several.ok=FALSE
, it reduces x
to a single argument. If nothing is provided, then it will default to the first value in the vector.
However, note that since it uses pmatch
internally, it allows partial matching. This means:
match.arg('a',c('aa','bb'))
# [1] "aa"
which may not be desired. In that case, then RonakShah's first suggestion (modified to check length as well) is likely the most direct, one of the following if
statements:
f <- function(x) {
if (is.null(x) || length(x) != 1L || !x %in% c("a", "b")) {
stop("'x' argument must be one of: 'a','b'")
}
### or, if 'x' can have length>1, then
if (is.null(x) || !length(x) || !all(x %in% c("a", "b"))) {
stop("'x' argument must be one of: 'a','b'")
}
# ...
}
If x
can legitimately have a length greater than 1, update the conditional to be !all(x %in% c("a","b"))
.
FYI: roxygen
is not for creating functions. I believe its power initially was that it kept the documentation in the same place as the code, which might prod the developer into updating the documentation when the function itself is modified. I believe in practice that this is perhaps too optimistic, especially with large functions where the roxygen docs are well off the page.
However, another benefit (in a subsequent release) is that it supports markdown-formatted documentation, no longer requiring the user to use R-centric formatting (e.g., for URLs, links to other R functions/packages, code, emphasis, etc).