Reputation: 978
I have a function that basically outputs a boolean condition as a string from the arguments (the details of the function don't matter here)
makeClause <-function(Sex=c("NA", "male", "female"),
SmokingHx=c("NA", "current", "former", "never"),
conjunction=c("&", "|")) {
arglist = as.list(match.call())
return(arglist)
}
I have a data frame that has all combinations of input arguments, as:
Sex SmokingHx conjunction
1 NA NA &
2 Male NA &
...
Which I obtain this way:
combinations = expand.grid(Sex=c("NA", "male", "female"),
SmokingHx=c("NA", "current", "former", "never"),
conjunction=c("&", "|"),
stringsAsFactors=FALSE)
And I call makeClause
with mapply
:
mapply(makeClause, Sex=combinations$Sex,SmokingHx=combinations$SmokingHx, conjunction=combinations$conjunction)
Looking at the arglist
variable I get:
$Sex
dots[[1L]][[1L]]
$SmokingHx
dots[[2L]][[1L]]
$conjunction
dots[[4L]][[1L]]
And if instead of as.list(match.call())
I call as.list(environment())
I get instead:
$Sex
[1] "male"
$SmokingHx
[1] "NA"
$conjunction
dots[[4L]][[1L]] # notice this is the only one for which I don't get the actual string
So I have two questions:
Thanks
Upvotes: 3
Views: 253
Reputation: 52637
match.call
captures the quoted call as a language object. The dots
business is what mapply
is using to invoke your function, so the return value of match.call
is correct. It is just matching the call that mapply
constructed for your function and returning the quoted (i.e. unevaluated) values. Internally mapply
is doing something like this (though not really since it is internal C code):
dots <- list(...)
call <- list()
for(j in seq_along(dots[[1]])) {
for(i in seq_along(dots)) call[[i]] <- bquote(dots[[.(j)]][[.(i)]])
eval(as.call(c(quote(FUN), call))))
}
If you look at as.call(c(FUN, call))
you would see something like FUN(dots[[1L]][[1L]], dots[[1L]][[2L]], dots[[1L]][[3L]])
which helps explain why you were getting the results you were getting.
You seem to want the values of your argument. You could evaluate what you get from match.call
, or simpler, just use:
list(Sex, SmokingHx, conjunction)
If you want something that gets all the arguments of your function without having to know their names you can do something like:
mget(names(formals()))
Try (simplifying fun for clarity):
makeClause <-function(Sex, SmokingHx, conjunction) mget(names(formals()))
with(combinations, t(mapply(makeClause, Sex, SmokingHx, conjunction)))
Produces:
Sex SmokingHx conjunction
NA "NA" "NA" "&"
male "male" "NA" "&"
female "female" "NA" "&"
NA "NA" "current" "&"
male "male" "current" "&"
female "female" "current" "&"
... further rows omitted
Upvotes: 3