R config: How to Manage Environment-Specific Configuration Files
How many times have you encountered a file path issue when running your code on a different environment? Probably far too many. It doesn't need to be the case anymore - The R config package is here to allow you to manage environment-specific configuration files. The best part? You'll learn all about it today.
In this article, we'll go through a basic introduction to R config, explain how to use different configuration environments, and also show you how to use the package in R Shiny applications. Let's get started.
<blockquote>Want to start a career as an R Shiny Developer? <a href="https://appsilon.com/how-to-start-a-career-as-an-r-shiny-developer/" target="_blank" rel="noopener">Here's our how-to guide for 2022 and beyond</a>.</blockquote>
Table of contents:
<ul><li><a href="#introduction">Introduction to R config</a></li><li><a href="#different-env">How to Change Environment for the Configuration File</a></li><li><a href="#shiny">R config in R Shiny - How to Get Started</a></li><li><a href="#summary">Summing up R config</a></li></ul>
<hr />
<h2 id="introduction">Introduction to R config</h2>
The <a href="https://cran.r-project.org/web/packages/config/vignettes/introduction.html" target="_blank" rel="nofollow noopener">config package for R</a> makes it easy for developers to manage environment-specific configuration values. That's useful when you want to use specific values for development, testing, and production environments.
For example, maybe you're reading a dataset from different locations in different environments, or storing runtime logs differently. Maybe you're developing an app on a Windows machine and deploying it to a server that runs Linux. Or perhaps you're deploying in different environments (e.g. development and production), where you'll have different credentials and ways to access data.
The reasons are long, and R config is here to save you from headaches.
To get started, you'll have to install the package. It's available on CRAN, so the installation can't be any simpler:
<pre><code class="language-r">install.packages("config")</code></pre>
R config wants to read a <code>config.yml</code> file by default. You can change that by specifying a different value to the <code>file</code> parameter, but we'll stick to the convention today.
Start by creating a <code>config.yml</code> file and specifying values for default and production environments:
<pre><code class="language-yml">default:
dataset: "/Users/dradecic/Desktop/iris.csv"
n_rows_to_print: 10
production:
dataset: "iris.csv"
n_rows_to_print: 5</code></pre>
The config file just stores a path to the <a href="https://gist.github.com/netj/8836201" target="_blank" rel="nofollow noopener">Iris dataset</a>. For demonstration purposes, let's say it's stored on the Desktop on by default, and in the same folder as <code>config.yml</code> in a production environment.
The question is, <b>how can you access this file path in R?</b>
The process can't be any simpler, just read the configuration file and access a property with R's traditional <code>$</code> notation:
<pre><code class="language-r">config <- config::get()
<br>print(config$dataset)
print(config$n_rows_to_print)</code></pre>
Here's the output:
<img class="size-full wp-image-16143" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b29f4b5d4048c02f96f0ab_1-3.webp" alt="Image 1 - Contents of the default environment" width="427" height="130" /> Image 1 - Contents of the default environment
For reference, if your config file wasn't named <code>config.yml</code>, you'd read it by running <code>config::get(file = "path/to/file")</code>.
You now know how to read a default environment, but what about others? Let's cover that next.
<h2 id="different-env">How to Change Environment for the Configuration File</h2>
The <code>R_CONFIG_ACTIVE</code> environment variable controls which environment is currently active. It's typically set either in <code>Renviron</code> or <code>Rprofile</code> file, but you can manually override it in your R script.
The best practice is to configure either of the two mentioned files on a production machine so you don't have to add anything to R scripts.
To manually set (or override) an environment variable in R, use <code>Sys.setenv()</code> function:
<pre><code class="language-r">Sys.setenv(R_CONFIG_ACTIVE = "production")
config <- config::get()
<br>print(config$dataset)
print(config$n_rows_to_print)</code></pre>
<img class="size-full wp-image-16145" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b29ff6afe4df21c48ac220_2-3.webp" alt="Image 2 - Contents of the production environment" width="490" height="155" /> Image 2 - Contents of the production environment
You can pass these configuration values straight into any R code. For example, the snippet below reads the Iris dataset and prints the head with the specified number of rows. Both are set in the configuration file:
<pre><code class="language-r">config <- config::get()
<br>df <- read.csv(config$dataset)
head(df, config$n_rows_to_print)</code></pre>
<img class="size-full wp-image-16147" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b29ff75ec24573082e9cdf_3-3.webp" alt="Image 3 - Head of the Iris dataset" width="652" height="181" /> Image 3 - Head of the Iris dataset
You now know how to use R config and how to change environments. Next, you'll learn how to use it in R Shiny.
<h2 id="shiny">R config in R Shiny - How to Get Started</h2>
Using configuration files in R shiny applications is a straightforward process, but needed for the reasons we listed earlier. You're likely to be deploying your Shiny apps to a Linux environment. It uses a different file system than, let's say, Windows, so a dedicated config file is a good way to perform <i>file path translation</i>.
There are other obvious benefits to using config files, but you get the gist.
Onto the Shiny app. We'll keep it simple - two dropdown menus allowing you to change columns for the X and Y axes of a scatter plot. The configuration file is loaded right after the library import.
Here's the full code snippet for the app:
<pre><code class="language-r">library(shiny)
library(ggplot2)
<br># Configuration
config <- config::get()
df_iris <- read.csv(config$dataset)
features_iris <- c("sepal.length", "sepal.width", "petal.length", "petal.width")
<br># Shiny app UI
ui <- fluidPage(
headerPanel("Iris dataset visualizer"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "xcol", label = "X Axis Variable", choices = features_iris, selected = features_iris[1]),
selectInput(inputId = "ycol", label = "Y Axis Variable", choices = features_iris, selected = features_iris[2])
),
mainPanel(
plotOutput("plot")
)
)
)
<br># Server logic
server <- function(input, output) {
output$plot <- renderPlot({
ggplot(df_iris, aes(x=.data[[input$xcol]], y=.data[[input$ycol]])) +
geom_point(size = 5, aes(color = variety)) +
theme(legend.position = "top")
})
}
<br>
shinyApp(ui, server)</code></pre>
Let's see it in action:
<img class="size-full wp-image-16149" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b29f0dc94ac8aeb3b36f2b_4.gif" alt="Image 4 - R Shiny app that uses the R config package" width="958" height="562" /> Image 4 - R Shiny app that uses the R config package
There's nothing special or groundbreaking about the app, but it perfectly demonstrates how to use R config in R Shiny. Let's wrap things up next.
<hr />
<h2 id="summary">Summing up R config</h2>
Long story short, configuration files make your life as a developer easier and can alleviate (some) headaches. It's a good idea to set up a configuration file at the beginning of the project, so you don't have to change a large code base at once.
Configuration files are also a lifesaver in R Shiny apps, as they tend to rely on I/O and database - and you don't want to hardcode these.
<i>What are your thoughts on R config? Is it your preferred method for managing configuration files, or do you use something else?</i> Please let us know in the comment section below. Also, feel free to move the discussion to Twitter - <a href="http://twitter.com/appsilon" target="_blank" rel="noopener">@appsilon</a>. We'd love to hear from you.
<blockquote>Did you know Shiny is also available for Python? <a href="https://appsilon.com/shiny-for-python-introduction/" target="_blank" rel="noopener">Read our first impressions and getting started guide</a>.</blockquote>