 # Help in understanding behavior of functions as arguments when passed to map_dbl

Using map_dbl in a function works as I expected.

my_func <- function(){map_dbl(1:5, ~ sample(1:10, size = 1))}
my_func()
 6 8 9 7 6

But let's redefine my_func to accept a function as an argument:

my_func <- function(FUN){map_dbl(1:5, ~ FUN)}

I would expect this to work the same as the above. But, instead, it produces a vector of identical numbers each time is it called.

my_func(sample(1:10, size = 1))
 2 2 2 2 2
my_func(sample(1:10, size = 1))
 10 10 10 10 10

1. I am interested in understanding why this is so.

2. How can I get the same behavior when passing in the full function as an argument? That is, I want my_func(sample(1:10, size = 1)) to produce a 5 element vector with each element being the result of an independent call to sample(1:10, size = 1)

Here's your function: `my_func <- function(FUN){map_dbl(1:5, ~ FUN)}`.

What I understand is that you expect that this function will take any function, say `f` as an argument and return `c(f(1), f(2), f(3), f(4), f(5))`. So, if you use a function that doesn't really depend its argument, it'll be same as `5` repetitions of the same function.

Is that so?

If yes, then it's not doing anything as such. It doesn't check whether `FUN` is a function or not, and if it's not, it doesn't care. It actually takes a number as an argument, and returns that `5` times.

Here's an illustration:

``````> library(purrr)
>
> my_func <- function(FUN) map_dbl(1:5, ~ FUN)
>
> set.seed(seed = 35763)
> a <- sample(x = 1:10, size = 1)
> my_func(FUN = a)
 8 8 8 8 8
>
> set.seed(seed = 35763)
> my_func(FUN = sample(x = 1:10, size = 1))
 8 8 8 8 8
``````

I would have done simply this:

``````> set.seed(seed = 35763)
> replicate(n = 5, expr = sample(x = 1:10, size = 1))
  8  6  1 10  3
``````

If you're a `tidy` person, consider `purrr::rerun`. Or, just use `map_dbl` this way:

``````> set.seed(seed = 35763)
> purrr::map_dbl(.x = 1:5, .f = ~ sample(x = 1:10, size = 1))
  8  6  1 10  3
``````

Hope this helps.

1 Like

So, if you use a function that doesn't really depend its argument, it'll be same as `5` repetitions of the same function. Is that so?

Yes. But I want these repetitions to be "fresh", that is, not as if the same seed were set before each one. So, sample() should not produce the same answer 5 times in a row.

I would have done simply this:

But, my issue is that this code needs to run within another function. So, I could use map_dbl, as in your example, but then I get:

my_func <- function(FUN){map_dbl(.x = 1:5, .f = ~ FUN)}
my_func(FUN = sample(x = 1:10, size = 1))
 9 9 9 9 9

Which is not what I want, obviously.

Here is a simpler example of my question. This works as expected. I am calling runif(1) five times and, each time, it produces a different number.

map_dbl(.x = 1:5, .f = ~ runif(1))
 0.4758260 0.1840778 0.4199492 0.5779564 0.8983577

But when I pass in runif(1) as an argument, I get five copies of the same answer:

my_func <- function(FUN){map_dbl(.x = 1:5, .f = ~ FUN)}
my_func(runif(1))
 0.7555603 0.7555603 0.7555603 0.7555603 0.7555603

For reasons that are unclear to me, this solves my problem:

my_func <- function(FUN){map_dbl(.x = 1:5, .f = FUN)}
my_func(~ runif(1))
 0.92841984 0.66576421 0.45799861 0.88515905 0.03660372

Thanks again to Yarnabrina for the help.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.