0

I want to turn object1 into a string called "object1"

object1 = c(1 ,2 ,3)
object2 = c(3 ,2 ,1)

my_list = list(object1,object2)

for(var in my_list){
  cat(toString(var),"\n")
}

this returns

1, 2, 3 
3, 2, 1

I want it to return

"object1"
"object2"
3
  • Are you trying to access variable names in your environment or jus list names - what is your goal? Commented May 17, 2020 at 12:08
  • @GWD my object1 is a time series object and i am attempting to plot several graphs and want to retrieve the name of the object to use for the title Commented May 17, 2020 at 12:16
  • Then I guess looping through a named list and using that list name "variable" in your plot or ?deparsing - I see that @MichaelChirico just elaborated in detail :-) Commented May 17, 2020 at 12:25

4 Answers 4

4

There is no information of "object1" and "object2" in my_list.

You need to name them like this :

my_list = list(object1 = object1,object2 = object2)

Or using tibble's lst

my_list <- tibble::lst(object1, object2)

so that you can access names using

names(my_list)
#[1] "object1" "object2"
Sign up to request clarification or add additional context in comments.

Comments

3

If you're trying to imitate the default plotting behavior:

my_x_var = 1:10
my_y_var = 10:1

plot(my_x_var, my_y_var)

sample plot

The way that's done is with deparse1(substitute(.)):

deparse1(substitute(my_x_var))
# [1] "my_x_var"

NB: deparse1 is new to R 4.0.0. On older versions, you'll in general need to do paste(deparse(substitute(my_x_var)), collapse = ' ') -- but this only matters if the argument in substitute(.) gets huge (lots of characters). In simple use cases, just deparse(.) would suffice.

1 Comment

Best thing in R 4.0.0 (after reference counting)! I was too lazy to enclose deparse with paste every single time, but it always gave me sleepless nights.
1

Given the application stated by the original poster (OP) for the functionality they are after, it's clear that the answer by MichaelChirico is the right solution.

For potential other applications where we need to know the names of the arguments passed during the creation of an object (e.g. "object1" and "object2" in the call to list(object1, object2) in the OP's example), below I give a solution that allows retrieving those names at a later stage where the created object is used. The solution is based on storing the argument names as an attribute of the created object (in this case the list).

To this end I define a function called create_list() that receives any number of arguments (defining the elements of the list to create) whose names are stored as part of the attribute "args" of the created list (using the structure() function).

create_list = function(...) {
  # Extract the function arguments
  # - as.list() separates the different parts of the call into function name and arguments
  # - [-1] removes the function name from the list
  params = as.list(match.call())[-1]

  # Create the list and store the argument names in the attribute "args"
  return( structure(list(...),  args=sapply(params, function(x) deparse(x))) )
}

Create the list using the function just defined and check the output.

object1 = c(1 ,2 ,3)
object2 = c(3 ,2 ,1)
my_list = create_list(object1, object2)

whose output is:

> my_list
[[1]]
[1] 1 2 3

[[2]]
[1] 3 2 1

attr(,"args")
[1] "object1" "object2"

As we can see, the names "object1" and "object2" are part of the "args" attribute of the created list. This attribute can be retrieved using the attr() function, as follows:

> attr(my_list, "args")
[1] "object1" "object2"

Therefore, the functionality requested by the OP can be now implemented as follows (complete code):

object1 = c(1 ,2 ,3)
object2 = c(3 ,2 ,1)
my_list = create_list(object1, object2)

i = 0
for(var in my_list) {
  i = i + 1
  cat( attr(my_list, "args")[i], "\n")
}

whose output is:

object1 
object2 

BONUS: EXTENSION TO ANY FUNCTION CALL

The create_list() function defined above can be extended to have the capability of calling any function, not only list(). This is done by extending the function to accept a new argument containing the function to call (e.g. list(), data.frame(), etc.). I call the extended function create_object() and define it as follows:

# Function that runs a function call and returns an object containing the output
# of the call, which includes in attribute "args" the name of the arguments passed to the function.
# The function to call should be the first argument, followed by any potential argument
# to pass to that function.
create_object = function(...) {
  # Extract the function arguments
  # - as.list() separates the different parts of the call into function name and arguments
  # - [-1] removes the function name from the list
  params = as.list(match.call())[-1]
  fun_to_call = params[[1]]
  args = params[-1]
  return( structure(do.call(deparse(fun_to_call), args),
                    args=sapply(args, function(x) deparse(x))) )
}

We now call this function to create a list and a data frame, respectively:

my_list = create_object(list, object1, object2)
my_df = create_object(data.frame, object1, object2)

whose values are:

> my_list2
[[1]]
[1] 1 2 3

[[2]]
[1] 3 2 1

attr(,"args")
[1] "object1" "object2"

> my_df
  object1 object2
1       1       3
2       2       2
3       3       1

The attributes of the data frame are not shown by default when printing, but they can be retrieved with attributes():

> attributes(my_df)
$names
[1] "object1" "object2"

$class
[1] "data.frame"

$row.names
[1] 1 2 3

$args
[1] "object1" "object2"

Clearly, the "args" attribute is expected to not already exist in created object, otherwise its value is overwritten.

Finally, note that we can also pass a function that does not create an object, such as print() or ls().

> create_object(print, object1, object2)
[1] 1 2 3
[1] 1 2 3
attr(,"args")
[1] "object1" "object2"

Comments

-1

We can use lst from dplyr

dplyr::lst(object1, object2)

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.