0

I have a function whose output is a list. For a package I'm writing, users will create a number of lists using this function. The order in which these lists are created really matters. Here's the issue: I need a list of these lists, in the correct order (the order in which the objects were created), and I don't want to have to make users declare the list objects again. What I'd like to do is something like the following:

# Approach 1
list_of_lists <- list(

m1 <- function_that_makes_list(arg1, arg2)
m2 <- function_that_makes_list( arg3, arg4)
m3 <- function_that_makes_list( arg5, arg6)

)

So this would be equivalent to the following (which obviously works, but involves having to re-type m1, m2, m3, which I don't want):

m1 <- function_that_makes_list(arg1, arg2)
m2 <- function_that_makes_list(arg3, arg4)
m3 <- function_that_makes_list(arg5, arg6)
list_of_lists <- list(m1, m2, m3)

How can I make Approach 1 work? Any suggestions? Thanks!

2
  • I believe this could be solved with a form of lapply(1:n, function_that_makes_list). Commented Jul 28, 2018 at 9:45
  • lapply(1:n, ...) won't work as the function takes two arguments and neither of them are 1:n. Commented Jul 28, 2018 at 10:29

2 Answers 2

1

Your option 1 needs commas (see below).

Here's a function that returns a list

fx <- function() {return(list())}

Now let's try your option 1 with commas [it works].

list(m1 <- fx(), m2 <- fx(), m3 <- fx()) # your option 1

# [[1]]
# list()

# [[2]]
# list()

# [[3]]
# list()

Now let's create a named list [it works too].

list(m1=fx(), m2=fx(), m3=fx())

# $m1
# list()

# $m2
# list()

# $m3
# list()

This has the advantage that the names can accessed programmatically.

nestedList <- list(m1=fx(), m2=fx(), m3=fx())
names(nestedList)

# [1] "m1" "m2" "m3"

Your second option

 m1 <- m2 <- m3 <- fx() # just for simplicity
 list(m1, m2, m3)

# [output identical to your option 1]
Sign up to request clarification or add additional context in comments.

Comments

1

I might be misunderstanding your question, but here two approaches that assume that your end users create these function calls dynamically, i.e. you don't know in advance when and how many of the lists are created:

# toyfunction:
funlist <- function(){
  return(list(rnorm(1)) )
}
funlist()
# [[1]]
# [1] 0.8481468

Assigning into the list directly

This avoids retyping of names:

globallist <- list()
globallist["m1"] <- funlist()
globallist["m2"] <- funlist()
globallist["m3"] <- funlist()
globallist
# $`m1`
# [1] -0.5160049
# $m2
# [1] 0.793974
# $m3
# [1] 0.06070436

Let the function write into the global variable:

This avoids retyping and keeping track of the correct order:

globallist <- list()
wrap <- function(){
  n <- length(globallist)
  globallist[n+1] <<- funlist() # change "n+1" if you need different names for the list elements
}
globallist
# list()
wrap()
globallist
# [[1]]
# [1] -1.626766

wrap()
globallist
# [[1]]
# [1] -1.626766

# [[2]]
# [1] -0.2278807

Note that with each successive call to wrap, the result of funlist is appended (as the last element of the global list) as a side effect of the function call. Modifying a global object from within a function is typically only recommended when you know what you are doing.

Comments

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.