I created the following function with six args:
nDone <- function(under,strike,ttoe,vol,rf,dy) { pnorm(((log(under/strike)+ (rf-dy+(vol^2)/2)*ttoe)/(vol*(ttoe^0.5)))) } nDone(90,100,3,0.17,0.05,0) # Result: [1] 0.6174643
Now I create a vector with the same values in an object, and try to call the function using the vector, but get the following error:
d <- c(90,100,3,0.17,0.05,0) nDone(d) Error in under/strike : 'strike' is missing
What am I doing wrong and how to fix?
Some functions are designed to return values, while others are designed for other purposes. We pass arguments in a function, we can pass no arguments at all, single arguments or multiple arguments to a function and can call the function multiple times. Example: Python.
Except for functions with variable-length argument lists, the number of arguments in a function call must be the same as the number of parameters in the function definition. This number can be zero. The maximum number of arguments (and corresponding parameters) is 253 for a single function.
The varargs functionality allows you to pass any number of arguments to a method. The method must be set up with the type of data and a variable name to hold the elements. You can add more parameters to the method, but the varargs statement must be the last one.
Try this
do.call(nDone, as.list(d))
Explanation of what's happening in your first attempt by @joran from the comments:
R is seeing you pass a single argument to nDone
, namely the vector d
, which is handed off to the first function argument, under
. Since you haven't specified a default value for the others, they are missing and hence the error
Maybe worth to add:
If your function can accept arguments that are vectors of length >1 and generates output of the same length, do.call
can handle that, too, and you will need list()
:
x <- c("a", "b", "c") y <- c(1, 2, 3) > do.call(paste0,c(list(x),list(y))) [1] "a1" "b2" "c3"
watch out that this won't fail or warn for vectors of unequal lengths:
x <- c("a", "b") > do.call(paste0,c(list(x),list(y))) [1] "a1" "b2" "a3"
Of course paste0(x,y)
would work here just as well, but I'm using this e.g. for rgb()
:
# whichever complex functions to generate vector of floats: x <- seq(1,6) %>% exp() # rescale for rgb x <- scales::rescale(x) # make a list of vectors # note that as.list() would not give the desired output here x <- rep(list(x),3) # call > do.call(rgb, x) [1] "#000000" "#030303" "#0B0B0B" "#212121" "#5D5D5D" "#FFFFFF"
or a tidy one line:
> seq(1,6) %>% exp() %>% scales::rescale() %>% list() %>% rep(3) %>% do.call(rgb,.) [1] "#000000" "#030303" "#0B0B0B" "#212121" "#5D5D5D" "#FFFFFF"
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