1

Suppose I have following function:

my.fun1 <- function(a,b,c){
  a * c + b
}

If I want to call it several times with multiple arguments I can do:

> my.fun1(1, 1, c(1:3))
[1] 2 3 4
> my.fun1(2, 2, c(1:3))
[1] 4 6 8
> my.fun1(3, 3, c(1:3))
[1]  6  9 12

But if I use mapply I get this:

> mapply(my.fun1, c(1:3), c(1:3), c(1:3))
[1]  2  6 12

Instead of desired:

[[1]]
[1] 2 3 4

[[2]]
[1] 4 6 8

[[3]]
[1]  6  9 12

IMHO the problem is that mapply basically translates the function call to:

> my.fun1(1, 1, 1)
[1] 2
> 
> my.fun1(2, 2, 2)
[1] 6
> 
> my.fun1(3, 3, 3)
[1] 12

How can I pass last argument of mapply directly to my.fun1 without being treat as argument to mapply but rather to my.func1?

PS: I've been playing with anonymous functions inside maplpy call. The closest is get (based on suggestions here):

> x <- mapply(function(x, y){my.fun1(x, y, c(1:3))}, c(1:3), c(1:3))
> split(x, rep(1:ncol(x), each = nrow(x)))
$`1`
[1] 2 3 4

$`2`
[1] 4 6 8

$`3`
[1]  6  9 12

But I guess this is ugly approach and there must be better way.

Community
  • 1
  • 1
Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122

1 Answers1

4

As the last input in my.fun1 is the same vector, we place that in a list and pass it as argument for Map or mapply.

Map(my.fun1, 1:3, 1:3, list(1:3))

Or as @baptiste mentioned, the constants can be passed with MoreArgs

Map(my.fun1, 1:3, 1:3, MoreArgs = list(c=1:3))

When we are using mapply, it is better to have SIMPLIFY=FALSE to avoid coercing the list to matrix (if the lengths of the list elements are the same.

mapply(my.fun1, 1:3, 1:3, list(1:3), SIMPLIFY=FALSE)
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 3
    i would usually pass constants as `MoreArgs=list(c=1:3)` – baptiste Apr 05 '16 at 09:07
  • @thank you. I see that in both cases (`Map` and `mapply`) casting vector to list is used. Why this work this way, is list passed somehow differently to function than vector or what is the trick? – Wakan Tanka Apr 05 '16 at 11:20
  • 1
    @WakanTanka `Map` is a convenient function for `mapply`. If you check the `Map` function, it is just `mapply(FUN = f, ..., SIMPLIFY = FALSE)`. Regarding the `list` working differently, it is just that there is only a single element in that `list`. So,it got recycled for each of the corresponding elements of the vectors – akrun Apr 05 '16 at 11:41