1

I wish to expand lists to a given length using rep(), as in:

n = 5
l = 1:3
rep(l, length=n)

However, my lists come in two flavours, nested or not nested:

l1 <- list(a=1, b=2)
l2 <- list(list(a=1, b=2), list(x=1, y=2))

rep(l2, length=n) # as desired

rep(l1, length=n) # result is a single list, where I really want 
rep(list(l1), length=n) # instead

To deal with this problem I probably need to identify the problematic l1 as being "first-level" and wrap it into list() before applying rep(). What is the best way to do this?

baptiste
  • 75,767
  • 19
  • 198
  • 294

2 Answers2

2

Here is an idea:

replist <- function(ls, n){
  ls <- 
  if(sum(sapply(ls, class) != "list") == 0){  # T: all list elements are lists
    ls
  } else {
    list(ls)
  }  
  rep(ls, length = n)
}

identical(replist(l2, 3), rep(l2, length=3))        # TRUE
identical(replist(l1, 3), rep(list(l1), length=3))  # TRUE
Ryogi
  • 5,497
  • 5
  • 26
  • 46
  • +1 yes, that does the job, thanks. I wonder if there could be a shorter trick. – baptiste Feb 26 '12 at 00:33
  • In terms of LOC, using `ifelse` doesn't help (your problem is what originated my question [here](http://stackoverflow.com/q/9449184/986817)). – Ryogi Feb 26 '12 at 00:56
2

Or, you could use is.list():

newlist = function(x,n){ 
        if(is.list(x[[1]])) { rep(x, length=n) 
        } else { rep(list(x), length=n) }}

identical(newlist(l2,5), rep(l2, length=5)) 
identical(newlist(l1,5), rep(list(l1), length=5))
baha-kev
  • 3,029
  • 9
  • 33
  • 31
  • true, that should work. Unfortunately, it turns out that my list elements are actually of class "gpar" (grid's options), and their class doesn't inherit from lists for some reason. – baptiste Feb 26 '12 at 01:11