<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Admin on R Views</title>
    <link>https://rviews.rstudio.com/categories/admin/</link>
    <description>Recent content in Admin on R Views</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 22 Apr 2019 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://rviews.rstudio.com/categories/admin/" rel="self" type="application/rss+xml" />
    
    
    
    
    <item>
      <title>Reproducible Environments</title>
      <link>https://rviews.rstudio.com/2019/04/22/reproducible-environments/</link>
      <pubDate>Mon, 22 Apr 2019 00:00:00 +0000</pubDate>
      
      <guid>https://rviews.rstudio.com/2019/04/22/reproducible-environments/</guid>
      <description>
        
&lt;script src=&#34;/rmarkdown-libs/htmlwidgets/htmlwidgets.js&#34;&gt;&lt;/script&gt;
&lt;script src=&#34;/rmarkdown-libs/plotly-binding/plotly.js&#34;&gt;&lt;/script&gt;
&lt;script src=&#34;/rmarkdown-libs/typedarray/typedarray.min.js&#34;&gt;&lt;/script&gt;
&lt;script src=&#34;/rmarkdown-libs/jquery/jquery.min.js&#34;&gt;&lt;/script&gt;
&lt;link href=&#34;/rmarkdown-libs/crosstalk/css/crosstalk.css&#34; rel=&#34;stylesheet&#34; /&gt;
&lt;script src=&#34;/rmarkdown-libs/crosstalk/js/crosstalk.min.js&#34;&gt;&lt;/script&gt;
&lt;link href=&#34;/rmarkdown-libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css&#34; rel=&#34;stylesheet&#34; /&gt;
&lt;script src=&#34;/rmarkdown-libs/plotly-main/plotly-latest.min.js&#34;&gt;&lt;/script&gt;


&lt;p&gt;Great data science work should be reproducible. The ability to repeat
experiments is part of the foundation for all science, and reproducible work is
also critical for business applications. Team collaboration, project validation,
and sustainable products presuppose the ability to reproduce work over time.&lt;/p&gt;
&lt;p&gt;In my opinion, mastering just a handful of important tools will make
reproducible work in R much easier for data scientists. R users should be
familiar with version control, RStudio projects, and literate programming
through R Markdown. Once these tools are mastered, the major remaining challenge
is creating a reproducible environment.&lt;/p&gt;
&lt;p&gt;An environment consists of all the dependencies required to enable your code to
run correctly. This includes R itself, R packages, and system dependencies. As
with many programming languages, it can be challenging to manage reproducible R
environments. Common issues include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code that used to run no longer runs, even though the code has not changed.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Being afraid to upgrade or install a new package, because it might break your code or someone else’s.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Typing &lt;code&gt;install.packages&lt;/code&gt; in your environment doesn’t do anything, or doesn’t do the &lt;em&gt;right&lt;/em&gt; thing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These challenges can be addressed through a careful combination of tools and
strategies. This post describes two use cases for reproducible environments:&lt;/p&gt;
&lt;ol style=&#34;list-style-type: decimal&#34;&gt;
&lt;li&gt;Safely upgrading packages&lt;/li&gt;
&lt;li&gt;Collaborating on a team&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The sections below each cover a strategy to address the use case, and the necessary
tools to implement each strategy. Additional use cases, strategies, and tools are
presented at &lt;a href=&#34;https://environments.rstudio.com&#34; class=&#34;uri&#34;&gt;https://environments.rstudio.com&lt;/a&gt;. This website is a work in
progress, but we look forward to your feedback.&lt;/p&gt;
&lt;div id=&#34;safely-upgrading-packages&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Safely Upgrading Packages&lt;/h2&gt;
&lt;p&gt;Upgrading packages can be a risky affair. It is not difficult to find serious R
users who have been in a situation where upgrading a package had unintended
consequences. For example, the upgrade may have broken parts of their current code, or upgrading a
package for one project accidentally broke the code in another project. A
strategy for safely upgrading packages consists of three steps:&lt;/p&gt;
&lt;ol style=&#34;list-style-type: decimal&#34;&gt;
&lt;li&gt;Isolate a project&lt;/li&gt;
&lt;li&gt;Record the current dependencies&lt;/li&gt;
&lt;li&gt;Upgrade packages&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first step in this strategy ensures one project’s packages and upgrades
won’t interfere with any other projects. Isolating projects is accomplished by
creating per-project libraries. A tool that makes this easy is the new &lt;a href=&#34;https://github.com/rstudio/renv&#34;&gt;&lt;code&gt;renv&lt;/code&gt;
package&lt;/a&gt;. Inside of your R project, simply use:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# inside the project directory
renv::init()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second step is to record the current dependencies. This step is critical
because it creates a safety net. If the package upgrade goes poorly, you’ll be
able to revert the changes and return to the record of the working state. Again,
the &lt;code&gt;renv&lt;/code&gt; package makes this process easy.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# record the current dependencies in a file called renv.lock
renv::snapshot()

# commit the lockfile alongside your code in version control
# and use this function to view the history of your lockfile
renv::history()

# if an upgrade goes astray, revert the lockfile
renv::revert(commit = &amp;quot;abc123&amp;quot;)

# and restore the previous environment
renv::restore()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With an isolated project and a safety net in place, you can now proceed to
upgrade or add new packages, while remaining certain the current functional
environment is still reproducible. The &lt;a href=&#34;https://github.com/r-lib/pak&#34;&gt;&lt;code&gt;pak&lt;/code&gt;
package&lt;/a&gt; can be used to install and upgrade
packages in an interactive environment:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# upgrade packages quickly and safely
pak::pkg_install(&amp;quot;ggplot2&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The safety net provided by the &lt;code&gt;renv&lt;/code&gt; package relies on access to older versions
of R packages. For public packages, CRAN provides these older versions in the
&lt;a href=&#34;https://cran.rstudio.com/src/contrib/Archive&#34;&gt;CRAN archive&lt;/a&gt;. Organizations can
use tools like &lt;a href=&#34;https://rstudio.com/products/package-manager&#34;&gt;RStudio Package
Manager&lt;/a&gt; to make multiple versions
of private packages available. The &lt;a href=&#34;https://environments.rstudio.com/snapshot&#34;&gt;“snapshot and
restore”&lt;/a&gt; approach can also be used
to &lt;a href=&#34;https://environments.rstudio.com/deploy&#34;&gt;promote content to production&lt;/a&gt;. In
fact, this approach is exactly how &lt;a href=&#34;https://rstudio.com/products/connect&#34;&gt;RStudio
Connect&lt;/a&gt; and
&lt;a href=&#34;https://shinyapps.io&#34;&gt;shinyapps.io&lt;/a&gt; deploy thousands of R applications to
production each day!&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;team-collaboration&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Team Collaboration&lt;/h2&gt;
&lt;p&gt;A common challenge on teams is sharing and running code. One strategy that
administrators and R users can adopt to facilitate collaboration is
shared baselines. The basics of the strategy are simple:&lt;/p&gt;
&lt;ol style=&#34;list-style-type: decimal&#34;&gt;
&lt;li&gt;Administrators setup a common environment for R users by installing RStudio Server.&lt;/li&gt;
&lt;li&gt;On the server, administrators &lt;a href=&#34;https://support.rstudio.com/hc/en-us/articles/215488098&#34;&gt;install multiple versions of R&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Each version of R is tied to a frozen repository using a Rprofile.site file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By using a frozen repository, either administrators or users can install
packages while still being sure that everyone will get the same set of packages.
A frozen repository also ensures that adding new packages won’t upgrade other
shared packages as a side-effect. New packages and upgrades are offered to users
over time through the addition of new versions of R.&lt;/p&gt;
&lt;p&gt;Frozen repositories can be created by manually cloning CRAN, accessing a service
like MRAN, or utilizing a supported product like &lt;a href=&#34;https://rstudio.com/products/package-manager&#34;&gt;RStudio Package
Manager&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/2019-04-15-repro-envs_files/figure-html/unnamed-chunk-4-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;adaptable-strategies&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Adaptable Strategies&lt;/h2&gt;
&lt;p&gt;The prior sections presented specific strategies for creating reproducible
environments in two common cases. The same strategy may not be appropriate for
every organization, R user, or situation. If you’re a student reporting an
error to your professor, capturing your &lt;code&gt;sessionInfo()&lt;/code&gt; may be all you need. In
contrast, a statistician working on a clinical trial will need a robust
framework for recreating their environment. &lt;strong&gt;Reproducibility is not binary!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/2019-04-15-repro-envs_files/figure-html/unnamed-chunk-5-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;To help pick between strategies, we’ve developed a &lt;a href=&#34;https://environments.rstudio.com/reproduce&#34;&gt;strategy
map&lt;/a&gt;. By answering two questions,
you can quickly identify where your team falls on this map and identify the
nearest successful strategy. The two questions are represented on the x and
y-axis of the map:&lt;/p&gt;
&lt;ol style=&#34;list-style-type: decimal&#34;&gt;
&lt;li&gt;Do I have any restrictions on what packages can be used?&lt;/li&gt;
&lt;li&gt;Who is responsible for managing installed packages?&lt;/li&gt;
&lt;/ol&gt;
&lt;div id=&#34;htmlwidget-1&#34; style=&#34;width:672px;height:480px;&#34; class=&#34;plotly html-widget&#34;&gt;&lt;/div&gt;
&lt;script type=&#34;application/json&#34; data-for=&#34;htmlwidget-1&#34;&gt;{&#34;x&#34;:{&#34;data&#34;:[{&#34;x&#34;:[-0.05,1.05],&#34;y&#34;:[0.15,1.25],&#34;text&#34;:&#34;&#34;,&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;lines&#34;,&#34;line&#34;:{&#34;width&#34;:1.88976377952756,&#34;color&#34;:&#34;rgba(0,0,0,0.2)&#34;,&#34;dash&#34;:&#34;solid&#34;},&#34;hoveron&#34;:&#34;points&#34;,&#34;showlegend&#34;:false,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;skip&#34;,&#34;frame&#34;:null},{&#34;x&#34;:[0,0,0.8,0],&#34;y&#34;:[0.2,1,1,0.2],&#34;text&#34;:&#34;NA&#34;,&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;lines&#34;,&#34;line&#34;:{&#34;width&#34;:1.88976377952756,&#34;color&#34;:&#34;transparent&#34;,&#34;dash&#34;:&#34;solid&#34;},&#34;fill&#34;:&#34;toself&#34;,&#34;fillcolor&#34;:&#34;rgba(255,0,0,0.1)&#34;,&#34;hoveron&#34;:&#34;fills&#34;,&#34;showlegend&#34;:false,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;skip&#34;,&#34;frame&#34;:null},{&#34;x&#34;:[0,1,0.8,0,0],&#34;y&#34;:[null,0.8,1,0.2,null],&#34;text&#34;:&#34;NA&#34;,&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;lines&#34;,&#34;line&#34;:{&#34;width&#34;:1.88976377952756,&#34;color&#34;:&#34;transparent&#34;,&#34;dash&#34;:&#34;solid&#34;},&#34;fill&#34;:&#34;toself&#34;,&#34;fillcolor&#34;:&#34;rgba(0,255,0,0.1)&#34;,&#34;hoveron&#34;:&#34;fills&#34;,&#34;showlegend&#34;:false,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;skip&#34;,&#34;frame&#34;:null},{&#34;x&#34;:[0,0,1,0.2,0],&#34;y&#34;:[0,0.2,0.8,0,0],&#34;text&#34;:&#34;&#34;,&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;lines&#34;,&#34;line&#34;:{&#34;width&#34;:1.88976377952756,&#34;color&#34;:&#34;transparent&#34;,&#34;dash&#34;:&#34;solid&#34;},&#34;fill&#34;:&#34;toself&#34;,&#34;fillcolor&#34;:&#34;rgba(0,255,0,0.1)&#34;,&#34;hoveron&#34;:&#34;fills&#34;,&#34;showlegend&#34;:false,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;skip&#34;,&#34;frame&#34;:null},{&#34;x&#34;:[0.2,1,1,0.2],&#34;y&#34;:[0,0,0.8,0],&#34;text&#34;:&#34;NA&#34;,&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;lines&#34;,&#34;line&#34;:{&#34;width&#34;:1.88976377952756,&#34;color&#34;:&#34;transparent&#34;,&#34;dash&#34;:&#34;solid&#34;},&#34;fill&#34;:&#34;toself&#34;,&#34;fillcolor&#34;:&#34;rgba(255,0,0,0.1)&#34;,&#34;hoveron&#34;:&#34;fills&#34;,&#34;showlegend&#34;:false,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;skip&#34;,&#34;frame&#34;:null},{&#34;x&#34;:[-0.05,1.05],&#34;y&#34;:[-0.25,0.85],&#34;text&#34;:&#34;&#34;,&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;lines&#34;,&#34;line&#34;:{&#34;width&#34;:1.88976377952756,&#34;color&#34;:&#34;rgba(0,0,0,0.2)&#34;,&#34;dash&#34;:&#34;solid&#34;},&#34;hoveron&#34;:&#34;points&#34;,&#34;showlegend&#34;:false,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;text&#34;,&#34;frame&#34;:null},{&#34;x&#34;:[0.5,0.75,0.2],&#34;y&#34;:[0.75,0.2,0.8],&#34;text&#34;:[&#34;Open access, &lt;br /&gt; not reproducible, &lt;br /&gt; how we learn&#34;,&#34;Backdoor package access, &lt;br /&gt; offline systems without a strategy&#34;,&#34;Admins involved, &lt;br /&gt; no testing, &lt;br /&gt; slow updates, &lt;br /&gt; high risk of breakage&#34;],&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;markers&#34;,&#34;marker&#34;:{&#34;autocolorscale&#34;:false,&#34;color&#34;:&#34;rgba(255,0,0,1)&#34;,&#34;opacity&#34;:1,&#34;size&#34;:5.66929133858268,&#34;symbol&#34;:&#34;circle&#34;,&#34;line&#34;:{&#34;width&#34;:1.88976377952756,&#34;color&#34;:&#34;rgba(255,0,0,1)&#34;}},&#34;hoveron&#34;:&#34;points&#34;,&#34;name&#34;:&#34;FALSE&#34;,&#34;legendgroup&#34;:&#34;FALSE&#34;,&#34;showlegend&#34;:true,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;text&#34;,&#34;frame&#34;:null},{&#34;x&#34;:[0.1,0.5,0.8],&#34;y&#34;:[0.1,0.5,0.8],&#34;text&#34;:[&#34;Admins test and approve &lt;br /&gt; a subset of CRAN&#34;,&#34;All or most of CRAN, &lt;br /&gt; updated with R versions, &lt;br /&gt; tied to a system library&#34;,&#34;Open access, user or system &lt;br /&gt; records per-project dependencies&#34;],&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;markers&#34;,&#34;marker&#34;:{&#34;autocolorscale&#34;:false,&#34;color&#34;:&#34;rgba(163,197,134,1)&#34;,&#34;opacity&#34;:1,&#34;size&#34;:5.66929133858268,&#34;symbol&#34;:&#34;circle&#34;,&#34;line&#34;:{&#34;width&#34;:1.88976377952756,&#34;color&#34;:&#34;rgba(163,197,134,1)&#34;}},&#34;hoveron&#34;:&#34;points&#34;,&#34;name&#34;:&#34; TRUE&#34;,&#34;legendgroup&#34;:&#34; TRUE&#34;,&#34;showlegend&#34;:true,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;text&#34;,&#34;frame&#34;:null},{&#34;x&#34;:[0.125,0.525,0.525,0.825,0.775,0.225],&#34;y&#34;:[0.125,0.525,0.775,0.825,0.225,0.825],&#34;text&#34;:[&#34;Validated&#34;,&#34;Shared Baseline&#34;,&#34;Wild West&#34;,&#34;Snapshot&#34;,&#34;Blocked&#34;,&#34;Ticket System&#34;],&#34;hovertext&#34;:[&#34;&#34;,&#34;&#34;,&#34;&#34;,&#34;&#34;,&#34;&#34;,&#34;&#34;],&#34;textfont&#34;:{&#34;size&#34;:14.6645669291339,&#34;color&#34;:&#34;rgba(0,0,0,1)&#34;},&#34;type&#34;:&#34;scatter&#34;,&#34;mode&#34;:&#34;text&#34;,&#34;hoveron&#34;:&#34;points&#34;,&#34;showlegend&#34;:false,&#34;xaxis&#34;:&#34;x&#34;,&#34;yaxis&#34;:&#34;y&#34;,&#34;hoverinfo&#34;:&#34;text&#34;,&#34;frame&#34;:null}],&#34;layout&#34;:{&#34;margin&#34;:{&#34;t&#34;:43.7625570776256,&#34;r&#34;:7.30593607305936,&#34;b&#34;:40.1826484018265,&#34;l&#34;:89.8630136986302},&#34;font&#34;:{&#34;color&#34;:&#34;rgba(0,0,0,1)&#34;,&#34;family&#34;:&#34;&#34;,&#34;size&#34;:14.6118721461187},&#34;title&#34;:&#34;Reproducing Environments: Strategies and Danger Zones&#34;,&#34;titlefont&#34;:{&#34;color&#34;:&#34;rgba(0,0,0,1)&#34;,&#34;family&#34;:&#34;&#34;,&#34;size&#34;:17.5342465753425},&#34;xaxis&#34;:{&#34;domain&#34;:[0,1],&#34;automargin&#34;:true,&#34;type&#34;:&#34;linear&#34;,&#34;autorange&#34;:false,&#34;range&#34;:[-0.05,1.05],&#34;tickmode&#34;:&#34;array&#34;,&#34;ticktext&#34;:[&#34;Admins&#34;,&#34;&#34;,&#34;&#34;,&#34;&#34;,&#34;Users&#34;],&#34;tickvals&#34;:[0,0.25,0.5,0.75,1],&#34;categoryorder&#34;:&#34;array&#34;,&#34;categoryarray&#34;:[&#34;Admins&#34;,&#34;&#34;,&#34;&#34;,&#34;&#34;,&#34;Users&#34;],&#34;nticks&#34;:null,&#34;ticks&#34;:&#34;&#34;,&#34;tickcolor&#34;:null,&#34;ticklen&#34;:3.65296803652968,&#34;tickwidth&#34;:0,&#34;showticklabels&#34;:true,&#34;tickfont&#34;:{&#34;color&#34;:&#34;rgba(77,77,77,1)&#34;,&#34;family&#34;:&#34;&#34;,&#34;size&#34;:11.689497716895},&#34;tickangle&#34;:-0,&#34;showline&#34;:false,&#34;linecolor&#34;:null,&#34;linewidth&#34;:0,&#34;showgrid&#34;:true,&#34;gridcolor&#34;:&#34;rgba(235,235,235,1)&#34;,&#34;gridwidth&#34;:0.66417600664176,&#34;zeroline&#34;:false,&#34;anchor&#34;:&#34;y&#34;,&#34;title&#34;:&#34;Who is Responsible for Reproducing the Environment?&#34;,&#34;titlefont&#34;:{&#34;color&#34;:&#34;rgba(0,0,0,1)&#34;,&#34;family&#34;:&#34;&#34;,&#34;size&#34;:14.6118721461187},&#34;hoverformat&#34;:&#34;.2f&#34;},&#34;yaxis&#34;:{&#34;domain&#34;:[0,1],&#34;automargin&#34;:true,&#34;type&#34;:&#34;linear&#34;,&#34;autorange&#34;:false,&#34;range&#34;:[-0.05,1.05],&#34;tickmode&#34;:&#34;array&#34;,&#34;ticktext&#34;:[&#34;Locked Down&#34;,&#34;&#34;,&#34;&#34;,&#34;&#34;,&#34;Open&#34;],&#34;tickvals&#34;:[0,0.25,0.5,0.75,1],&#34;categoryorder&#34;:&#34;array&#34;,&#34;categoryarray&#34;:[&#34;Locked Down&#34;,&#34;&#34;,&#34;&#34;,&#34;&#34;,&#34;Open&#34;],&#34;nticks&#34;:null,&#34;ticks&#34;:&#34;&#34;,&#34;tickcolor&#34;:null,&#34;ticklen&#34;:3.65296803652968,&#34;tickwidth&#34;:0,&#34;showticklabels&#34;:true,&#34;tickfont&#34;:{&#34;color&#34;:&#34;rgba(77,77,77,1)&#34;,&#34;family&#34;:&#34;&#34;,&#34;size&#34;:11.689497716895},&#34;tickangle&#34;:-0,&#34;showline&#34;:false,&#34;linecolor&#34;:null,&#34;linewidth&#34;:0,&#34;showgrid&#34;:true,&#34;gridcolor&#34;:&#34;rgba(235,235,235,1)&#34;,&#34;gridwidth&#34;:0.66417600664176,&#34;zeroline&#34;:false,&#34;anchor&#34;:&#34;x&#34;,&#34;title&#34;:&#34;Package Access&#34;,&#34;titlefont&#34;:{&#34;color&#34;:&#34;rgba(0,0,0,1)&#34;,&#34;family&#34;:&#34;&#34;,&#34;size&#34;:14.6118721461187},&#34;hoverformat&#34;:&#34;.2f&#34;},&#34;shapes&#34;:[{&#34;type&#34;:&#34;rect&#34;,&#34;fillcolor&#34;:null,&#34;line&#34;:{&#34;color&#34;:null,&#34;width&#34;:0,&#34;linetype&#34;:[]},&#34;yref&#34;:&#34;paper&#34;,&#34;xref&#34;:&#34;paper&#34;,&#34;x0&#34;:0,&#34;x1&#34;:1,&#34;y0&#34;:0,&#34;y1&#34;:1}],&#34;showlegend&#34;:false,&#34;legend&#34;:{&#34;bgcolor&#34;:null,&#34;bordercolor&#34;:null,&#34;borderwidth&#34;:0,&#34;font&#34;:{&#34;color&#34;:&#34;rgba(0,0,0,1)&#34;,&#34;family&#34;:&#34;&#34;,&#34;size&#34;:11.689497716895},&#34;y&#34;:1},&#34;hovermode&#34;:&#34;closest&#34;,&#34;barmode&#34;:&#34;relative&#34;},&#34;config&#34;:{&#34;doubleClick&#34;:&#34;reset&#34;,&#34;modeBarButtonsToAdd&#34;:[{&#34;name&#34;:&#34;Collaborate&#34;,&#34;icon&#34;:{&#34;width&#34;:1000,&#34;ascent&#34;:500,&#34;descent&#34;:-50,&#34;path&#34;:&#34;M487 375c7-10 9-23 5-36l-79-259c-3-12-11-23-22-31-11-8-22-12-35-12l-263 0c-15 0-29 5-43 15-13 10-23 23-28 37-5 13-5 25-1 37 0 0 0 3 1 7 1 5 1 8 1 11 0 2 0 4-1 6 0 3-1 5-1 6 1 2 2 4 3 6 1 2 2 4 4 6 2 3 4 5 5 7 5 7 9 16 13 26 4 10 7 19 9 26 0 2 0 5 0 9-1 4-1 6 0 8 0 2 2 5 4 8 3 3 5 5 5 7 4 6 8 15 12 26 4 11 7 19 7 26 1 1 0 4 0 9-1 4-1 7 0 8 1 2 3 5 6 8 4 4 6 6 6 7 4 5 8 13 13 24 4 11 7 20 7 28 1 1 0 4 0 7-1 3-1 6-1 7 0 2 1 4 3 6 1 1 3 4 5 6 2 3 3 5 5 6 1 2 3 5 4 9 2 3 3 7 5 10 1 3 2 6 4 10 2 4 4 7 6 9 2 3 4 5 7 7 3 2 7 3 11 3 3 0 8 0 13-1l0-1c7 2 12 2 14 2l218 0c14 0 25-5 32-16 8-10 10-23 6-37l-79-259c-7-22-13-37-20-43-7-7-19-10-37-10l-248 0c-5 0-9-2-11-5-2-3-2-7 0-12 4-13 18-20 41-20l264 0c5 0 10 2 16 5 5 3 8 6 10 11l85 282c2 5 2 10 2 17 7-3 13-7 17-13z m-304 0c-1-3-1-5 0-7 1-1 3-2 6-2l174 0c2 0 4 1 7 2 2 2 4 4 5 7l6 18c0 3 0 5-1 7-1 1-3 2-6 2l-173 0c-3 0-5-1-8-2-2-2-4-4-4-7z m-24-73c-1-3-1-5 0-7 2-2 3-2 6-2l174 0c2 0 5 0 7 2 3 2 4 4 5 7l6 18c1 2 0 5-1 6-1 2-3 3-5 3l-174 0c-3 0-5-1-7-3-3-1-4-4-5-6z&#34;},&#34;click&#34;:&#34;function(gd) { \n        // is this being viewed in RStudio?\n        if (location.search == &#39;?viewer_pane=1&#39;) {\n          alert(&#39;To learn about plotly for collaboration, visit:\\n https://cpsievert.github.io/plotly_book/plot-ly-for-collaboration.html&#39;);\n        } else {\n          window.open(&#39;https://cpsievert.github.io/plotly_book/plot-ly-for-collaboration.html&#39;, &#39;_blank&#39;);\n        }\n      }&#34;}],&#34;cloud&#34;:false,&#34;displayModeBar&#34;:false},&#34;source&#34;:&#34;A&#34;,&#34;attrs&#34;:{&#34;f87a7b9b28cc&#34;:{&#34;intercept&#34;:{},&#34;slope&#34;:{},&#34;type&#34;:&#34;scatter&#34;},&#34;f87a793a87a&#34;:{&#34;x&#34;:{},&#34;y&#34;:{},&#34;text&#34;:{},&#34;x.1&#34;:{},&#34;y.1&#34;:{}},&#34;f87a6f19e578&#34;:{&#34;x&#34;:{},&#34;y&#34;:{},&#34;text&#34;:{},&#34;x.1&#34;:{},&#34;y.1&#34;:{}},&#34;f87ad286244&#34;:{&#34;x&#34;:{},&#34;y&#34;:{},&#34;text&#34;:{},&#34;x.1&#34;:{},&#34;y.1&#34;:{}},&#34;f87a564b651b&#34;:{&#34;x&#34;:{},&#34;y&#34;:{},&#34;text&#34;:{},&#34;x.1&#34;:{},&#34;y.1&#34;:{}},&#34;f87a6fdafbdf&#34;:{&#34;intercept&#34;:{},&#34;slope&#34;:{}},&#34;f87a11ce26d8&#34;:{&#34;x&#34;:{},&#34;y&#34;:{},&#34;colour&#34;:{},&#34;text&#34;:{},&#34;x.1&#34;:{},&#34;y.1&#34;:{}},&#34;f87a75583809&#34;:{&#34;x&#34;:{},&#34;y&#34;:{},&#34;label&#34;:{},&#34;x.1&#34;:{},&#34;y.1&#34;:{}}},&#34;cur_data&#34;:&#34;f87a7b9b28cc&#34;,&#34;visdat&#34;:{&#34;f87a7b9b28cc&#34;:[&#34;function (y) &#34;,&#34;x&#34;],&#34;f87a793a87a&#34;:[&#34;function (y) &#34;,&#34;x&#34;],&#34;f87a6f19e578&#34;:[&#34;function (y) &#34;,&#34;x&#34;],&#34;f87ad286244&#34;:[&#34;function (y) &#34;,&#34;x&#34;],&#34;f87a564b651b&#34;:[&#34;function (y) &#34;,&#34;x&#34;],&#34;f87a6fdafbdf&#34;:[&#34;function (y) &#34;,&#34;x&#34;],&#34;f87a11ce26d8&#34;:[&#34;function (y) &#34;,&#34;x&#34;],&#34;f87a75583809&#34;:[&#34;function (y) &#34;,&#34;x&#34;]},&#34;highlight&#34;:{&#34;on&#34;:&#34;plotly_click&#34;,&#34;persistent&#34;:false,&#34;dynamic&#34;:false,&#34;selectize&#34;:false,&#34;opacityDim&#34;:0.2,&#34;selected&#34;:{&#34;opacity&#34;:1},&#34;debounce&#34;:0},&#34;base_url&#34;:&#34;https://plot.ly&#34;,&#34;.hideLegend&#34;:true},&#34;evals&#34;:[&#34;config.modeBarButtonsToAdd.0.click&#34;],&#34;jsHooks&#34;:[]}&lt;/script&gt;
&lt;p&gt;For more information on picking and using these strategies, please visit
&lt;a href=&#34;https://environments.rstudio.com&#34; class=&#34;uri&#34;&gt;https://environments.rstudio.com&lt;/a&gt;. By adopting a strategy for reproducible
environments, R users, administrators, and teams can solve a number of important
challenges. Ultimately, reproducible work adds credibility, creating a solid
foundation for research, business applications, and production systems. We are
excited to be working on tools to make reproducible work in R easy and fun. We
look forward to your feedback, community discussions, and future posts.&lt;/p&gt;
&lt;/div&gt;

        &lt;script&gt;window.location.href=&#39;https://rviews.rstudio.com/2019/04/22/reproducible-environments/&#39;;&lt;/script&gt;
      </description>
    </item>
    
    <item>
      <title>Setting up RStudio Server on a Cloud for Collaboration and Reproducibility</title>
      <link>https://rviews.rstudio.com/2019/04/17/setting-up-rstudio-server-on-a-cloud-with-linux/</link>
      <pubDate>Wed, 17 Apr 2019 00:00:00 +0000</pubDate>
      
      <guid>https://rviews.rstudio.com/2019/04/17/setting-up-rstudio-server-on-a-cloud-with-linux/</guid>
      <description>
        &lt;p&gt;&lt;em&gt;Roland Stevenson is a data scientist and consultant who may be reached on &lt;a href=&#34;https://www.linkedin.com/in/roland-stevenson/&#34;&gt;Linkedin&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When setting up R and RStudio Server on a cloud Linux instance, some thought should be given to implementing a workflow that facilitates collaboration and ensures R project reproducibility. There are many possible workflows to accomplish this. In this post, we offer an &amp;ldquo;opinionated&amp;rdquo; solution based on what we have found to work in a production environment. We assume all development takes place on an RStudio Server cloud Linux instance, ensuring that only one operating system needs to be supported. We will keep the motivation for &lt;a href=&#34;https://semver.org/&#34;&gt;good versioning&lt;/a&gt; and &lt;a href=&#34;http://adv-r.had.co.nz/Reproducibility.html&#34;&gt;reproducibility&lt;/a&gt; short:  R projects evolve over time, as do the packages that they rely on. R projects that do not control package versions will eventually break and/or not be shareable or &lt;a href=&#34;https://en.wikipedia.org/wiki/Replication_crisis&#34;&gt;reproducible&lt;/a&gt;&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Since R is a slowly evolving language, it might be reasonable to require that a particular Linux instance have only one version of R installed.  However, requiring all R users to use the same versions of all packages to facilitate collaboration is clearly out of the question. The solution is to control package versions at the project level.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/post/2019-04-15-Roland_files/Roland1.png&#34; alt=&#34;R system, user, and Packrat library locations in Linux CentOS 7&#34; /&gt;&lt;/p&gt;

&lt;p&gt;We use &lt;a href=&#34;https://rstudio.github.io/packrat/&#34;&gt;&lt;code&gt;packrat&lt;/code&gt;&lt;/a&gt; to control package versions. Already integrated with RStudio Server, &lt;code&gt;packrat&lt;/code&gt; ensures that all installed packages are stored &lt;em&gt;with&lt;/em&gt; the project&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, and that these packages are available when a project is opened.  With &lt;code&gt;packrat&lt;/code&gt;, we know that project A will always be able to use ggplot2 2.5.0 and project B will always be able to use ggplot2 3.1.0.  This is important if we want to be able to reproduce results in the future.&lt;/p&gt;

&lt;p&gt;On Linux, &lt;code&gt;packrat&lt;/code&gt; stores compiled packages in &lt;code&gt;packrat/lib/&amp;lt;LINUX_FLAVOR&amp;gt;/&amp;lt;R_VERSION&amp;gt;&lt;/code&gt;, an R-version-specific path, relative to the project&amp;rsquo;s base directory.  An issue arises if we are using R version 3.5.0 one week and then upgrade to R 3.5.1 the next week: a &lt;code&gt;packrat&lt;/code&gt; project will not find the 3.5.0 libraries anymore, and we will need to rebuild all the packages to install them in the 3.5.1 path. &lt;code&gt;packrat&lt;/code&gt; will automatically build all packages from source (sources are stored in &lt;code&gt;packrat/src&lt;/code&gt;) if it notices they are missing. However, this process can take tens of minutes, depending on the number of packages being built. Since this can be cumbersome when collaborating, we also opt to include the &lt;code&gt;packrat/lib&lt;/code&gt; path in version control, thereby committing the compiled libraries as well.&lt;/p&gt;

&lt;p&gt;Our solution is to bind one fixed R version to an instance&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and release fixed-R instance images periodically. We prefer limited, consistent R-versions over continually upgrading to the most recent version of R. This approach helps to ensure reproducibility and make collaboration easier, avoids having to use docker containers&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;. While binding a fixed version of R to an instance may seem restrictive, we have found that it is in fact quite liberating. Since we only update the existing R version infrequently (think once a year), the barrier of agreeing on an R-version is removed and with it any need to agree on package versions at the user level.  Instead, packages are distributed with the project via git. The benefits of fixing the R version for a particular instance are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sharing &lt;code&gt;packrat&lt;/code&gt; projects and reproducing results are both made easier, since pre-compiled libraries are included with the projects.&lt;/li&gt;
&lt;li&gt;Fixing the R-version on an instance doesn&amp;rsquo;t keep us from upgrading R for a project, as &lt;code&gt;packrat&lt;/code&gt; will automatically build and install libraries if an upgraded version is detected. In this way, a project can be opened on an instance with an upgraded R version and have its libraries compiled. Our limited instance image release schedule means the overhead to handle this only occurs at a maximum of once each year.&lt;/li&gt;
&lt;li&gt;It is very unlikely that results will be different across R-versions, however being able to tie project results to one R-version allows us to upgrade R for a project while ensuring that results remain as expected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we lose by not being on the bleeding edge of (thankfully relatively non-critical) bug fixes we gain in ease of collaboration. Here&amp;rsquo;s what we&amp;rsquo;ve done to accomplish this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ras44/rstudio-instance&#34;&gt;rstudio-instance&lt;/a&gt; contains branches with scripts to set up a Linux instance with fixed R and RStudio versions. We &lt;code&gt;git clone&lt;/code&gt; the repo and &lt;code&gt;git checkout&lt;/code&gt; the branch suitable for the Linux flavor, R-version, and RStudio version we want. The scripts also ensure R is not auto-updated in the future.&lt;/li&gt;
&lt;li&gt;We then run the install script to set up the instance and archive an image of it for future use.&lt;/li&gt;
&lt;li&gt;Once the fixed-R instance is set up, &lt;a href=&#34;https://github.com/ras44/rstudio-project&#34;&gt;rstudio-project&lt;/a&gt; contains an R-version specific base project with pre-built, &lt;code&gt;packrat&lt;/code&gt;-managed, fixed-versions of many popular data-science packages&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;We &lt;code&gt;git clone&lt;/code&gt; &lt;a href=&#34;https://github.com/ras44/rstudio-project&#34;&gt;rstudio-project&lt;/a&gt; to a new project directory locally and remove the existing &lt;code&gt;.git&lt;/code&gt; directory so that it can be turned it into a new git repo with &lt;code&gt;git init&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We open the project in RStudio and begin work. All packages are pre-built, so we don&amp;rsquo;t have to go through lengthy installs.  We can upgrade packages in the &lt;code&gt;packrat&lt;/code&gt; library of the &amp;ldquo;Packages&amp;rdquo; tab, and then run &lt;code&gt;packrat::snapshot()&lt;/code&gt; to save any libraries and ugrades into the project&amp;rsquo;s &lt;code&gt;packrat/&lt;/code&gt; directory. We can then &lt;code&gt;git add packrat&lt;/code&gt; to add any &lt;code&gt;packrat&lt;/code&gt; updates to the project&amp;rsquo;s git repo.&lt;/li&gt;
&lt;li&gt;If we ever need to duplicate results, we can always build the same fixed-R instance (or clone the image we stored earlier), clone the project on the instance, and know that it will work exactly the same as when we previously worked on it&amp;hellip; sometimes years earlier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a quick example script showing the workflow:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone git@github.com:ras44/rstudio-instance.git
cd rstudio-instance
git checkout centos7_R3.5.0_RSS1.1.453
./install.sh
sudo passwd &amp;lt;USERNAME&amp;gt; # set user password for RStudio Server login
cd
git clone git@github.com:ras44/rstudio-project.git new-project
cd new-project
git checkout dev-linux-centos7-R3.5.0
rm -rf .git
git init
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, here are some issues with &lt;code&gt;packrat&lt;/code&gt; that we have run into along with our solutions. Note that RStudio support has been very helpful in addressing issues while monitoring and providing solutions via their &lt;a href=&#34;https://github.com/rstudio/packrat/issues&#34;&gt;github issue tracker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/post/2019-04-15-Roland_files/Roland2.png&#34; alt=&#34;`packrat` libraries are listed under &amp;quot;Project Library&amp;quot;&#34; /&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If R crashes and the &lt;code&gt;packrat&lt;/code&gt; libraries are not accessible after the RStudio restarts the session, the project might need to be re-opened. Run &lt;code&gt;.libPaths()&lt;/code&gt; to ensure the project library paths are correct. Verify libraries are accessible by looking at the &amp;ldquo;packages&amp;rdquo; tab in RStudio Server and ensuring a &amp;ldquo;Project Library&amp;rdquo; header exists with all packages(see above image). Follow &lt;a href=&#34;https://github.com/rstudio/packrat/issues/549&#34;&gt;issue discussion&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;An &lt;a href=&#34;https://github.com/r-dbi/bigrquery/issues/247&#34;&gt;issue&lt;/a&gt; can arise when some packages are updated but others aren&amp;rsquo;t. This can be challenging to troubleshoot and raises the question of what to do when package versions become incompatible with each other. This is not &lt;code&gt;packrat&lt;/code&gt;, but version compatibility.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Installing packages directly from a private/internal github is evolving. An easy solution exists: simply clone the package to a local directory such as &lt;code&gt;~/local_repos/&lt;/code&gt;.  Then use &lt;code&gt;install_local()&lt;/code&gt; to install from the &lt;code&gt;local_repos&lt;/code&gt; directory. See &lt;a href=&#34;https://github.com/rstudio/packrat/issues/447&#34;&gt;issue&lt;/a&gt; for details.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;packrat&lt;/code&gt; can occasionally have &lt;a href=&#34;https://github.com/rstudio/packrat/issues/347&#34;&gt;very slow snapshots&lt;/a&gt;, particularly with projects that contains many R-Markdown files and packages.  This is likely due to &lt;code&gt;packrat&lt;/code&gt; dependency searches. As discussed in the issue, we resolve it by ignoring all of our source directories with &lt;code&gt;packrat::set_opts(ignored.directories=c(&amp;quot;all&amp;quot;,&amp;quot;my&amp;quot;,&amp;quot;R&amp;quot;,&amp;quot;src&amp;quot;,&amp;quot;directories&amp;quot;)&lt;/code&gt; and then running &lt;code&gt;packrat::snapshot(ignore.stale=TRUE, infer.dependencies=FALSE)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr /&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;Unless you somehow exclusively use packages that are never updated, never implement version-breaking/major version updates, or always provide backwards-compatible version upgrades. Many R packages are in major version 0, meaning there is no guarantee that a future release will maintain the same API.
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:1&#34;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;In the &lt;code&gt;packrat/&lt;/code&gt; directory
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:2&#34;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;It &lt;a href=&#34;https://support.rstudio.com/hc/en-us/articles/215488098-Installing-multiple-versions-of-R-on-Linux&#34;&gt;is possible&lt;/a&gt; to have multiple R versions installed on a system. I have avoided that for simplicity.
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:5&#34;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;docker containers may be a good alternate solution, but in this case we are not using them.
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:4&#34;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;rstudio-project contains all packages in the anaconda distribution and more.
 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:3&#34;&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

        &lt;script&gt;window.location.href=&#39;https://rviews.rstudio.com/2019/04/17/setting-up-rstudio-server-on-a-cloud-with-linux/&#39;;&lt;/script&gt;
      </description>
    </item>
    
    <item>
      <title>Reading and analysing log files in the RRD database format</title>
      <link>https://rviews.rstudio.com/2018/06/20/reading-rrd-files/</link>
      <pubDate>Wed, 20 Jun 2018 00:00:00 +0000</pubDate>
      
      <guid>https://rviews.rstudio.com/2018/06/20/reading-rrd-files/</guid>
      <description>
        

&lt;p&gt;I have frequent conversations with R champions and Systems Administrators responsible for R, in which they ask how they can measure and analyze the usage of their servers.  Among the many solutions to this problem, one of the my favourites is to use an &lt;strong&gt;RRD&lt;/strong&gt; database and &lt;strong&gt;RRDtool&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From &lt;a href=&#34;https://en.wikipedia.org/wiki/RRDtool&#34;&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RRDtool&lt;/strong&gt; (&lt;em&gt;round-robin database tool&lt;/em&gt;) aims to handle time series data such as network bandwidth, temperatures or CPU load. The data is stored in a &lt;a href=&#34;https://en.wikipedia.org/wiki/Circular_buffer&#34;&gt;circular buffer&lt;/a&gt; based &lt;a href=&#34;https://en.wikipedia.org/wiki/Database&#34;&gt;database&lt;/a&gt;, thus the system storage footprint remains constant over time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&#34;https://oss.oetiker.ch/rrdtool/index.en.html&#34;&gt;RRDtool&lt;/a&gt; is a library written in C, with implementations that can also be accessed from the Linux command line. This makes it convenient for system development, but makes it difficult for R users to extract and analyze this data.&lt;/p&gt;

&lt;p&gt;I am pleased to announce that I&amp;rsquo;ve been working on the &lt;code&gt;rrd&lt;/code&gt; &lt;a href=&#34;https://github.com/andrie/rrd&#34;&gt;R package&lt;/a&gt; to import RRD files directly into &lt;code&gt;tibble&lt;/code&gt; objects, thus making it easy to analyze your metrics.&lt;/p&gt;

&lt;p&gt;As an aside, the RStudio Pro products (specifically &lt;a href=&#34;https://www.rstudio.com/products/rstudio-server-pro/&#34;&gt;RStudio Server Pro&lt;/a&gt; and &lt;a href=&#34;https://www.rstudio.com/products/connect/&#34;&gt;RStudio Connect&lt;/a&gt;) also make use of RRD to store metrics &amp;ndash; more about this later.&lt;/p&gt;

&lt;h2 id=&#34;understanding-the-rrd-format-as-an-r-user&#34;&gt;Understanding the RRD format as an R user&lt;/h2&gt;

&lt;p&gt;The name RRD is an initialism of &lt;strong&gt;R&lt;/strong&gt;ound &lt;strong&gt;R&lt;/strong&gt;obin &lt;strong&gt;D&lt;/strong&gt;atabase.  The &amp;ldquo;round robin&amp;rdquo; refers to the fact that the database is always fixed in size, and as a new entry enters the database, the oldest entry is discarded. In practical terms, the database collects data for a fixed period of time, and information that is older than the threshold gets removed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/post/2018-06-21-analysing-rrd-files_files/rra.png&#34; alt=&#34;Image from loriotpro(https://bit.ly/2tk2MFa)&#34; /&gt;&lt;/p&gt;

&lt;p&gt;A second quality of RRD databases is that each datum is stored in different &amp;ldquo;consolidation data points&amp;rdquo;, where every data point is an aggregation over time. For example, a data point can represent an average value for the time period, or a maximum over the period.  Typical consolidation functions include &lt;code&gt;average&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt; and  &lt;code&gt;max&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The third quality is that every RRD database file typically consists of multiple archives. Each archive measures data for a different time period. For instance, the archives can capture data for intervals of 10 seconds, 30 seconds, 1 minute or 5 minutes.&lt;/p&gt;

&lt;p&gt;As an example, here is a description of an RRD file that originated in RStudio Connect:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe_rrd(&amp;quot;rrd_cpu_0&amp;quot;)
#&amp;gt; A RRD file with 10 RRA arrays and step size 60
#&amp;gt; [1] AVERAGE_60 (43200 rows)
#&amp;gt; [2] AVERAGE_300 (25920 rows)
#&amp;gt; [3] MIN_300 (25920 rows)
#&amp;gt; [4] MAX_300 (25920 rows)
#&amp;gt; [5] AVERAGE_3600 (8760 rows)
#&amp;gt; [6] MIN_3600 (8760 rows)
#&amp;gt; [7] MAX_3600 (8760 rows)
#&amp;gt; [8] AVERAGE_86400 (1825 rows)
#&amp;gt; [9] MIN_86400 (1825 rows)
#&amp;gt; [10] MAX_86400 (1825 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This &lt;code&gt;RRD&lt;/code&gt; file contains data for the properties of CPU 0 of the system.  In this example, the first &lt;code&gt;RRA&lt;/code&gt; archive contains averaged metrics for one minute (60s) intervals, while the second &lt;code&gt;RRA&lt;/code&gt; measures the same metric, but averaged over five minutes.  The same metrics are also available for intervals of one hour and one day.&lt;/p&gt;

&lt;p&gt;Notice also that every archive has a different number of rows, representing a different historical period where the data is kept.  For example, the &lt;em&gt;per minute&lt;/em&gt; data &lt;code&gt;AVERAGE_60&lt;/code&gt; is retained for 43,200 periods (12 days) while the &lt;em&gt;daily&lt;/em&gt; data &lt;code&gt;MAX_86400&lt;/code&gt; is retained for 1,825 periods (5 years).&lt;/p&gt;

&lt;p&gt;If you want to know more, please read the excellent &lt;a href=&#34;https://oss.oetiker.ch/rrdtool/tut/rrdtutorial.en.html&#34;&gt;introduction tutorial&lt;/a&gt; to RRD database.&lt;/p&gt;

&lt;h2 id=&#34;introducing-the-rrd-package&#34;&gt;Introducing the &lt;code&gt;rrd&lt;/code&gt; package&lt;/h2&gt;

&lt;p&gt;Until recently, it wasn&amp;rsquo;t easy to import RRD files into R.  But I was pleased to discover that a &lt;a href=&#34;https://www.google-melange.com/archive/gsoc/2014&#34;&gt;Google Summer of Code 2014&lt;/a&gt; project created a proof-of-concept R package to read these files.  The author of this package is &lt;a href=&#34;http://plamendimitrov.net/&#34;&gt;Plamen Dimitrov&lt;/a&gt;, who published the code on &lt;a href=&#34;https://github.com/pldimitrov/Rrd&#34;&gt;GitHub&lt;/a&gt; and also wrote an &lt;a href=&#34;http://plamendimitrov.net/blog/2014/08/09/r-package-for-working-with-rrd-files/&#34;&gt;explanatory blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Because I had to provide some suggestions to our customers, I decided to update the package, provide some example code, and generally improve the reliability.&lt;/p&gt;

&lt;p&gt;The result is not yet on CRAN, but you can install the development version of package from &lt;a href=&#34;https://github.com/andrie/rrd&#34;&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&#34;installing-the-package&#34;&gt;Installing the package&lt;/h3&gt;

&lt;p&gt;To build the package from source, you first need to install &lt;a href=&#34;http://oss.oetiker.ch/rrdtool/doc/librrd.en.html&#34;&gt;librrd&lt;/a&gt;. Installing &lt;a href=&#34;http://oss.oetiker.ch/rrdtool/&#34;&gt;RRDtool&lt;/a&gt; from your Linux package manager will usually also install this library.&lt;/p&gt;

&lt;p&gt;Using Ubuntu:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;sudo apt-get install rrdtool librrd-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Using RHEL / CentOS:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-sh&#34;&gt;sudo yum install rrdtool rrdtool-devel
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once you have the system requirements in place, you can install the development version of the R package from &lt;a href=&#34;https://github.com/andrie/rrd&#34;&gt;GitHub&lt;/a&gt; using:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;# install.packages(&amp;quot;devtools&amp;quot;)
devtools::install_github(&amp;quot;andrie/rrd&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;limitations&#34;&gt;Limitations&lt;/h3&gt;

&lt;p&gt;The package is not yet available for Windows.&lt;/p&gt;

&lt;h3 id=&#34;using-the-package&#34;&gt;Using the package&lt;/h3&gt;

&lt;p&gt;Once you&amp;rsquo;ve installed the package, you can start to use it. The package itself contains some built-in RRD files, so you should be able to run the following code directly.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;library(rrd)
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;describing-the-contents-of-a-rrd&#34;&gt;Describing the contents of a RRD&lt;/h4&gt;

&lt;p&gt;To describe the contents of an RRD file, use &lt;code&gt;describe_rrd()&lt;/code&gt;. This function reports information about the names of each archive (RRA) file, the consolidation function, and the number of observations:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;rrd_cpu_0 &amp;lt;- system.file(&amp;quot;extdata/cpu-0.rrd&amp;quot;, package = &amp;quot;rrd&amp;quot;)

describe_rrd(rrd_cpu_0)
#&amp;gt; A RRD file with 10 RRA arrays and step size 60
#&amp;gt; [1] AVERAGE_60 (43200 rows)
#&amp;gt; [2] AVERAGE_300 (25920 rows)
#&amp;gt; [3] MIN_300 (25920 rows)
#&amp;gt; [4] MAX_300 (25920 rows)
#&amp;gt; [5] AVERAGE_3600 (8760 rows)
#&amp;gt; [6] MIN_3600 (8760 rows)
#&amp;gt; [7] MAX_3600 (8760 rows)
#&amp;gt; [8] AVERAGE_86400 (1825 rows)
#&amp;gt; [9] MIN_86400 (1825 rows)
#&amp;gt; [10] MAX_86400 (1825 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;reading-an-entire-rrd-file&#34;&gt;Reading an entire RRD file&lt;/h4&gt;

&lt;p&gt;To read an entire RRD file, i.e. all of the RRA archives, use &lt;code&gt;read_rrd()&lt;/code&gt;. This returns a list of &lt;code&gt;tibble&lt;/code&gt; objects:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;cpu &amp;lt;- read_rrd(rrd_cpu_0)

str(cpu, max.level = 1)
#&amp;gt; List of 10
#&amp;gt;  $ AVERAGE60   :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    43199 obs. of  9 variables:
#&amp;gt;  $ AVERAGE300  :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    25919 obs. of  9 variables:
#&amp;gt;  $ MIN300      :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    25919 obs. of  9 variables:
#&amp;gt;  $ MAX300      :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    25919 obs. of  9 variables:
#&amp;gt;  $ AVERAGE3600 :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    8759 obs. of  9 variables:
#&amp;gt;  $ MIN3600     :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    8759 obs. of  9 variables:
#&amp;gt;  $ MAX3600     :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    8759 obs. of  9 variables:
#&amp;gt;  $ AVERAGE86400:Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    1824 obs. of  9 variables:
#&amp;gt;  $ MIN86400    :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    1824 obs. of  9 variables:
#&amp;gt;  $ MAX86400    :Classes &#39;tbl_df&#39;, &#39;tbl&#39; and &#39;data.frame&#39;:    1824 obs. of  9 variables:
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since the resulting object is a list of &lt;code&gt;tibble&lt;/code&gt; objects, you can easily use R functions to work with an individual archive:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;names(cpu)
#&amp;gt;  [1] &amp;quot;AVERAGE60&amp;quot;    &amp;quot;AVERAGE300&amp;quot;   &amp;quot;MIN300&amp;quot;       &amp;quot;MAX300&amp;quot;      
#&amp;gt;  [5] &amp;quot;AVERAGE3600&amp;quot;  &amp;quot;MIN3600&amp;quot;      &amp;quot;MAX3600&amp;quot;      &amp;quot;AVERAGE86400&amp;quot;
#&amp;gt;  [9] &amp;quot;MIN86400&amp;quot;     &amp;quot;MAX86400&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To inspect the contents of the first archive (&lt;code&gt;AVERAGE60&lt;/code&gt;), simply print the object - since it&amp;rsquo;s a &lt;code&gt;tibble&lt;/code&gt;, you get 10 lines of output.&lt;/p&gt;

&lt;p&gt;For example, the CPU metrics contains a time stamp and metrics for average &lt;em&gt;user&lt;/em&gt; and &lt;em&gt;sys&lt;/em&gt; usage, as well as the &lt;a href=&#34;https://en.wikipedia.org/wiki/Nice_(Unix)&#34;&gt;&lt;em&gt;nice&lt;/em&gt;&lt;/a&gt; value, &lt;em&gt;idle&lt;/em&gt; time, &lt;a href=&#34;https://en.wikipedia.org/wiki/Interrupt_request_(PC_architecture)&#34;&gt;&lt;em&gt;interrupt requests&lt;/em&gt;&lt;/a&gt; and &lt;em&gt;soft interrupt requests&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;cpu[[1]]
#&amp;gt; # A tibble: 43,199 x 9
#&amp;gt;    timestamp              user     sys  nice  idle  wait   irq softirq
#&amp;gt;  * &amp;lt;dttm&amp;gt;                &amp;lt;dbl&amp;gt;   &amp;lt;dbl&amp;gt; &amp;lt;dbl&amp;gt; &amp;lt;dbl&amp;gt; &amp;lt;dbl&amp;gt; &amp;lt;dbl&amp;gt;   &amp;lt;dbl&amp;gt;
#&amp;gt;  1 2018-04-02 12:24:00 0.0104  0.00811     0 0.981     0     0       0
#&amp;gt;  2 2018-04-02 12:25:00 0.0126  0.00630     0 0.979     0     0       0
#&amp;gt;  3 2018-04-02 12:26:00 0.0159  0.00808     0 0.976     0     0       0
#&amp;gt;  4 2018-04-02 12:27:00 0.00853 0.00647     0 0.985     0     0       0
#&amp;gt;  5 2018-04-02 12:28:00 0.0122  0.00999     0 0.978     0     0       0
#&amp;gt;  6 2018-04-02 12:29:00 0.0106  0.00604     0 0.983     0     0       0
#&amp;gt;  7 2018-04-02 12:30:00 0.0147  0.00427     0 0.981     0     0       0
#&amp;gt;  8 2018-04-02 12:31:00 0.0193  0.00767     0 0.971     0     0       0
#&amp;gt;  9 2018-04-02 12:32:00 0.0300  0.0274      0 0.943     0     0       0
#&amp;gt; 10 2018-04-02 12:33:00 0.0162  0.00617     0 0.978     0     0       0
#&amp;gt; # ... with 43,189 more rows, and 1 more variable: stolen &amp;lt;dbl&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since the data is in &lt;code&gt;tibble&lt;/code&gt; format, you can easily extract specific data, e.g., the last values of the system usage:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;
tail(cpu$AVERAGE60$sys)
#&amp;gt; [1] 0.0014390667 0.0020080000 0.0005689333 0.0000000000 0.0014390667
#&amp;gt; [6] 0.0005689333
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;reading-only-a-single-archive&#34;&gt;Reading only a single archive&lt;/h4&gt;

&lt;p&gt;The underlying code in the &lt;code&gt;rrd&lt;/code&gt; package is written in C, and is therefore blazingly fast. Reading an entire RRD file takes a fraction of a second, but sometimes you may want to extract a specific RRA archive immediately.&lt;/p&gt;

&lt;p&gt;To read a single RRA archive from an RRD file, use &lt;code&gt;read_rra()&lt;/code&gt;. To use this function, you must specify several arguments that define the specific data to retrieve. This includes the consolidation function (e.g., &lt;code&gt;&amp;quot;AVERAGE&amp;quot;&lt;/code&gt;) and time step (e.g., &lt;code&gt;60&lt;/code&gt;). You must also specify either the &lt;code&gt;start&lt;/code&gt; time or the number of steps, &lt;code&gt;n_steps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this example, I extract the average for one-minute periods (&lt;code&gt;step = 60&lt;/code&gt;) for one day (&lt;code&gt;n_steps = 24 * 60&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;end_time &amp;lt;- as.POSIXct(&amp;quot;2018-05-02&amp;quot;) # timestamp with data in example
avg_60 &amp;lt;- read_rra(rrd_cpu_0, cf = &amp;quot;AVERAGE&amp;quot;, step = 60, n_steps = 24 * 60,
                     end = end_time)

avg_60
#&amp;gt; # A tibble: 1,440 x 9
#&amp;gt;    timestamp              user      sys  nice  idle     wait   irq softirq
#&amp;gt;  * &amp;lt;dttm&amp;gt;                &amp;lt;dbl&amp;gt;    &amp;lt;dbl&amp;gt; &amp;lt;dbl&amp;gt; &amp;lt;dbl&amp;gt;    &amp;lt;dbl&amp;gt; &amp;lt;dbl&amp;gt;   &amp;lt;dbl&amp;gt;
#&amp;gt;  1 2018-05-01 00:01:00 0.00458 0.00201      0 0.992 0            0       0
#&amp;gt;  2 2018-05-01 00:02:00 0.00258 0.000570     0 0.996 0            0       0
#&amp;gt;  3 2018-05-01 00:03:00 0.00633 0.00144      0 0.992 0            0       0
#&amp;gt;  4 2018-05-01 00:04:00 0.00515 0.00201      0 0.991 0            0       0
#&amp;gt;  5 2018-05-01 00:05:00 0.00402 0.000569     0 0.995 0            0       0
#&amp;gt;  6 2018-05-01 00:06:00 0.00689 0.00144      0 0.992 0            0       0
#&amp;gt;  7 2018-05-01 00:07:00 0.00371 0.00201      0 0.993 0.00144      0       0
#&amp;gt;  8 2018-05-01 00:08:00 0.00488 0.00201      0 0.993 0.000569     0       0
#&amp;gt;  9 2018-05-01 00:09:00 0.00748 0.000568     0 0.992 0            0       0
#&amp;gt; 10 2018-05-01 00:10:00 0.00516 0            0 0.995 0            0       0
#&amp;gt; # ... with 1,430 more rows, and 1 more variable: stolen &amp;lt;dbl&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;plotting-the-results&#34;&gt;Plotting the results&lt;/h4&gt;

&lt;p&gt;The original &lt;code&gt;RRDTool&lt;/code&gt; library for Linux contains some functions to &lt;a href=&#34;https://oss.oetiker.ch/rrdtool/gallery/index.en.html&#34;&gt;easily plot&lt;/a&gt; the RRD data, a feature that distinguishes RRD from many other databases.&lt;/p&gt;

&lt;p&gt;However, R already has very rich plotting capability, so the &lt;code&gt;rrd&lt;/code&gt; R package doesn&amp;rsquo;t expose any specific plotting functions.&lt;/p&gt;

&lt;p&gt;For example, you can easily plot these data using your favourite packages, like &lt;code&gt;ggplot2&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;library(ggplot2)
ggplot(avg_60, aes(x = timestamp, y = user)) + 
  geom_line() +
  stat_smooth(method = &amp;quot;loess&amp;quot;, span = 0.125, se = FALSE) +
  ggtitle(&amp;quot;CPU0 usage, data read from RRD file&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;/post/2018-06-21-analysing-rrd-files_files/ggplot.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;h2 id=&#34;getting-the-rrd-files-from-rstudio-server-pro-and-rstudio-connect&#34;&gt;Getting the RRD files from RStudio Server Pro and RStudio Connect&lt;/h2&gt;

&lt;p&gt;As I mentioned in the introduction, both &lt;a href=&#34;https://www.rstudio.com/products/rstudio-server-pro/&#34;&gt;RStudio Server Pro&lt;/a&gt; and &lt;a href=&#34;https://www.rstudio.com/products/connect/&#34;&gt;RStudio Connect&lt;/a&gt; use RRD to store metrics. In fact, these metrics are used to power the administration dashboard of these products.&lt;/p&gt;

&lt;p&gt;This means that often the easiest solution is simply to enable the admin dashboard and view the information there.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/post/2018-06-21-analysing-rrd-files_files/rsp_admin_dashboard.png&#34; alt=&#34;RStudio Server Pro admin dashboard&#34; /&gt;&lt;/p&gt;

&lt;p&gt;However, sometimes R users and system administrators have a need to analyze the metrics in more detail, so in this section, I discuss where you can find the files for analysis.&lt;/p&gt;

&lt;p&gt;The administration guides for these products explain where to find the metrics files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The admin guide for &lt;strong&gt;RStudio Server Pro&lt;/strong&gt; discusses metrics in this in section &lt;a href=&#34;http://docs.rstudio.com/ide/server-pro/auditing-and-monitoring.html#monitoring-configuration&#34;&gt;8.2 Monitoring Configuration&lt;/a&gt;.

&lt;ul&gt;
&lt;li&gt;By default, the metrics are stored at &lt;code&gt;/var/lib/rstudio-server/monitor/rrd&lt;/code&gt;, although this path is configurable by the server administrator&lt;/li&gt;
&lt;li&gt;RStudio Server Pro stores system metrics as well as user metrics&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RStudio Connect&lt;/strong&gt; discusses metrics in section &lt;a href=&#34;http://docs.rstudio.com/connect/admin/historical-information.html#metrics&#34;&gt;16.1 Historical Metrics&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;The default path for metrics logs is &lt;code&gt;/var/lib/rstudio-connect/metrics&lt;/code&gt;, though again, this is configurable by the server administrator.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;rsc &amp;lt;- &amp;quot;/var/lib/rstudio-connect/metrics/rrd&amp;quot;
rsp &amp;lt;- &amp;quot;/var/lib/rstudio-server/monitor/rrd&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you want to analyze these files, it is best to copy the files to a different location.  The security and permissions on both products are configured in such a way that it&amp;rsquo;s not possible to read the files while they are in the original folder. Therefore, we recommend that you copy the files to a different location and do the analysis there.&lt;/p&gt;

&lt;h3 id=&#34;warning-about-using-the-rstudio-connect-rrd-files&#34;&gt;Warning about using the RStudio Connect RRD files:&lt;/h3&gt;

&lt;p&gt;The RStudio Connect team is actively planning to change the way content-level metrics are stored, so data related to shiny apps, markdown reports, etc. will likely look different in a future release.&lt;/p&gt;

&lt;p&gt;To be clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The schemas might change&lt;/li&gt;
&lt;li&gt;RStudio Connect may stop tracking some metrics&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s also possible that the entire mechanism might change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The only guarantees that we make in RStudio Connect are around the data that we actually surface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;server-wide user counts&lt;/li&gt;
&lt;li&gt;RAM&lt;/li&gt;
&lt;li&gt;CPU data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means that if you analyze RRD files, you should be aware that &lt;strong&gt;the entire mechanism for storing metrics might change in future&lt;/strong&gt;.&lt;/p&gt;

&lt;h3 id=&#34;additional-caveat&#34;&gt;Additional caveat&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The metrics collection process runs in a sandboxed environment, and it is not possible to publish a report to RStudio Connect that reads the metrics directly. If you want to automate a process to read the Connect metrics, you will have to set up a &lt;a href=&#34;https://en.wikipedia.org/wiki/Cron&#34;&gt;cron&lt;/a&gt; job to copy the files to a different location, and run the analysis against the copied files. (Also, re-read the warning that everything might change!)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;example&#34;&gt;Example&lt;/h3&gt;

&lt;p&gt;In the following worked example, I copied some &lt;code&gt;rrd&lt;/code&gt; files that originated in RStudio Connect to a different location on disk, and stored this in a &lt;a href=&#34;https://github.com/rstudio/config&#34;&gt;&lt;code&gt;config&lt;/code&gt;&lt;/a&gt; file.&lt;/p&gt;

&lt;p&gt;First, list the file names:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;config &amp;lt;- config::get()
rrd_location &amp;lt;- config$rrd_location
rrd_location %&amp;gt;% 
  list.files() %&amp;gt;% 
  tail(20)
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;##  [1] &amp;quot;content-978.rrd&amp;quot;      &amp;quot;content-986.rrd&amp;quot;      &amp;quot;content-98.rrd&amp;quot;      
##  [4] &amp;quot;content-990.rrd&amp;quot;      &amp;quot;content-995.rrd&amp;quot;      &amp;quot;content-998.rrd&amp;quot;     
##  [7] &amp;quot;cpu-0.rrd&amp;quot;            &amp;quot;cpu-1.rrd&amp;quot;            &amp;quot;cpu-2.rrd&amp;quot;           
## [10] &amp;quot;cpu-3.rrd&amp;quot;            &amp;quot;license-users.rrd&amp;quot;    &amp;quot;network-eth0.rrd&amp;quot;    
## [13] &amp;quot;network-lo.rrd&amp;quot;       &amp;quot;system-CPU.rrd&amp;quot;       &amp;quot;system.cpu.usage.rrd&amp;quot;
## [16] &amp;quot;system.load.rrd&amp;quot;      &amp;quot;system.memory.rrd&amp;quot;    &amp;quot;system-RAM.rrd&amp;quot;      
## [19] &amp;quot;system.swap.rrd&amp;quot;      &amp;quot;system-SWAP.rrd&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The file names indicated that RStudio Connect collects metrics for the system (CPU, RAM, etc.), as well as for every piece of published content.&lt;/p&gt;

&lt;p&gt;To look at the system load, first describe the contents of the &lt;code&gt;&amp;quot;system.load.rrd&amp;quot;&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;sys_load &amp;lt;- file.path(rrd_location, &amp;quot;system.load.rrd&amp;quot;)
describe_rrd(sys_load)
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;## A RRD file with 10 RRA arrays and step size 60
## [1] AVERAGE_60 (43200 rows)
## [2] AVERAGE_300 (25920 rows)
## [3] MIN_300 (25920 rows)
## [4] MAX_300 (25920 rows)
## [5] AVERAGE_3600 (8760 rows)
## [6] MIN_3600 (8760 rows)
## [7] MAX_3600 (8760 rows)
## [8] AVERAGE_86400 (1825 rows)
## [9] MIN_86400 (1825 rows)
## [10] MAX_86400 (1825 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This output tells you that metrics are collected every 60 seconds (one minute), and then in selected multiples (1 minute, 5 minutes, 1 hour and 1 day.) You can also tell that the consolidation functions are &lt;code&gt;average&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To extract one month of data, averaged at 5-minute intervals use &lt;code&gt;step = 300&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;dat &amp;lt;- read_rra(sys_load, cf = &amp;quot;AVERAGE&amp;quot;, step = 300L, n_steps = (3600 / 300) * 24 * 30)
dat
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;## # A tibble: 8,640 x 4
##    timestamp            `1min` `5min` `15min`
##  * &amp;lt;dttm&amp;gt;                &amp;lt;dbl&amp;gt;  &amp;lt;dbl&amp;gt;   &amp;lt;dbl&amp;gt;
##  1 2018-05-10 19:10:00 0.0254  0.0214  0.05  
##  2 2018-05-10 19:15:00 0.263   0.153   0.0920
##  3 2018-05-10 19:20:00 0.0510  0.117   0.101 
##  4 2018-05-10 19:25:00 0.00137 0.0509  0.0781
##  5 2018-05-10 19:30:00 0       0.0168  0.0534
##  6 2018-05-10 19:35:00 0       0.01    0.05  
##  7 2018-05-10 19:40:00 0.0146  0.0166  0.05  
##  8 2018-05-10 19:45:00 0.00147 0.0115  0.05  
##  9 2018-05-10 19:50:00 0.0381  0.0306  0.05  
## 10 2018-05-10 19:55:00 0.0105  0.018   0.05  
## # ... with 8,630 more rows
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is very easy to plot this using your preferred plotting package, e.g., &lt;code&gt;ggplot2&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-r&#34;&gt;ggplot(dat, aes(x = timestamp, y = `5min`)) + 
  geom_line() + 
  stat_smooth(method = &amp;quot;loess&amp;quot;, span = 0.125)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src=&#34;/post/2018-06-21-analysing-rrd-files_files/ggplot.png&#34; alt=&#34;&#34; /&gt;&lt;/p&gt;

&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;rrd&lt;/code&gt; package, available from &lt;a href=&#34;https://github.com/andrie/rrd&#34;&gt;GitHub&lt;/a&gt;, makes it very easy to read metrics stored in the RRD database format. Reading an archive is very quick, and your resulting data is a &lt;code&gt;tibble&lt;/code&gt; for an individual archive, or a list of &lt;code&gt;tibble&lt;/code&gt;s for the entire file.&lt;/p&gt;

&lt;p&gt;This makes it easy to analyze your data using the &lt;code&gt;tidyverse&lt;/code&gt; packages, and to plot the information.&lt;/p&gt;

        &lt;script&gt;window.location.href=&#39;https://rviews.rstudio.com/2018/06/20/reading-rrd-files/&#39;;&lt;/script&gt;
      </description>
    </item>
    
  </channel>
</rss>
