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 