<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/interactive-graphics-with-r-shiny/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://www.theusrus.de/blog/interactive-graphics-with-r-shiny/"> R – Statistical Graphics and more</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Well, R is definitively here to stay and made its way into the data science tool zoo. For me as a statistician, I often feel alienated surrounded by these animals, but R is still also the statistician’s tool of choice (yes, it has come to age, but where are the predators ..?)</p>
<p>What was usually a big problem for us statistician, was to get our methods and models out to our customers, who (usually) don’t speak R. At this point Shiny comes in handy and offers a whole suite of bread and butter interface widgets, which can be deployed to web-pages and wired to R functions via all kinds of callback-routines.</p>
<p>A typical <a rel="nofollow" href="http://shiny.rstudio.com/gallery/kmeans-example.html" target="_blank">example</a> (sorry for the data set) looks like this:</p>
<p><iframe width="450" src="https://gallery.shinyapps.io/050-kmeans-example"></iframe></p>
<p>(Please use this example in class to demonstrate how limited k-means is!)</p>
<p>Hey, this is already pretty interactive for what we know from R and all without messing around with <a rel="nofollow" href="https://www.tcl.tk/" target="_blank">Tcl/Tk</a> or other hard to manage and hard to port UI builders. But what struck me was to try out and see what can actually be done with “real” interactive graphics as we know from e.g. <a rel="nofollow" href="http://www.theusrus.de/Mondrian/" target="_blank">Mondrian</a> and in some parts from <a rel="nofollow" href="https://www.tableau.com/" target="_blank">Tableau</a>.</p>
<p>Here is what I came up with (same data for better recognition ;-):</p>
<p><iframe width="450" src="https://theusrus.shinyapps.io/shiny-interactive-graphics/"></iframe></p>
<p>The whole magic is done with these lines of code:</p>
<pre>library(MASS)

options(shiny.sanitize.errors = FALSE)

options(shiny.fullstacktrace = TRUE)

ui &lt;- fluidPage(title=&quot;Shiny Linking Demo&quot;,
                fluidRow(
                  column(5,
                         plotOutput(&quot;plot1&quot;,
                                    click = &quot;plot_click&quot;,
                                    brush = brushOpts(&quot;plot_brush&quot;),
                                    width = 500,
                                    height = 500
                         )),
                  column(5,
                         plotOutput(&quot;plot2&quot;,
                                    click = &quot;plot2_click&quot;,
                                    width = 500,
                                    height = 500
                         ))),
                fluidRow(
                  column(5,
                         plotOutput(&quot;plot3&quot;,
                                    click = &quot;plot3_click&quot;,
                                    brush = brushOpts(&quot;plot3_brush&quot;),
                                    width = 600,
                                    height = 400
                         ))
                )
            )

server &lt;- function(input, output, session) {
  keep &lt;- rep(FALSE, 150)
  shift &lt;- FALSE
  old_brush &lt;- -9999
  var&lt;- 1
  
  keeprows &lt;- reactive({
    keepN &lt;- keep
    if (!is.null(input$plot_click$x) |  !is.null(input$plot3_click$x))
      keepN &lt;- rep(FALSE, 150)
    if (!is.null(input$plot_brush$xmin) ) {
      if( old_brush != input$plot_brush$xmin ) {
        keepN &lt;- brushedPoints(iris, input$plot_brush,
                               xvar = &quot;Sepal.Length&quot;,
                               yvar = &quot;Sepal.Width&quot;,
                               allRows = TRUE)$selected_
        old_brush &lt;- input$plot_brush$xmin
      }
    }
    if (!is.null(input$plot2_click$x) ) {
      keepN &lt;- pmax(1,pmin(3,round(input$plot2_click$x))) == as.numeric(iris$Species)
      session$resetBrush(&quot;plot_brush&quot;)
      session$resetBrush(&quot;plot3_brush&quot;)
    }
    if (!is.null(input$plot3_brush$xmin) ) {
      if( old_brush != input$plot3_brush$xmin ) {
        var &lt;- round((input$plot3_brush$xmin + input$plot3_brush$xmax) / 2 )
        coor_min &lt;- min(iris[,var]) + input$plot3_brush$ymin * diff(range(iris[,var]))
        coor_max &lt;- min(iris[,var]) + input$plot3_brush$ymax * diff(range(iris[,var]))
        keepN &lt;- iris[, var] >= coor_min &amp; iris[, var] &lt;= coor_max
        old_brush &lt;- input$plot3_brush$xmin
      }
    }
    if( is.null(input$key) )
      keep &lt;- keepN
    else {
      if( input$key )
        keep &lt;- keepN | keep
      else
        keep &lt;- keepN
    }
    return(keep)
  })
  
  output$plot1 &lt;- renderPlot({
    plot(iris$Sepal.Length, iris$Sepal.Width, main=&quot;Drag to select points&quot;)
    points(iris$Sepal.Length[keeprows()],
           iris$Sepal.Width[keeprows()], col=2, pch=16)
  })
  output$plot2 &lt;- renderPlot({
    barplot(table(iris$Species), main=&quot;Click to select classes&quot;)
    barplot(table(iris$Species[keeprows()]), add=T, col=2)
  })
  output$plot3 &lt;- renderPlot({
    parcoord(iris[,-5], col=keeprows() + 1, lwd=keeprows() + 1)
  })
}

shinyApp(ui, server)
</pre>
<p>What makes this example somewhat special is:</p>
<ul>
<li>It does not need too much code</li>
<li>It is relatively general, i.e. other plots may be added</li>
<li>It uses traditional R graphics off the shelf</li>
<li>It is not too slow</li>
</ul>
<p>Of course it is a hack! But it proves that Shiny is capable to do interactive statistical graphics to some degree.</p>
<p>Something the developer of Shiny actually do <a rel="nofollow" href="https://www.rstudio.com/resources/webinars/interactive-graphics-with-shiny/" target="_blank">think about</a>.</p>
<p> <img width="1" src="http://www.theusrus.de/blog/?feed-stats-post-id=2149" height="1"></p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://www.theusrus.de/blog/interactive-graphics-with-r-shiny/"> R – Statistical Graphics and more</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/QBeYjENv0cA" height="1"></a></div>