How can I pass multiple arguments to a function as a single vector?

21,720

Solution 1

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

Solution 2

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"
Share:
21,720
rsgmon
Author by

rsgmon

Updated on March 15, 2021

Comments

  • rsgmon
    rsgmon over 3 years

    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?