2

TL;DR: what I need is a vectorised version of list().

I'm trying to create a list of objects. I don't know how many objects there'll be or what they'll be called, and there may be a large number of them. So I can't just make a list by hand.

However, I know that all the objects will exist in my environment when it comes time to make the list, and I know I will have a character vector containing the names of all the objects.

(These are the outputs of a horrible three-layer for loop that I'm trying to avoid making any bigger. I could just create an empty list and then assign objects to it as the loop creates them, but I'd prefer not to.)

I've searched Google and Stack Overflow, but I can't find a good solution. It seems to me that what I need is a vectorised version of list(): something that will take a vector of object names, find all those objects and shove them in a list.

list(obj1, obj2, obj3) # Not this. I don't want to name each element individually.

objectsVector <- c("obj1", "obj2", "obj3")
list_vectorised(elements = objectsVector) # I want this instead. 

namesVector <- c("anObject", "anotherObject", "yetAnotherObject")
list_vectorised(elements = objectsVector, names  = namesVector) # Or better still, this. 
d.b
  • 29,772
  • 5
  • 24
  • 63
Max Green
  • 33
  • 2
  • 4
  • Thanks! Using mget is much better than lapply-ing get. – Max Green Aug 30 '17 at 15:14
  • See my answer in the linked post. It uses `mget` together with the pattern argument in `ls` to pull objects whose names match certain patterns. The linked post asks about data.frames, but all answers will work for any type of R object. – lmo Aug 30 '17 at 15:17
  • Thanks, lmo. The pattern won't help much, as my objects aren't actually called obj1 etc, but instead have dynamic names that may be similar to the names of objects I don't want to get. But mget is good. – Max Green Aug 30 '17 at 15:33
  • 1
    I believe an existing post answers your question fairly well: https://stackoverflow.com/questions/22235809/append-value-to-empty-vector-in-r#22235924 I typically find the rep(NA,x) strategy is good for my needs. There are also some publicized ways to convert an existing list to a vector (see: https://stackoverflow.com/questions/4390862/convert-a-vector-to-a-list) It looks like you will need to use an apply function, or write your own probably less efficient function (using rep() and a for loop, I think would be the naive approach) – 3pitt Aug 30 '17 at 15:08

2 Answers2

9

You can use mget to get objects from the environment and put them in a list.

mget(VECTOR_OF_NAMES_OF_OBJECTS)

You can also combine mget with ls() so that you don't have to type the object names your self.

obj1 = 1:2
obj2 = 3:7
obj13 = 8:11

mget(ls(pattern = "obj\\d+"))
#$obj1
#[1] 1 2

#$obj13
#[1]  8  9 10 11

#$obj2
#[1] 3 4 5 6 7
d.b
  • 29,772
  • 5
  • 24
  • 63
  • That wouldn't solve my problem, I'm afraid. the objects won't actually be called obj1, ob2 and so on, and will have dynamic names. But I'm glad to know that mget exists and that ls() can take a regex. mget is better than my solution. Thanks! – Max Green Aug 30 '17 at 15:10
1

I found a solution!

foo <- lapply(objectsVector, get) # This creates a list of the objects.
foo <- setnames(foo, namesVector) # This names the elements of the list. 

I'm leaving the question up because I spent so long searching for an answer and want to spare other people the trouble. I'm not sure whether that's the approved thing to do.

Max Green
  • 33
  • 2
  • 4