5

I try to get an object's name from the list containing this object. I searched through similar questions and find some suggestions about using the deparse(substitute(object)) formula:

> my.list <- list(model.product, model.i, model.add)
> lapply(my.list, function(model) deparse(substitute(model)))

and the result is:

[[1]]
[1] "X[[1L]]"

[[2]]
[1] "X[[2L]]"

[[3]]
[1] "X[[3L]]"

whereas I want to obtain:

[1] "model.product", "model.i", "model.add"

Thank you in advance for being of some help!

Marta Karas
  • 4,967
  • 10
  • 47
  • 77

4 Answers4

10

You can write your own list() function so it behaves like data.frame(), i.e., uses the un-evaluated arg names as entry names:

List <- function(...) {
  names <- as.list(substitute(list(...)))[-1L]
  setNames(list(...), names)
}

my.list <- List(model.product, model.i, model.add)

Then you can just access the names via:

names(my.list)
flodel
  • 87,577
  • 21
  • 185
  • 223
  • 3
    also see http://stackoverflow.com/questions/16951080/can-list-objects-be-created-in-r-that-name-themselves-based-on-input-object-name/16951524#16951524 – Ben Bolker Sep 18 '13 at 01:35
3
names(my.list) #..............

Oh wait, you didn't actually create names did you? There is actually no "memory" for the list function. It returns a list with the values of its arguments but not from whence they came, unless you add names to the pairlist given as the argument.

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • 2
    Any idea as to why `my.df <- data.frame(model.product, model.i, model.add)` does populate the names, while `list()` does not? I find it puzzling... – flodel Sep 18 '13 at 01:22
  • 1
    deep-rooted inconsistency, I think. R is organic. – Ben Bolker Sep 18 '13 at 01:34
  • @flodel - `as.list(data.frame(model.product, model.i, model.add))` for a clunky hack method? – thelatemail Sep 18 '13 at 01:57
  • 1
    @thelatemail: it won't work as expected if the items have different lengths, probably why `list` was used in the first place. – flodel Sep 18 '13 at 02:04
1

You won't be able to extract the information that way once you've created my.list.

The underlying way R works is that expressions are not evaluated until they're needed; using deparse(substitute()) will only work before the expression has been evaluated. So:

deparse(substitute(list(model.product, model.i, model.add)))

should work, while yours doesn't.

Scott Ritchie
  • 10,293
  • 3
  • 28
  • 64
1

To save stuffing around, you could employ mget to collect your free-floating variables into a list with the names included:

one <- two <- three <- 1
result <- mget(c("one","two","three"))
result
#$one
#[1] 1
# 
#$two
#[1] 1
# 
#$three
#[1] 1

Then you can follow @DWin's suggestion:

names(result)
#[1] "one"   "two"   "three"
thelatemail
  • 91,185
  • 12
  • 128
  • 188