I want to drop an element from an ellipsis because I want to set it manaully inside my function. The example below illustrates the point as the error is sensible given I'm passing na.rm
in manually and via ellipsis. How can I remove na.rm
from the ellipsis so that the error isn't thrown?
mymean <- function(x, ...){
dots <- list(...)
if (is.null(dots$na.rm)) {
na_arg <- TRUE
} else {
na_arg <- dots$na.rm
}
mean(x, na.rm = na_arg, ...)
}
set.seed(10); a <- c(rnorm(20), NA)
mymean(a)
## [1] -0.06053267
mymean(a, trim = .5)
## [1] -0.08275319
mymean(a, na.rm = TRUE, trim = .1)
## Error in mean.default(x, na.rm = na_arg, ...) :
## formal argument "na.rm" matched by multiple actual arguments
1) lm Look at the source code of lm. Following that:
mymean1 <- function(x, ...){
mc <- match.call()
mc[[1]] <- as.name("mean")
if (is.null(mc$na.rm)) mc$na.rm <- TRUE
eval(mc, parent.frame())
}
mymean1(a, na.rm = TRUE, trim = .1)
## [1] -0.01886715
mymean1(a, trim = .1)
## [1] -0.01886715
2) do.call This would also work although there is a subtle difference, namely ... gets evaluated. In this and most cases it won't matter but it might in some less usual cases.
mymean2 <- function(x, ...) {
dots <- list(...)
if (! "na.rm" %in% names(dots)) dots$na.rm <- TRUE
do.call("mean", c(list(x), dots))
}
mymean2(a, na.rm = TRUE, trim = .1)
## [1] -0.01886715
mymean2(a, trim = .1)
## [1] -0.01886715
3) ordinary arg However, it would be easier to just write:
mymean3 <- function(x, na.rm = TRUE, ...) mean(x, na.rm = na.rm, ...)
mymean3(a, na.rm = TRUE, trim = .1)
## [1] -0.01886715
mymean3(a, trim = .1)
## [1] -0.01886715
This is the usual way wrappers with different defaults are written. For example see the read.csv source code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With