You are currently browsing winstonchang’s articles.
If there’s one word that could describe the default styling of Shiny applications, it might be “minimalist.” Shiny’s UI components are built using the Bootstrap web framework, and unless the appearance is customized, the application will be mostly white and light gray.
Fortunately, it’s easy to add a bit of flavor to your Shiny application, with the shinythemes package. We’ve just released version 1.1.1 of shinythemes, which includes many new themes from bootswatch.com, as well as a theme selector which you can use to test out different themes on a live Shiny application.
Here’s an example of the theme selector in use (try out the app here):
To install the latest version of shinythemes, run:
To use the theme selector, all you need to do is add this somewhere in your app’s UI code:
Once you’ve chosen which theme you want, all you need to do is use the
theme argument of the
fixedPage functions. If you want to use “cerulean”, you would do this:
fluidPage(theme = shinytheme("cerulean"), ... )
To learn more and see screenshots of the different themes, visit the shinythemes web page. Enjoy!
A new Shiny release is upon us! There are many new exciting features, bug fixes, and library updates. We’ll just highlight the most important changes here, but you can browse through the full changelog for details. This will likely be the last release before shiny 1.0, so get out your party hats!
To install it, you can just run:
Shiny now supports bookmarkable state: users can save the state of an application and get a URL which will restore the application with that state. There are two types of bookmarking: encoding the state in a URL, and saving the state to the server. With an encoded state, the entire state of the application is contained in the URL’s query string. You can see this in action with this app: https://gallery.shinyapps.io/113-bookmarking-url/. An example of a bookmark URL for this app is https://gallery.shinyapps.io/113-bookmarking-url/?inputs&n=200. When the state is saved to the server, the URL might look something like: https://gallery.shinyapps.io/bookmark-saved/?state_id=d80625dc681e913a (note that this URL is not for an active app).
Important note: Saved-to-server bookmarking currently works with Shiny Server Open Source. Support on Shiny Server Pro, RStudio Connect, and shinyapps.io is under development and testing. However, URL-encoded bookmarking works on all hosting platforms.
Shiny can now display notifications on the client browser by using the
showNotification() function. Use this demo app to play around with the notification API. For more, see our article about notifications.
If your Shiny app contains computations that take a long time to complete, a progress bar can improve the user experience by communicating how far along the computation is, and how much is left. Progress bars were added in Shiny 0.10.2. In Shiny 0.14, we’ve changed them to use the notifications system, which gives them a different look.
Important note: If you were already using progress bars and had customized them with your own CSS, you can add the
style = "old" argument to your
withProgress() call (or
Progress$new()). This will result in the same appearance as before. You can also call
shinyOptions(progress.style = "old") in your app’s server function to make all progress indicators use the old styling.
Shiny has now built-in support for displaying modal dialogs like the one below (live app here):
To learn more about modal dialogs in Shiny, read the article about them.
Sometimes in a Shiny app, arbitrary HTML UI may need to be created on-the-fly in response to user input. The existing
renderUI functions let you continue using reactive logic to call UI functions and make the results appear in a predetermined place in the UI. The
removeUI functions, which are used in the server code, allow you to use imperative logic to add and remove arbitrary chunks of HTML (all independent from one another), as many times as you want, whenever you want, wherever you want. This option may be more convenient when you want to, for example, add a new model to your app each time the user selects a different option (and leave previous models unchanged, rather than substitute the previous one for the latest one).
See this simple demo app of how one could use
removeUI to insert and remove text elements using a queue. Also see this other app that demonstrates how to insert and remove a few common Shiny input objects. Finally, this app shows how to dynamically insert modules using
Documentation for connecting to an external database
Many Shiny users have asked about best practices for accessing external databases from their Shiny applications. Although database access has long been possible using various database connector packages in R, it can be challenging to use them robustly in the dynamic environment that Shiny provides. So far, it has been mostly up to application authors to find the appropriate database drivers and to discover how to manage the database connections within an application. In order to demystify this process, we wrote a series of articles (first one here) that covers the basics of connecting to an external database, as well as some security precautions to keep in mind (e.g. how to avoid SQL injection attacks).
There are a few packages that you should look at if you’re using a relational database in a Shiny app: the
DBI packages (both featured in the article linked to above), and the brand new
pool package, which provides a further layer of abstraction to make it easier and safer to use either
pool is not yet on CRAN. In particular,
pool will take care of managing connections, preventing memory leaks, and ensuring the best performance. See this
pool basics article and the more advanced-level article if you’re feeling adventurous! (Both of these articles contain Shiny app examples that use
DBI to connect to an external MySQL database.) If you are more comfortable with
DBI, don’t miss the article about the integration of
If you’re new to databases in the Shiny world, we recommend using
pool if possible. If you need greater control than
dplyr offers (for example, if you need to modify data in the database or use transactions), then use
pool package was introduced to make your life easier, but in no way constrains you, so we don’t envision any situation in which you’d be better off not using it. The only caveat is that
pool is not yet on CRAN, so you may prefer to wait for that.
There are many more minor features, small improvements, and bug fixes than we can cover here, so we’ll just mention a few of the more noteworthy ones. (For more, you can see the full changelog.).
- Error Sanitization: you now have the option to sanitize error messages; in other words, the content of the original error message can be suppressed so that it doesn’t leak any sensitive information. To sanitize errors everywhere in your app, just add
options(shiny.sanitize.errors = TRUE)somewhere in your app. Read this article for more, or play with the demo app.
- Code Diagnostics: if there is an error parsing
global.R, Shiny will search the code for missing commas, extra commas, and unmatched braces, parens, and brackets, and will print out messages pointing out those problems. (#1126)
- Reactlog visualization: by default, the
showReactLog()function (which brings up the reactive graph) also displays the time that each reactive and observer were active for:
Additionally, to organize the graph, you can now drag any of the nodes to a specific position and leave it there.
- Nicer-looking tables: we’ve made tables generated with
renderTable()look cleaner and more modern. While this won’t break any older code, the finished look of your table will be quite a bit different, as the following image shows:
“How can I make my code faster?” If you write R code, then you’ve probably asked yourself this question. A profiler is an important tool for doing this: it records how the computer spends its time, and once you know that, you can focus on the slow parts to make them faster.
The preview releases of RStudio now have integrated support for profiling R code and for visualizing profiling data. R itself has long had a built-in profiler, and now it’s easier than ever to use the profiler and interpret the results.
To profile code with RStudio, select it in the editor, and then click on Profile -> Profile Selected Line(s). R will run that code with the profiler turned on, and then open up an interactive visualization.
In the visualization, there are two main parts: on top, there is the code with information about the amount of time spent executing each line, and on the bottom there is a flame graph, which shows R was doing over time. In the flame graph, the horizontal direction represents time, moving from left to right, and the vertical direction represents the call stack, which are the functions that are currently being called. (Each time a function calls another function, it goes on top of the stack, and when a function exits, it is removed from the stack.)
The Data tab contains a call tree, showing which function calls are most expensive:
Armed with this information, you’ll know what parts of your code to focus on to speed things up!
The interactive profile visualizations are created with the profvis package, which can be used separately from the RStudio IDE. If you use profvis outside of RStudio, the visualizations will open in a web browser.
Shiny 0.13.0 is now available on CRAN! This release has some of the most exciting features we’ve shipped since the first version of Shiny. Highlights include:
- Shiny Gadgets
- HTML templates
- Shiny modules
- Error stack traces
- Checking for missing inputs
For a comprehensive list of changes, see the NEWS file.
To install the new version from CRAN, run:
Read on for details about these new features!
Shiny version 0.11 is available now! Notable changes include:
- Shiny has migrated from Bootstrap 2 to Bootstrap 3 for its web front end. More on this below.
- The old jsliders have been replaced with ion.rangeSlider. These sliders look better, are easier for users to interact with, and support updating more fields from the server side.
- There is a new
passwordInput()which can be used to create password fields.
eventReactive()functions greatly streamline the use of
actionButtonand other inputs that act more like events than reactive inputs.
For a full set of changes, see the NEWS file. To install, run:
We’ve also posted an article with notes on upgrading to 0.11.
Bootstrap 3 migration
In all versions of Shiny prior to 0.11, Shiny has used the Bootstrap 2 framework for its web front-end. Shiny generates HTML that is structured to work with Bootstrap, and this makes it easy to create pages with sidebars, tabs, dropdown menus, mobile device support, and so on.
The Bootstrap development team stopped development on the Bootstrap 2 series after version 2.3.2, which was released over a year ago, and has since focused their efforts on Bootstrap 3. The new version of Bootstrap builds on many of the same underlying ideas, but it also has many small changes – for example, many of the CSS class names have changed.
In Shiny 0.11, we’ve moved to Bootstrap 3. For most Shiny users, the transition will be seamless; the only differences you’ll see are slight changes to fonts and spacing.
If, however, you customized any of your code to use features specific to Bootstrap 2, then you may need to update your code to work with Bootstrap 3 (see the Bootstrap migration guide for details). If you don’t want to update your code right away, you can use the shinybootstrap2 package for backward compatibility with Bootstrap 2 – using it requires adding just two lines of code. If you do use shinybootstrap2, we suggest using it just as an interim solution until you update your code for Bootstrap 3, because Shiny development going forward will use Bootstrap 3.
Why is Shiny moving to Bootstrap 3? One reason is support: as mentioned earlier, Bootstrap 2 is no longer developed and is no longer supported. Another reason is that there is dynamic community of actively-developed Bootstrap 3 themes. (Themes for Bootstrap 2 also exist, but there is less development activity.) Using these themes will allow you to customize the appearance of a Shiny app so that it doesn’t just look like… a Shiny app.
We’ve also created a package that make it easy to use Bootstrap themes: shinythemes. Here’s an example using the included Flatly theme:
See the shinythemes site for more screenshots and instructions on how to use it.
The shinydashboard package still under development, but feel free to try it out and give us feedback.
ggvis 0.4 is now available on CRAN. You can install it with:
The major features of this release are:
- Boxplots, with
chickwts %>% ggvis(~feed, ~weight) %>% layer_boxplots()
- Better stability when errors occur.
- Better handling of empty data and malformed data.
- More consistent handling of data in compute pipeline functions.
Because of these changes, interactive graphics with dynamic data sources will work more reliably.
Additionally, there are many small improvements and bug fixes under the hood. You can see the full change log here.
Our first public release of ggvis, version 0.3, is now available on CRAN. What is ggvis? It’s a new package for data visualization. Like ggplot2, it is built on concepts from the grammar of graphics, but it also adds interactivity, a new data pipeline, and it renders in a web browser. Our goal is to make an interface that’s flexible, so that you can compose new kinds of visualizations, yet simple, so that it’s accessible to all R users.
Update: there was an issue affecting interactive plots in version 0.3. Version 0.3.0.1 fixes the issue. The updated source package is now on CRAN, and Windows and Mac binary packages will be available shortly.
ggvis integrates with Shiny, so you can use dynamic, interactive ggvis graphics in Shiny applications. We hope that the combination of ggvis and Shiny will make it easy for you to create applications for interactive data exploration and presentation. ggvis plots are inherently reactive and they render in the browser, so they can take advantage of the capabilities provided by modern web browsers. You can use Shiny’s interactive components for interactivity as well as more direct forms of interaction with the plot, such as hovering, clicking, and brushing.
And don’t worry — ggvis isn’t only meant to be used with Shiny and interactive documents. Because the RStudio IDE is also a web browser, ggvis plots can display in the IDE, like any other R graphics:
There’s much more to come with ggvis. To learn more, visit the ggvis website.
Please note that ggvis is still young, and lacks a number of important features from ggplot2. But we’re working hard on ggvis and expect many improvements in the months to come.
Shiny version 0.4.0 is now available on CRAN. The most visible change is that the API has been slightly simplified. Your existing code will continue to work, although Shiny will print messages about how to migrate your code. Migration should be straightforward, as described below. It will take a bit of work to switch to the new API, but we think it’s worth it in the long run, because the new interface is somewhat simpler, and because it offers a better mapping between function names and reactive programming concepts.
We’ve also updated the Shiny tutorial to reflect the changes, and we’ve also added a some new content explaining Shiny’s reactive programming model in depth. If you want to have a better understanding of how Shiny works, see the sections under Understanding Reactivity, starting with the Reactivity Overview.
Another new feature is that Shiny now suspends outputs when they aren’t visible on the user’s web browser. For example, if your Shiny application has multiple tabs or conditional panels, Shiny will only run the calculations and send data for the currently-visible tabs and panels. This new feature will reduce network traffic and computational load on the server, resulting in a faster application.
Version 0.3.0 of Shiny is now available on CRAN. This version of Shiny has several new features and bug fixes. Some of the changes are under the hood: for example, Shiny now uses a more efficient algorithm for scheduling the execution of reactive functions. There are also some user-facing changes: for example, the new
runGitHub() function lets you download and run applications directly from a GitHub repository.
You can install the new version of Shiny with
We’re pleased to announce new versions of ggplot2 (0.9.3) and plyr (1.8). To get up and running with the new versions, start a clean R session without ggplot2 or plyr loaded, and run
install.packages(c("ggplot2", "gtable", "scales", "plyr")). Read on to find out what’s new.
Most of the changes version 0.9.3 are bug fixes. Perhaps the most visible change is that ggplot will now print out warning messages when you use
stat="bin" and also map a variable to y. For example, these are valid:
ggplot(mtcars, aes(wt, mpg)) + geom_bar(stat = "identity") ggplot(mtcars, aes(cyl)) + geom_bar(stat = "bin")
But this will result in some warnings:
ggplot(mtcars, aes(wt, mpg)) + geom_bar(stat = "bin") # The default stat for geom_bar is "bin", so this is the same as above: ggplot(mtcars, aes(wt, mpg)) + geom_bar()
The reason for this change is to make behavior more consistent –
stat_bin generates a y value, and so should not work when you also map a value to y.
For a full list of changes, please see the NEWS file.
Version 1.8 has 28 improvements and bug fixes. Among the most prominent:
- All parallel plyr functions gain a
.paroptsargument, a list of options that is passed onto
foreachwhich allows you to control parallel execution.
progress_timeis a new progress bar contributed by Mike Lawrence estimates the amount of time remaining before a job is complete
- The summarise() function now calculates columns sequentially, so you can calculate new columns from other new columns, like this:
summarise(mtcars, x = disp/10, y = x/10)
This behavior is similar to the mutate() function. Please be aware that this could change the behavior of existing code, if any columns of the output have the same name but different values as columns in the input. For example, this will result in different behavior in plyr 1.7 and 1.8:
summarise(mtcars, disp = disp/10, y = disp*10)
In the old version, the y column would equal
mtcars$disp * 10, and in the new version, it would equal
- There are a number of performance improvements:
a*plyuses more efficient indexing so should be more competitive with
idata.frameall have performance tweaks which will help a few people out a lot, and a lot of people a little.
For a full list of changes, please see the NEWS file.