0

I'm looking for a way to map a function over a list, but to be able to give the function different inputs for each iteration.

a simple example would be the following:

example_func <- function(a, b, c) {
  z = a + b + c
  return(z)
}

ex_list <- list(5, 14, 32)

executing on the first element in the list would look like:

example_func(ex_list[[1]], 45, 43)

I know I could also:

lapply(ex_list, function(x) example_func(x, 45, 43)

but that example would use 45 and 43 for each of the iterations in lapply. How could I give it, for example, these three sets of arguments to iterate over the three elements in the list?

c(x, 45, 43)
c(x, 3, 33)
c(x, 23, 22)

Or another similar example would be write.csv(), which takes the object and then the name of the file to be written.

set.seed(123)
df <- data.frame(x = sample(1:10, 1000, replace = TRUE))
df_list <- split(df, df$x)
lapply(df_list, function(x) write.csv(x, arg1))...

how could I iterate through this list and give the specified names to feed it?

I've done something similar to this before, but it would be a for loop iterating through seq_along the list, and then also finding that index within a vector of names. Is there a better way to do this?

2 Answers 2

5

Just put the other values in two other lists, say, l2 and l3. Then use Map, that is what it's meant for.

ex_list <- list(5, 14, 32)
l2 <- list(45, 3, 23)
l3 <- list(43, 33, 22)

Map(example_func, ex_list, l2, l3)
#[[1]]
#[1] 93
#
#[[2]]
#[1] 50
#
#[[3]]
#[1] 77

This can be done for any number of function arguments, each set in its own list.

Sign up to request clarification or add additional context in comments.

Comments

4

Using the tidyverse, this is a job for purrr. With pmap function you can iterate through several lists.

example_func <- function(a, b, c) {
  z = a + b + c
  return(z)
}

ex_list <- list(5, 14, 32)
ex_args1 <- list(45, 3, 23)
ex_args2 <- list(43, 33, 22)

library(purrr)       

list(ex_list, ex_args1, ex_args2) %>% pmap(example_func)
#> [[1]]
#> [1] 93
#> 
#> [[2]]
#> [1] 50
#> 
#> [[3]]
#> [1] 77
example_func(ex_list[[1]], ex_args1[[1]], ex_args2[[1]])
#> [1] 93
example_func(ex_list[[2]], ex_args1[[2]], ex_args2[[2]])
#> [1] 50
example_func(ex_list[[3]], ex_args1[[3]], ex_args2[[3]])
#> [1] 77

purrr package helps you with functionnal programming and iteration. You should look at the documentation as it could help you with other task like iteration with write.csv using purrr::walk for example.

one example using a dataframe to provide the iterating list and matching by named arguments.

example_func <- function(a, b, c) {
  z = a + b + c
  return(z)
}

library(tidyverse)
tribble(
  ~a, ~b, ~c,
  5, 45, 43,
  13, 3, 33,
  32, 23, 22
) %>% pmap_dbl(example_func)
#> [1] 93 49 77

2 Comments

awesome thank you, I think this is exactly what I'm looking for. last quick Q. What if the first argument of the example_func is a dataframe, and I want to keep that dataframe object constant? So instead of example_func(ex_list[[1]], ex_args1[[1]].. etc, it would be example_func(df, ex_args[[1]], ex_args2[[1]]
you can provide some fixed argument to example_func inside pmap. if example_fun <- function(df, a, b, c) and you want to iterate through a b and c only, you can do pmap(example_func, df = mydf) to fix the df arg. Look to the documentation, it is very powerful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.