<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/forcats-0-1-0-%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88/"></div></div><div><a data-url="https://www.r-bloggers.com/forcats-0-1-0-%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88/" data-counturl="https://www.r-bloggers.com/forcats-0-1-0-%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88/" data-count="horizontal" data-text="forcats 0.1.0 🐈🐈🐈🐈" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://blog.rstudio.org/2016/08/31/forcats-0-1-0/"> RStudio Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<div>
<p>I’m excited to announce forcats, a new package for categorical variables, or factors. Factors have a bad rap in R because they often turn up when you don’t want them. That’s because historically, factors were more convenient than character vectors, as discussed in <a target="_blank" href="http://simplystatistics.org/2015/07/24/stringsasfactors-an-unauthorized-biography/"><em>stringsAsFactors: An unauthorized biography</em></a> by Roger Peng, and <a target="_blank" href="http://notstatschat.tumblr.com/post/124987394001/stringsasfactors-sigh"><em>stringsAsFactors = &lt;sigh></em></a> by Thomas Lumley.</p>
</div>
<p>If you use packages from the tidyverse (like <a target="_blank" href="http://r4ds.had.co.nz/tibbles.html">tibble</a> and <a target="_blank" href="http://r4ds.had.co.nz/data-import.html">readr</a>) you don’t need to worry about getting factors when you don’t want them. But factors are a useful data structure in their own right, particularly for modelling and visualisation, because they allow you to control the order of the levels. Working with factors in base R can be a little frustrating because of a handful of missing tools. The goal of forcats is to fill in those missing pieces so you can access the power of factors with a minimum of pain.</p>
<p>Install forcats with:</p>
<pre><code><span>install.packages</span><span>(</span><span>&quot;forcats&quot;</span><span>)</span></code></pre>
<p>forcats provides two main types of tools to change either the values or the order of the levels. I’ll call out some of the most important functions below, using using the included <code>gss_cat</code> dataset which contains a selection of categorical variables from the <a target="_blank" href="http://gss.norc.org/">General Social Survey</a>.</p>
<pre><code><span>library</span><span>(</span><span>dplyr</span><span>)</span>
<span>library</span><span>(</span><span>ggplot2</span><span>)</span>
<span>library</span><span>(</span><span>forcats</span><span>)</span>

<span>gss_cat</span>
<span>#> # A tibble: 21,483 × 9</span>
<span>#> year marital age race rincome partyid</span>
<span>#> &lt;int> &lt;fctr> &lt;int> &lt;fctr> &lt;fctr> &lt;fctr></span>
<span>#> 1 2000 Never married 26 White $8000 to 9999 Ind,near rep</span>
<span>#> 2 2000 Divorced 48 White $8000 to 9999 Not str republican</span>
<span>#> 3 2000 Widowed 67 White Not applicable Independent</span>
<span>#> 4 2000 Never married 39 White Not applicable Ind,near rep</span>
<span>#> 5 2000 Divorced 25 White Not applicable Not str democrat</span>
<span>#> 6 2000 Married 25 White $20000 - 24999 Strong democrat</span>
<span>#> # ... with 2.148e+04 more rows, and 3 more variables: relig &lt;fctr>,</span>
<span>#> # denom &lt;fctr>, tvhours &lt;int></span></code></pre>
<div>
<h2>Change level values</h2>
<p>You can recode specified factor levels with <a target="_blank" href="https://hadley.github.io/forcats/fct_recode.html"><code>fct_recode()</code></a>:</p>
<pre><code><span>gss_cat</span> <span>%>%</span> <span>count</span><span>(</span><span>partyid</span><span>)</span>
<span>#> # A tibble: 10 × 2</span>
<span>#> partyid n</span>
<span>#> &lt;fctr> &lt;int></span>
<span>#> 1 No answer 154</span>
<span>#> 2 Don't know 1</span>
<span>#> 3 Other party 393</span>
<span>#> 4 Strong republican 2314</span>
<span>#> 5 Not str republican 3032</span>
<span>#> 6 Ind,near rep 1791</span>
<span>#> # ... with 4 more rows</span>

<span>gss_cat</span> <span>%>%</span>
  <span>mutate</span><span>(</span><span>partyid</span> <span>=</span> <span>fct_recode</span><span>(</span><span>partyid</span>,
    <span>&quot;Republican, strong&quot;</span>    <span>=</span> <span>&quot;Strong republican&quot;</span>,
    <span>&quot;Republican, weak&quot;</span>      <span>=</span> <span>&quot;Not str republican&quot;</span>,
    <span>&quot;Independent, near rep&quot;</span> <span>=</span> <span>&quot;Ind,near rep&quot;</span>,
    <span>&quot;Independent, near dem&quot;</span> <span>=</span> <span>&quot;Ind,near dem&quot;</span>,
    <span>&quot;Democrat, weak&quot;</span>        <span>=</span> <span>&quot;Not str democrat&quot;</span>,
    <span>&quot;Democrat, strong&quot;</span>      <span>=</span> <span>&quot;Strong democrat&quot;</span>
  <span>)</span><span>)</span> <span>%>%</span>
  <span>count</span><span>(</span><span>partyid</span><span>)</span>
<span>#> # A tibble: 10 × 2</span>
<span>#> partyid n</span>
<span>#> &lt;fctr> &lt;int></span>
<span>#> 1 No answer 154</span>
<span>#> 2 Don't know 1</span>
<span>#> 3 Other party 393</span>
<span>#> 4 Republican, strong 2314</span>
<span>#> 5 Republican, weak 3032</span>
<span>#> 6 Independent, near rep 1791</span>
<span>#> # ... with 4 more rows</span></code></pre>
<p>Note that unmentioned levels are left as is, and the order of the levels is preserved.</p>
<p><a target="_blank" href="https://hadley.github.io/forcats/fct_relump.html"><code>fct_lump()</code></a> allows you to lump the rarest (or most common) levels in to a new “other” level. The default behaviour is to collapse the smallest levels in to other, ensuring that it’s still the smallest level. For the religion variable that tells us that Protestants out number all other religions, which is interesting, but we probably want more level.</p>
<pre><code><span>gss_cat</span> <span>%>%</span> 
  <span>mutate</span><span>(</span><span>relig</span> <span>=</span> <span>fct_lump</span><span>(</span><span>relig</span><span>)</span><span>)</span> <span>%>%</span> 
  <span>count</span><span>(</span><span>relig</span><span>)</span>
<span>#> # A tibble: 2 × 2</span>
<span>#> relig n</span>
<span>#> &lt;fctr> &lt;int></span>
<span>#> 1 Other 10637</span>
<span>#> 2 Protestant 10846</span></code></pre>
<p>Alternatively you can supply a number of levels to keep, <code>n</code>, or minimum proportion for inclusion, <code>prop</code>. If you use negative values, <code>fct_lump()</code>will change direction, and combine the most common values while preserving the rarest.</p>
<pre><code><span>gss_cat</span> <span>%>%</span> 
  <span>mutate</span><span>(</span><span>relig</span> <span>=</span> <span>fct_lump</span><span>(</span><span>relig</span>, <span>n</span> <span>=</span> <span>5</span><span>)</span><span>)</span> <span>%>%</span> 
  <span>count</span><span>(</span><span>relig</span><span>)</span>
<span>#> # A tibble: 6 × 2</span>
<span>#> relig n</span>
<span>#> &lt;fctr> &lt;int></span>
<span>#> 1 Other 913</span>
<span>#> 2 Christian 689</span>
<span>#> 3 None 3523</span>
<span>#> 4 Jewish 388</span>
<span>#> 5 Catholic 5124</span>
<span>#> 6 Protestant 10846</span>

<span>gss_cat</span> <span>%>%</span> 
  <span>mutate</span><span>(</span><span>relig</span> <span>=</span> <span>fct_lump</span><span>(</span><span>relig</span>, <span>prop</span> <span>=</span> <span>-</span><span>0.10</span><span>)</span><span>)</span> <span>%>%</span> 
  <span>count</span><span>(</span><span>relig</span><span>)</span>
<span>#> # A tibble: 12 × 2</span>
<span>#> relig n</span>
<span>#> &lt;fctr> &lt;int></span>
<span>#> 1 No answer 93</span>
<span>#> 2 Don't know 15</span>
<span>#> 3 Inter-nondenominational 109</span>
<span>#> 4 Native american 23</span>
<span>#> 5 Christian 689</span>
<span>#> 6 Orthodox-christian 95</span>
<span>#> # ... with 6 more rows</span></code></pre>
</div>
<div>
<h2>Change level order</h2>
<p>There are four simple helpers for common operations:</p>
<ul>
<li><a target="_blank" href="https://hadley.github.io/forcats/fct_relevel.html"><code>fct_relevel()</code></a> is similar to <code>stats::relevel()</code> but allows you to move any number of levels to the front.</li>
<li><a target="_blank" href="https://hadley.github.io/forcats/fct_inorder.html"><code>fct_inorder()</code></a> orders according to the first appearance of each level.</li>
<li><a target="_blank" href="https://hadley.github.io/forcats/fct_infreq.html"><code>fct_infreq()</code></a> orders from most common to rarest.</li>
<li><a target="_blank" href="https://hadley.github.io/forcats/fct_rev.html"><code>fct_rev()</code></a> reverses the order of levels.</li>
</ul>
<p><a target="_blank" href="https://hadley.github.io/forcats/fct_reorder.html"><code>fct_reorder()</code></a> and <code>fct_reorder2()</code> are useful for visualisations. <code>fct_reorder()</code> reorders the factor levels by another variable. This is useful when you map a categorical variable to position, as shown in the following example which shows the average number of hours spent watching television across religions.</p>
<pre><code><span>relig</span> <span>&lt;-</span> <span>gss_cat</span> <span>%>%</span>
  <span>group_by</span><span>(</span><span>relig</span><span>)</span> <span>%>%</span>
  <span>summarise</span><span>(</span>
    <span>age</span> <span>=</span> <span>mean</span><span>(</span><span>age</span>, <span>na.rm</span> <span>=</span> <span>TRUE</span><span>)</span>,
    <span>tvhours</span> <span>=</span> <span>mean</span><span>(</span><span>tvhours</span>, <span>na.rm</span> <span>=</span> <span>TRUE</span><span>)</span>,
    <span>n</span> <span>=</span> <span>n</span><span>(</span><span>)</span>
  <span>)</span>

<span>ggplot</span><span>(</span><span>relig</span>, <span>aes</span><span>(</span><span>tvhours</span>, <span>relig</span><span>)</span><span>)</span> <span>+</span> <span>geom_point</span><span>(</span><span>)</span>
<a target="_blank" href="https://i1.wp.com/rstudioblog.files.wordpress.com/2016/08/reorder-1.png?ssl=1"><img alt="reorder-1" class="wp-image-3079" src="https://i1.wp.com/rstudioblog.files.wordpress.com/2016/08/reorder-1.png?resize=456%2C281&ssl=1" data-recalc-dims="1"></a><span>ggplot</span><span>(</span><span>relig</span>, <span>aes</span><span>(</span><span>tvhours</span>, <span>fct_reorder</span><span>(</span><span>relig</span>, <span>tvhours</span><span>)</span><span>)</span><span>)</span> <span>+</span>
  <span>geom_point</span><span>(</span><span>)</span></code></pre>
<p><a target="_blank" href="https://i2.wp.com/rstudioblog.files.wordpress.com/2016/08/reorder-2.png?ssl=1"><img alt="reorder-2" class="wp-image-3080" src="https://i2.wp.com/rstudioblog.files.wordpress.com/2016/08/reorder-2.png?resize=456%2C281&ssl=1" data-recalc-dims="1"></a></p>
<p><code>fct_reorder2()</code> extends the same idea to plots where a factor is mapped to another aesthetic, like colour. The defaults are designed to make legends easier to read for line plots, as shown in the following example looking at marital status by age.</p>
<pre><code><span>by_age</span> <span>&lt;-</span> <span>gss_cat</span> <span>%>%</span>
  <span>filter</span><span>(</span><span>!</span><span>is.na</span><span>(</span><span>age</span><span>)</span><span>)</span> <span>%>%</span>
  <span>group_by</span><span>(</span><span>age</span>, <span>marital</span><span>)</span> <span>%>%</span>
  <span>count</span><span>(</span><span>)</span> <span>%>%</span>
  <span>mutate</span><span>(</span><span>prop</span> <span>=</span> <span>n</span> <span>/</span> <span>sum</span><span>(</span><span>n</span><span>)</span><span>)</span>

<span>ggplot</span><span>(</span><span>by_age</span>, <span>aes</span><span>(</span><span>age</span>, <span>prop</span><span>)</span><span>)</span> <span>+</span>
  <span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>colour</span> <span>=</span> <span>marital</span><span>)</span><span>)</span>
<a target="_blank" href="https://i1.wp.com/rstudioblog.files.wordpress.com/2016/08/reorder2-1.png?ssl=1"><img alt="reorder2-1" class="wp-image-3081" src="https://i1.wp.com/rstudioblog.files.wordpress.com/2016/08/reorder2-1.png?resize=456%2C281&ssl=1" data-recalc-dims="1"></a><span>ggplot</span><span>(</span><span>by_age</span>, <span>aes</span><span>(</span><span>age</span>, <span>prop</span><span>)</span><span>)</span> <span>+</span>
  <span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>colour</span> <span>=</span> <span>fct_reorder2</span><span>(</span><span>marital</span>, <span>age</span>, <span>prop</span><span>)</span><span>)</span><span>)</span> <span>+</span>
  <span>labs</span><span>(</span><span>colour</span> <span>=</span> <span>&quot;marital&quot;</span><span>)</span></code>
 <a target="_blank" href="https://i2.wp.com/rstudioblog.files.wordpress.com/2016/08/reorder2-2.png?ssl=1"><img alt="reorder2-2" class="wp-image-3082" src="https://i2.wp.com/rstudioblog.files.wordpress.com/2016/08/reorder2-2.png?resize=456%2C281&ssl=1" data-recalc-dims="1"></a></pre>
</div>
<div>
<h2>Learning more</h2>
<p>You can learn more about forcats in <a target="_blank" href="http://r4ds.had.co.nz/factors.html">R for data science</a>, and on the <a target="_blank" href="https://hadley.github.io/forcats/">forcats website</a>.</p>
<p>Please <a target="_blank" href="https://github.com/hadley/forcats/issues">let me know</a> if you have more factor problems that forcats doesn’t help with!</p>
</div>
<p> <a target="_blank" rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rstudioblog.wordpress.com/3078/"><img alt="" src="http://feeds.wordpress.com/1.0/comments/rstudioblog.wordpress.com/3078/" border="0"></a> <img alt="" src="https://i1.wp.com/pixel.wp.com/b.gif?resize=1%2C1&ssl=1" border="0" data-recalc-dims="1"></p>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="https://www.r-bloggers.com/forcats-0-1-0-%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88/"></div></div><div><a data-url="https://www.r-bloggers.com/forcats-0-1-0-%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88/" data-counturl="https://www.r-bloggers.com/forcats-0-1-0-%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88%f0%9f%90%88/" data-count="vertical" data-text="forcats 0.1.0 🐈🐈🐈🐈" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://blog.rstudio.org/2016/08/31/forcats-0-1-0/"> RStudio 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 title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/q3v0zuRYy3U"></a></div>