Passing Several Arguments to Fun of Lapply (And Others *Apply)

passing several arguments to FUN of lapply (and others *apply)

If you look up the help page, one of the arguments to lapply is the mysterious .... When we look at the Arguments section of the help page, we find the following line:

...: optional arguments to ‘FUN’.

So all you have to do is include your other argument in the lapply call as an argument, like so:

lapply(input, myfun, arg1=6)

and lapply, recognizing that arg1 is not an argument it knows what to do with, will automatically pass it on to myfun. All the other apply functions can do the same thing.

An addendum: You can use ... when you're writing your own functions, too. For example, say you write a function that calls plot at some point, and you want to be able to change the plot parameters from your function call. You could include each parameter as an argument in your function, but that's annoying. Instead you can use ... (as an argument to both your function and the call to plot within it), and have any argument that your function doesn't recognize be automatically passed on to plot.

passing more than one argument to FUN of lapply

You can do:

library(purrr)

map2(1:3, 1:3, fn)

[[1]]
res text
1 1 a
2 1 b
3 2 total

[[2]]
res text
1 2 a
2 2 b
3 4 total

[[3]]
res text
1 3 a
2 3 b
3 6 total

If you wanto to stick to mapply you can do:

x <- mapply(fn, b = 1:3, a = 1:3, SIMPLIFY = F)

or

x <- Map(fn, b = 1:3, a = 1:3)

which is a wrapper for mapply with SIMPLIFY = F.

Passing multiple arguments to lapply from a dataframe

With apply in the second argument you need to pass the MARGIN which is to specify if you want to apply the function row-wise (1) or column-wise (2). Also you would need to use an anonymous function here since your function accepts two separate arguments.

apply(combined, 1, function(x) my_func(x[1], x[2]))

Applying a function with two arguments using Lapply

Change your function to

testFunc<-function(x,y){
return(c(length(x), nrow(y)))
}

By default, a R function returns the last evaluated value

using sapply with a function that has multiple arguments

Use an anonymous function for clarity -

sapply(prep1, function(x) BTm(cbind(win1,win2), player1, player2, data= x))

The same should work with lapply as well.

R apply function with multiple parameters

Just pass var2 as an extra argument to one of the apply functions.

mylist <- list(a=1,b=2,c=3)
myfxn <- function(var1,var2){
var1*var2
}
var2 <- 2

sapply(mylist,myfxn,var2=var2)

This passes the same var2 to every call of myfxn. If instead you want each call of myfxn to get the 1st/2nd/3rd/etc. element of both mylist and var2, then you're in mapply's domain.

R lapply with several dynamic arguments

Your result from mapply() is because the function tries to convert the output to a matrix with the simplify argument by default. You can get your desired output with the following:

prices <- mapply(lots$ticker, FUN = tq_get, 
from = lots$buy_date,
get = "stock.prices",
to = today(), SIMPLIFY = FALSE)

Passing a function as an argument to FUN in lapply

Ooh, you're close. You just need the expression to be a function.

fit <- function(x, expr = function(i) splines::bs(i, df = 5)) {
nvars <- ncol(x)
x <- scale(x, center = TRUE, scale = FALSE)
design <- design_mat(x = x, expr = expr, nvars = nvars)
# then fit some model on design
}

send multiple arguments using apply function

Assuming you want to pass the row, and a single argument that is the same for each row:

manydo3 <- function(x, r1) NULL
apply(eq, 1, manydo3, r1=18)

If you want different values for the second argument for each row, then you want to split your matrix into rows and pass both the rows and your other argument with mapply:

mapply(manydo3, split(eq, row(eq)), R)

where length(R) == nrow(eq) (i.e. R contains r1, r2, etc).

Using lapply with changing arguments

Apply over list names rather than list elements. E.g.:

somelist <- list('USA'=rnorm(10), 'Europe'=rnorm(10), 'Switzerland'=rnorm(10))
anotherlist <- list('USA'=5, 'Europe'=10, 'Switzerland'=4)
lapply(names(somelist), function(i) somelist[[i]] / anotherlist[[i]])

EDIT:

You also ask if there is a way "except for a loop" to do this "efficiently". You should note that the apply will not necessarily be more efficient. Efficiency will probably be determined by how quick your inner function is. If you want to operate on each elements of a list, you will need a loop, whether it is hidden in an apply() call or not. Check this question: Is R's apply family more than syntactic sugar?

The example I gave above can be re-written as a for loop, and you can make some naive benchmarks:

fun1 <- function(){
lapply(names(somelist), function(i) somelist[[i]] / anotherlist[[i]])
}
fun2 <- function(){
for (i in names(somelist)){
somelist[[i]] <- somelist[[i]] / anotherlist[[i]]
}
return(somelist)
}
library(rbenchmark)

benchmark(fun1(), fun2(),
columns=c("test", "replications",
"elapsed", "relative"),
order="relative", replications=10000)

The output of the benchmark on my machine was this:

    test replications elapsed relative
1 fun1() 10000 0.145 1.000000
2 fun2() 10000 0.148 1.020690

Although this is not a real work application and the functions are not realistic tasks, you can see that the difference in computation time is quite negligible.



Related Topics



Leave a reply



Submit