<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/five-tips-to-improve-your-r-code/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code"> blogR</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><a rel="nofollow" href="https://twitter.com/drsimonj" target="_blank">@drsimonj</a> here with five simple tricks I find myself sharing all the time with fellow R users to improve their code!</p>
<p><strong><em>This post was originally published on <a rel="nofollow" href="https://www.datacamp.com/community/tutorials/five-tips-r-code-improve?tap_a=5644-dce66f&tap_s=10907-287229" target="_blank">DataCamp’s community</a> as one of their top 10 articles in 2017</em></strong></p>
<h2><a rel="nofollow" href="http://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code#1-more-fun-to-sequence-from-1_2" target="_blank"> </a>1. More fun to sequence from 1</h2>
<p>Next time you use the colon operator to create a sequence from 1 like <code>1:n</code>, try <code>seq()</code>.</p>
<pre><code># Sequence a vector
x &lt;- runif(10)
seq(x)
#>  [1]  1  2  3  4  5  6  7  8  9 10

# Sequence an integer
seq(nrow(mtcars))
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#> [24] 24 25 26 27 28 29 30 31 32
</code></pre>
<p>The colon operator can produce unexpected results that can create all sorts of problems without you noticing! Take a look at what happens when you want to sequence the length of an empty vector:</p>
<pre><code># Empty vector
x &lt;- c()

1:length(x)
#> [1] 1 0

seq(x)
#> integer(0)
</code></pre>
<p>You’ll also notice that this saves you from using functions like <code>length()</code>. When applied to an object of a certain length, <code>seq()</code> will automatically create a sequence from 1 to the length of the object.</p>
<h2><a rel="nofollow" href="http://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code#2-code-classprettyprintvectorcode-what-you-co_2" target="_blank"> </a>2. <code>vector()</code> what you <code>c()</code></h2>
<p>Next time you create an empty vector with <code>c()</code>, try to replace it with <code>vector(&quot;type&quot;, length)</code>.</p>
<pre><code># A numeric vector with 5 elements
vector(&quot;numeric&quot;, 5)
#> [1] 0 0 0 0 0

# A character vector with 3 elements
vector(&quot;character&quot;, 3)
#> [1] &quot;&quot; &quot;&quot; &quot;&quot;
</code></pre>
<p>Doing this improves memory usage and increases speed! You often know upfront what type of values will go into a vector, and how long the vector will be. Using <code>c()</code> means R has to <strong>slowly</strong> work both of these things out. So help give it a boost with <code>vector()</code>!</p>
<p>A good example of this value is in a for loop. People often write loops by declaring an empty vector and growing it with <code>c()</code> like this:</p>
<pre><code>x &lt;- c()
for (i in seq(5)) {
  x &lt;- c(x, i)
}
</code></pre>
<pre><code>#> x at step 1 : 1
#> x at step 2 : 1, 2
#> x at step 3 : 1, 2, 3
#> x at step 4 : 1, 2, 3, 4
#> x at step 5 : 1, 2, 3, 4, 5
</code></pre>
<p>Instead, pre-define the type and length with <code>vector()</code>, and reference positions by index, like this:</p>
<pre><code>n &lt;- 5
x &lt;- vector(&quot;integer&quot;, n)
for (i in seq(n)) {
  x[i] &lt;- i
}
</code></pre>
<pre><code>#> x at step 1 : 1, 0, 0, 0, 0
#> x at step 2 : 1, 2, 0, 0, 0
#> x at step 3 : 1, 2, 3, 0, 0
#> x at step 4 : 1, 2, 3, 4, 0
#> x at step 5 : 1, 2, 3, 4, 5
</code></pre>
<p>Here’s a quick speed comparison:</p>
<pre><code>n &lt;- 1e5

x_empty &lt;- c()
system.time(for(i in seq(n)) x_empty &lt;- c(x_empty, i))
#>    user  system elapsed 
#>  16.147   2.402  20.158

x_zeros &lt;- vector(&quot;integer&quot;, n)
system.time(for(i in seq(n)) x_zeros[i] &lt;- i)
#>    user  system elapsed 
#>   0.008   0.000   0.009
</code></pre>
<p>That should be convincing enough!</p>
<h2><a rel="nofollow" href="http://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code#3-ditch-the-code-classprettyprintwhichcode_2" target="_blank"> </a>3. Ditch the <code>which()</code></h2>
<p>Next time you use <code>which()</code>, try to ditch it! People often use <code>which()</code> to get indices from some boolean condition, and then select values at those indices. This is not necessary.</p>
<p>Getting vector elements greater than 5:</p>
<pre><code>x &lt;- 3:7

# Using which (not necessary)
x[which(x > 5)]
#> [1] 6 7

# No which
x[x > 5]
#> [1] 6 7
</code></pre>
<p>Or counting number of values greater than 5:</p>
<pre><code># Using which
length(which(x > 5))
#> [1] 2

# Without which
sum(x > 5)
#> [1] 2
</code></pre>
<p>Why should you ditch <code>which()</code>? It’s often unnecessary and boolean vectors are all you need.</p>
<p>For example, R lets you select elements flagged as <code>TRUE</code> in a boolean vector:</p>
<pre><code>condition &lt;- x > 5
condition
#> [1] FALSE FALSE FALSE  TRUE  TRUE
x[condition]
#> [1] 6 7
</code></pre>
<p>Also, when combined with <code>sum()</code> or <code>mean()</code>, boolean vectors can be used to get the count or proportion of values meeting a condition:</p>
<pre><code>sum(condition)
#> [1] 2
mean(condition)
#> [1] 0.4
</code></pre>
<p><code>which()</code> tells you the indices of TRUE values:</p>
<pre><code>which(condition)
#> [1] 4 5
</code></pre>
<p>And while the results are not wrong, it’s just not necessary. For example, I often see people combining <code>which()</code> and <code>length()</code> to test whether any or all values are TRUE. Instead, you just need <code>any()</code> or <code>all()</code>:</p>
<pre><code>x &lt;- c(1, 2, 12)

# Using `which()` and `length()` to test if any values are greater than 10
if (length(which(x > 10)) > 0)
  print(&quot;At least one value is greater than 10&quot;)
#> [1] &quot;At least one value is greater than 10&quot;

# Wrapping a boolean vector with `any()`
if (any(x > 10))
  print(&quot;At least one value is greater than 10&quot;)
#> [1] &quot;At least one value is greater than 10&quot;

# Using `which()` and `length()` to test if all values are positive
if (length(which(x > 0)) == length(x))
  print(&quot;All values are positive&quot;)
#> [1] &quot;All values are positive&quot;

# Wrapping a boolean vector with `all()`
if (all(x > 0))
  print(&quot;All values are positive&quot;)
#> [1] &quot;All values are positive&quot;
</code></pre>
<p>Oh, and it saves you a little time…</p>
<pre><code>x &lt;- runif(1e8)

system.time(x[which(x > .5)])
#>    user  system elapsed 
#>   1.245   0.486   1.856

system.time(x[x > .5])
#>    user  system elapsed 
#>   1.085   0.395   1.541
</code></pre>
<h2><a rel="nofollow" href="http://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code#4-code-classprettyprintfactorcode-that-factor_2" target="_blank"> </a>4. <code>factor</code> that factor!</h2>
<p>Ever removed values from a factor and found you’re stuck with old levels that don’t exist anymore? I see all sorts of creative ways to deal with this. The simplest solution is often just to wrap it in <code>factor()</code> again.</p>
<p>This example creates a factor with four levels (<code>&quot;a&quot;</code>, <code>&quot;b&quot;</code>, <code>&quot;c&quot;</code> and <code>&quot;d&quot;</code>):</p>
<pre><code># A factor with four levels
x &lt;- factor(c(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;))
x
#> [1] a b c d
#> Levels: a b c d

plot(x)
</code></pre>
<p><a rel="nofollow" href="https://i0.wp.com/svbtleusercontent.com/jzrk7zvnpyaquq.png?ssl=1" target="_blank"><img alt="factor-1-1.png" src="https://i1.wp.com/svbtleusercontent.com/jzrk7zvnpyaquq_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>If you drop all cases of one level (<code>&quot;d&quot;</code>), the level is still recorded in the factor:</p>
<pre><code># Drop all values for one level
x &lt;- x[x != &quot;d&quot;]

# But we still have this level!
x
#> [1] a b c
#> Levels: a b c d

plot(x)
</code></pre>
<p><a rel="nofollow" href="https://i2.wp.com/svbtleusercontent.com/1e9acxfzvls3mq.png?ssl=1" target="_blank"><img alt="factor-2-1.png" src="https://i0.wp.com/svbtleusercontent.com/1e9acxfzvls3mq_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>A super simple method for removing it is to use <code>factor()</code> again:</p>
<pre><code>x &lt;- factor(x)
x
#> [1] a b c
#> Levels: a b c

plot(x)
</code></pre>
<p><a rel="nofollow" href="https://i1.wp.com/svbtleusercontent.com/yk6esbvbbbxm0q.png?ssl=1" target="_blank"><img alt="factor-3-1.png" src="https://i1.wp.com/svbtleusercontent.com/yk6esbvbbbxm0q_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>This is typically a good solution to a problem that gets a lot of people mad. So save yourself a headache and <code>factor</code> that factor!</p>
<blockquote>
<p>Aside, thanks to Amy Szczepanski who contacted me after the original publication of this article and mentioned <code>droplevels()</code>. Check it out if this is a problem for you!</p>
</blockquote>
<h2><a rel="nofollow" href="http://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code#5-first-you-get-the-code-classprettyprintcode_2" target="_blank"> </a>5. First you get the <code>$</code>, then you get the power</h2>
<p>Next time you want to extract values from a <code>data.frame</code> column where the rows meet a condition, specify the column with <code>$</code> before the rows with <code>[</code>.</p>
<h4><a rel="nofollow" href="http://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code#examples_4" target="_blank"> </a>Examples</h4>
<p>Say you want the horsepower (<code>hp</code>) for cars with 4 cylinders (<code>cyl</code>), using the <code>mtcars</code> data set. You can write either of these:</p>
<pre><code># rows first, column second - not ideal
mtcars[mtcars$cyl == 4, ]$hp
#>  [1]  93  62  95  66  52  65  97  66  91 113 109

# column first, rows second - much better
mtcars$hp[mtcars$cyl == 4]
#>  [1]  93  62  95  66  52  65  97  66  91 113 109
</code></pre>
<p>The tip here is to use the second approach.</p>
<p>But why is that?</p>
<p>First reason: do away with that pesky comma! When you specify rows before the column, you need to remember the comma: <code>mtcars[mtcars$cyl == 4</code><strong>,</strong><code>]$hp</code>. When you specify column first, this means that you’re now referring to a vector, and don’t need the comma!</p>
<p>Second reason: speed! Let’s test it out on a larger data frame:</p>
<pre><code># Simulate a data frame...
n &lt;- 1e7
d &lt;- data.frame(
  a = seq(n),
  b = runif(n)
)

# rows first, column second - not ideal
system.time(d[d$b > .5, ]$a)
#>    user  system elapsed 
#>   0.559   0.152   0.758

# column first, rows second - much better
system.time(d$a[d$b > .5])
#>    user  system elapsed 
#>   0.093   0.013   0.107
</code></pre>
<p>Worth it, right?</p>
<p>Still, if you want to hone your skills as an R data frame ninja, I suggest learning <code>dplyr</code>. You can get a good overview on the <a rel="nofollow" href="http://dplyr.tidyverse.org/" target="_blank"><code>dplyr</code> website</a> or really learn the ropes with online courses like DataCamp’s <a rel="nofollow" href="https://www.datacamp.com/courses/dplyr-data-manipulation-r-tutorial?tap_a=5644-dce66f&tap_s=10907-287229" target="_blank">Data Manipulation in R with <code>dplyr</code></a>.</p>
<h2><a rel="nofollow" href="http://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code#sign-off_2" target="_blank"> </a>Sign off</h2>
<p>Thanks for reading and I hope this was useful for you.</p>
<p>For updates of recent blog posts, follow <a rel="nofollow" href="https://twitter.com/drsimonj" target="_blank">@drsimonj</a> on Twitter, or email me at <a rel="nofollow" href="mailto:drsimonjackson@gmail.com" target="_blank">drsimonjackson@gmail.com</a> to get in touch.</p>
<p>If you’d like the code that produced this blog, check out the <a rel="nofollow" href="https://github.com/drsimonj/blogR" target="_blank">blogR GitHub repository</a>.</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://drsimonj.svbtle.com/five-simple-tricks-to-improve-your-r-code"> blogR</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/Fim2oVk5Qxc" height="1"></a></div>