170

I have a function f(var1, var2) in R. Suppose we set var2 = 1 and now I want to apply the function f() to the list L. Basically I want to get a new list L* with the outputs

[f(L[1],1),f(L[2],1),...,f(L[n],1)]

How do I do this with either apply, mapply or lapply?

Braiam
  • 1
  • 11
  • 47
  • 78
Michael
  • 7,087
  • 21
  • 52
  • 81

3 Answers3

232

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.

Ari B. Friedman
  • 71,271
  • 35
  • 175
  • 235
  • 5
    but note that `myfxn` may be vectorised, in which case one should use `myfxn(unlist(mylist), var2=var2)` – baptiste Jul 26 '11 at 21:08
  • The original example was unclear but seemed to be to be non-vectorized. Point well taken, however. – Ari B. Friedman Jul 26 '11 at 21:14
  • Is the a way to make this work as a function "on the fly?" Something like this: `sapply(mylist, function(var1, var2) { var1*var2 }, var=thisvar2)` But I get an error that argument 2 matches multiple formal arguments – emudrak Jan 26 '17 at 18:43
  • 1
    @emudrak I think the problem there is jus that you're naming the argument you pass `var` instead of `var2`. R can't divine what you mean. – Ari B. Friedman Jan 30 '17 at 14:32
80

If your function have two vector variables and must compute itself on each value of them (as mentioned by @Ari B. Friedman) you can use mapply as follows:

vars1 <- c(1, 2, 3)
vars2 <- c(10, 20, 30)
mult_one <- function(var1, var2)
{
   var1*var2
}
mapply(mult_one, vars1, vars2)

which gives you:

> mapply(mult_one, vars1, vars2)
[1] 10 40 90
ah bon
  • 9,293
  • 12
  • 65
  • 148
Alexander Borochkin
  • 4,249
  • 7
  • 38
  • 53
  • 6
    One upvote for generalizing, even with a simple and clear example. – JASC Dec 27 '18 at 17:51
  • 2
    `mapply` will also recycle if `vars1` has a single element. For example when `vars1 <- 3`, `mapply(mult_one, vars1, vars2)` returns `30 60 90`. This is useful when you want to use `lapply` over the second argument of a function. – Paul Rougieux Jun 10 '19 at 09:12
  • 1
    Does `mapply` work with more than 2 arguments in the fucntion ? – Julien Jul 02 '22 at 17:48
14

To further generalize @Alexander's example, outer is relevant in cases where a function must compute itself on each pair of vector values:

vars1 <- c(1,2,3)
vars2 <- c(10,20,30)
mult_one <- function(var1, var2)
{
   var1*var2
}
outer(vars1, vars2, mult_one)

gives:

> outer(vars1, vars2, mult_one)
     [,1] [,2] [,3]
[1,]   10   20   30
[2,]   20   40   60
[3,]   30   60   90
ah bon
  • 9,293
  • 12
  • 65
  • 148
Martin Smith
  • 3,687
  • 1
  • 24
  • 51