Create a column that contains the name of the data frame

Hi, I would like to add column to an existing data frame that contains the name of that data frame. The value in the new column would be dynamic, i.e. would depend on the name of the data frame.

For example, say I create the following data frame called "my_df":

my_df <- data.frame(letters = c("a","b","c"), numbers = c(1,2,3))

Then I would like to add a column called "dataframe_name" containing the value "my_df". I could do it manually as follows:

my_df <- my_df %>% mutate(dataframe_name = "my_df")

But is there a way to do this "dynamically" so that the name in the new column will be whatever the name of the data frame is?

Thank you for your time.

Hi Steve!

Here is a solution that does the trick:

addName<-function(x){
  a<-as.character(substitute(x))
  x$df_name<-a
  return(x)
}

my_df <- data.frame(letters = c("a","b","c"), numbers = c(1,2,3)) 
my_df
#   letters numbers
# 1       a       1
# 2       b       2
# 3       c       3

addName(my_df)
#   letters numbers df_name
# 1       a       1   my_df
# 2       b       2   my_df
# 3       c       3   my_df

2 Likes

@jms great, thank you very much!

This is a neat trick! What is substitute(x) doing? I tried reading the help documentation on it, but could not make sense of it! Hoping for a plain English understanding of this trick.

Hi @Piranha,
The trick takes advantages of the fact that substitute() returns the input without evaluating it when the env argument is .GlobalEnv (usually the default). So substitute(x) returns x, independent of what kind of object x is. Using as.character() this output is then transformed into a character so that it can be added to the data frame.

x<-c(1,2,3)
substitute(x)
#> x
eval(substitute(x))
#> [1] 1 2 3
as.character(substitute(x))
#> [1] "x"

Created on 2020-10-22 by the reprex package (v0.3.0)

Other than that, substitute() can be used to evaluate a part of an object (like an item in a list) in the context of the object:

my_list<-list(a=c(1,2,3),b=c(3,2,1))
a
#> Error in eval(expr, envir, enclos): object 'a' not found
substitute(a,my_list)
#> [1] 1 2 3

Created on 2020-10-22 by the reprex package (v0.3.0)

However, I have no idea in which context this might be usefull, and I don't know what substitue() is used for except for some shady tricks to get the name of an object :grinning:

Thanks! Now it makes more sense :slight_smile:

1 Like