<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/r-tip-put-your-values-in-columns/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://www.win-vector.com/blog/2018/08/r-tip-put-your-values-in-columns/"> R – Win-Vector Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Today’s <a rel="nofollow" href="https://www.r-project.org/" target="_blank"><code>R</code></a> <a rel="nofollow" href="http://www.win-vector.com/blog/tag/r-tips/" target="_blank">tip</a> is: put your values in columns.</p>
<p><span></span></p>
<p>
<p>Some <code>R</code> users use different seemingly clever tricks to bring data to an analysis.</p>
<p>Here is an (artificial) example.</p>
<pre>
chamber_sizes &lt;- mtcars$disp/mtcars$cyl
form &lt;- hp ~ chamber_sizes
model &lt;- lm(form, data = mtcars)
print(model)
# Call:
# lm(formula = form, data = mtcars)
#
# Coefficients:
#   (Intercept)  chamber_sizes  
#         2.937          4.104  
</pre>
<p>Our advice is: do not do that. Place all of your values in columns. This allows you to write simple code that works over explicit data. The style we recommend looks like the following.</p>
<pre>
mtcars$chamber_sizes &lt;- mtcars$disp/mtcars$cyl
form &lt;- hp ~ chamber_sizes
model &lt;- lm(form, data = mtcars)
print(model)
# Call:
# lm(formula = form, data = mtcars)
#
# Coefficients:
#   (Intercept)  chamber_sizes  
#         2.937          4.104  
</pre>
<p>The only difference is we took the time to place the derived vector into the data frame we are working with (assigned to <code>mtcars$chamber_sizes</code> instead of the global environment in the first line). This is a very organized way to work, and as you see it does not take much effort.</p>
<p>Or use only existing values, as we show below.</p>
<pre>
form &lt;- hp ~ I(disp/cyl)
model &lt;- lm(form, data = mtcars)
print(model)
# Call:
# lm(formula = form, data = mtcars)
#
# Coefficients:
#   (Intercept)  chamber_sizes  
#         2.937          4.104  
</pre>
<p>This is something we teach: with some care you can reliably treat variables as strings, and this is in no way inferior to complex systems such as <code>stats::formula</code> or <code>rlang::quosure</code>. The fact that these objects cary around an environment in addition the names is in fact a barrier to reliable code, not an unmitigated advantage.</p>
<p>I am not alone in this opinion.</p>
<blockquote>
<p>
If the formula was typed in by the user interactively, then the call came from the global environment, meaning that variables not found in the data frame, or all variables if the <code>data</code> argument was missing, will be looked up in the same way they would in ordinary evaluation. But if the formula object was precomputed somewhere else, then its environment is the environment of the function call that created it. That means that arguments to that call and local assignments in that call will define variables for use in the model parent (that is, enclosing) environment of the call, which may be a package namespace. These rules are standard for <code>R</code>, at least once one know that an environment attribute has been assigned to the formula. They are similar to the use of closures described in Section 5.4, page 126.</p>
<p>
Where clear and trustworthy software is a priority, I would personally avoid such tricks. Ideally, all the variables in the model frame should come from an explicit, verifiable data source, typically a data frame object that is archived for future inspection (or equivalently, some other equally well-defined source of data, either inside or outside <code>R</code>, that is used explicitly to construct the data for the model).
<p>
<center><small><em>Software for Data Analysis</em> (Springer 2008), John M. Chambers, Chapter 6, section 9, page 221.</small></center>

</blockquote>
<p>Chambers’ critique applies equally to <code>stats::formula</code> or <code>rlang::quosure</code>, and roughly he is calling over-use an <a rel="nofollow" href="https://en.wikipedia.org/wiki/Anti-pattern" target="_blank">anti-pattern</a>.</p>
<p>This is why we say from the user point of view variables can be treated as mere names or strings. With some care you can ensure all your values are coming from a single <code>data.frame</code>. And if that is the case, variables are column names.</p>
<p>Going to extra effort to carry around <a rel="nofollow" href="https://en.wikipedia.org/wiki/Free_variables_and_bound_variables" target="_blank">bound variables</a> (variable names, plus an environment resolving the name to a value) is silly and a <a rel="nofollow" href="http://www.win-vector.com/blog/2014/05/trimming-the-fat-from-glm-models-in-r/" target="_blank">big source of reference leaks</a>. Roughly: if you don’t know the value of a variable then pass it as a name or string (as that is all an unbound variable or symbol is), if you do know the value then use that value (the variable is serving little purpose at that point). Being able to replace variables with values is the hallmark of <a rel="nofollow" href="https://en.wikipedia.org/wiki/Referential_transparency" target="_blank">referential transparency</a>, which is the family of expressions that are well-behaved in the sense that replacing the expressions with their referred to values does not change observable program behavior. There is code that breaks when you replace variables with values, but that should be considered to be a limitation of such code (not a merit).</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://www.win-vector.com/blog/2018/08/r-tip-put-your-values-in-columns/"> R – Win-Vector Blog</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/uEUO6toAlkI" height="1"></a></div>