Reputation: 852
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"
Upvotes: 0
Views: 910
Reputation: 1414
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"
Upvotes: 1
Reputation: 34703
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)
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.
Upvotes: 3
Reputation: 388982
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"
Upvotes: 4