user111092
user111092

Reputation: 33

lapply with optional function argument and optional vector arguments

I have a function in R, say
f1 <- function(x,y,vec, func0,...){
...
...
...
return(out) }

The arguments func0 and vec in this function f1 are function object and some vector object respectively. Now I want to repeat this function 'reps' times (everything else being the same). I have stored the arguments of this function in a list as there are a lot of arguments and I keep changing them to do the replications again.

list1 <- list(x,y,vec, func0, other arguments)

Then I want to do, f1_reps <- lapply(1:reps, f1, list1)

I get an error when I do this as the function arguments func0 and vec are not found.

Any help in this direction would be helpful. Here is a mock example of the situation.

Here is an example,

a <- function(n){
  sqrt(n)
}
N = 100
out <- rep(NA,N)
# simple function with multiple arguments
foo <- function(a=a, b= c(1:3), c= 1000){
  for(n in 1:N){
    out[n] <- b%*%b+ a(n)*c
  }
  return(out)
}

candidates <- list(a=a, b = c(1:3), c=1000)
lapply(1:4, foo(a=candidates$a,b=candidates$b,c=candidates$c))  ## Doesn't work
lapply(1:4, foo, a=candidates$a, b=candidates$b, c=candidates$c) ## Doesn't work

candidates2 <- c(a=a, b = c(1:3), c=1000) # A vector of arguments
lapply(1:4, foo, a=candidates2$a, b = c(candidates2$b1,candidates2$b2,candidates2$b3), c=candidates2$c) #Doesn't work either

Upvotes: 1

Views: 228

Answers (2)

Cole
Cole

Reputation: 11255

This uses the dots aka the ... argument:

foo2 <- function(...) {
#I just returns the identity
  l <- lapply(..., I)
  a <- l[[1]]
  b <- l[[2]]
  c <- l[[3]]

  for(n in 1:N){
    out[n] <- b%*%b+ a(n)*c
  }
  return(out)
  }


candidates <- list(a=a, b = c(1:3), c=1000)

foo2(candidates)
# or to simplify. Same output as previous.
c(crossprod(1:3)) + sqrt(seq_len(100)) * 1000

  [1]  1014.000  1428.214  1746.051  2014.000  2250.068  2463.490  2659.751  2842.427  3014.000  3176.278  3330.625  3478.102  3619.551  3755.657
 [15]  3886.983  4014.000  4137.106  4256.641  4372.899  4486.136  4596.576  4704.416  4809.832  4912.979  5014.000  5113.020  5210.152  5305.503
 [29]  5399.165  5491.226  5581.764  5670.854  5758.563  5844.952  5930.080  6014.000  6096.763  6178.414  6258.998  6338.555  6417.124  6494.741
 [43]  6571.439  6647.250  6722.204  6796.330  6869.655  6942.203  7014.000  7085.068  7155.428  7225.103  7294.110  7362.469  7430.198  7497.315
 [57]  7563.834  7629.773  7695.146  7759.967  7824.250  7888.008  7951.254  8014.000  8076.258  8138.038  8199.353  8260.211  8320.624  8380.600
 [71]  8440.150  8499.281  8558.004  8616.325  8674.254  8731.798  8788.964  8845.761  8902.194  8958.272  9014.000  9069.385  9124.434  9179.151
 [85]  9233.544  9287.618  9341.379  9394.832  9447.981  9500.833  9553.392  9605.663  9657.651  9709.360  9760.794  9811.959  9862.858  9913.495
 [99]  9963.874 10014.000

Upvotes: 0

Jonny Phelps
Jonny Phelps

Reputation: 2727

The main issue is your function f1 takes an input of variables, not a list of the variables. This is one way you could approach it, with a simple eg, if I've understood correctly how your inputs are stored

# simple function with multiple arguments
foo <- function(a=1, b=2, c=3){
  return(a+b+c)
}

# works
foo(a=1, b=2, c=3)
# doesn't work as not required format
foo(list(a=1, b=2, c=3))

# formatted list such that each element has 5 elements
candidates <- list(
  a=1:5,
  b=2:6,
  c=3:7
)

# you need to apply the variables one by one with this setup
N <- 5
out <- lapply(1:N, function(i){
  foo(a=candidates$a[i]
      ,b=candidates$b[i]
      ,c=candidates$c[i])
})
out 

Upvotes: 0

Related Questions