This is because substitute
behaves differently when you are dealing with a normal variable instead of a promise object. A promise object is a formal argument and has a special slot that contains the expression that generated it. In other words, a promise object is a variable in a function that is part of the argument list of that function. When you use substitute
on a promise object in a function, then it will retrieve the expression in the call to the function that was assigned to that formal argument. From ?substitute
:
Substitution takes place by examining each component of the parse tree as follows: If it is not a bound symbol in env, it is unchanged. If it is a promise object, i.e., a formal argument to a function or explicitly created using delayedAssign(), the expression slot of the promise replaces the symbol. If it is an ordinary variable, its value is substituted, unless env is .GlobalEnv in which case the symbol is left unchanged.
In your case, you actually overwrite the original promise variable with a new one with:
u <- data.table(u)
at which point u
becomes a normal variable that contains a data table. When you substitute
on u
after this point, substitute
just returns the data table, which deparse
processes back to the R language that would generate it, which is why it is slow.
This also explains why your second example works. You substitute
while the variable is still a promise (i.e. before you overwrite u
). This is also the answer to your second question. Either substitute before you overwrite your promise, or don't overwrite your promise.
For more details, see section 2.1.8 of the R Language Definition (promises) which I excerpt here:
Promise objects are part of R’s lazy evaluation mechanism. They contain three slots: a value, an expression, and an environment. When a function is called the arguments are matched and then each of the formal arguments is bound to a promise. The expression that was given for that formal argument and a pointer to the environment the function was called from are stored in the promise.