This should be really basic but I'm totally new to defining functions in R.
Sometimes I want to define a function which simply consists of wrapping a base function in one or more other functions.
E.g., I wrote prop.table2
which basically accomplishes prop.table(table(...))
.
The hitch that I see is that I also want my wrapper function to take the optional arguments of any of the subfunctions and pass them appropriately,
E.g.,
prop.table2(TABLE, useNA = "always", margin = 2) =
prop.table(table(TABLE, useNA = "always"), margin = 2)
What's the simplest way to accomplish something like this (assuming there's no conflict in argument names, etc)? My baseline approach is to simply paste all of the optional arguments to each subfunction into the main function definition, i.e., defining:
prop.table2 <- function(..., exclude = if (useNA == "no") c(NA, NaN),
useNA = c("no", "ifany", "always"), dnn = list.names(...),
deparse.level = 1, margin = NULL)
Let's work from this example for concreteness:
dt <- data.table(id = sample(5, size = 100, replace = TRUE),
grp = letters[sample(4, size = 100, replace=TRUE)])
I want to replicate the following with my function:
dt[ , prop.table(table(grp, id, useNA = "always"), margin = 1)]
id
grp 1 2 3 4 5 <NA>
a 0.28571429 0.10714286 0.17857143 0.25000000 0.17857143 0.00000000
b 0.12000000 0.28000000 0.08000000 0.12000000 0.40000000 0.00000000
c 0.23076923 0.23076923 0.15384615 0.19230769 0.19230769 0.00000000
d 0.23809524 0.19047619 0.23809524 0.28571429 0.04761905 0.00000000
<NA>
Here's where I'm at now, which still doesn't quite work; the idea was to split everything into those arguments which prop.table
accepts and then pass the rest to table
, but I'm still struggling.
prop.table2 <- function(...) {
dots <- list(...)
dots2 <- dots
dots2[intersect(names(dots2), names(formals(prop.table)))] <- NULL
dots3 <- dots2
dots3[intersect(names(dots3), names(formals(table)))] <- NULL
dots2[names(dots2) == ""] <- NULL
prop.table(table(dots3, dots2), margin = list(...)$margin)
}