:::: MENU ::::

Learning Shiny

In the last couple of days after returning from the Joint Aquatic Sciences Meeting in Portland, I started learning Shiny. Shiny is a great R package for converting R code into interactive web pages. I’ve known about it for a while, but I hadn’t given it a go until now for various reasons not least finishing graduate school. The learning curve was a bit steep for me. My R skills are not exactly stellar to begin with and integrating the R code with a whole set of new functions specific to Shiny was a bit of a mess at first. After a day and a half of trial and error I managed to put together a working Shiny app. It is now available on my GitHub repository under the name Interactive Diatom Phylogeny.

My basic goal with this web application, aside from learning Shiny, was to make a place on the web where a diatomist — unfamiliar with phylogenetic programs — can go and look up the current best estimate of the sister species of their favourite diatom. At least as far as the available molecular data allow. Also of interest was to have a tool that can allow for quick browsing of large phylogenetic trees that are becoming common in the diatom literature. Basically, if I want to look up the topology of a particular diatom group, I have to find a good study that has included the taxa of interest or plot one of the trees we have around the lab and try to zoom-in on the desired area. Neither of these strategies are necessarily quick or effective, especially opening trees in Mesquite or FigTree just to look up one thing. This pretty much defined the basic functionality the Shiny app should have: plot a big phylogeny and provide mechanisms for sub-setting the tree based on taxa of interest. This stuff is pretty simple in R using packages like ape and phangorn and functions like plot.phylo() and getMRCA() or mrca.phylo(). The latter two functions find the most recent common ancestor of a set of taxa. Thus, all I needed to do is make the app ask the user for two taxa that will define the clade of interest. The phylogenetic code was a breeze. However, it took me a while to figure out how to make the app reactive so that 1) it will wait for the user before plotting the sub-tree, 2) it will monitor if the user wants to define a custom subset of taxa or plot some of the sub-trees that I had defined. The following code did the trick, mostly basic Shiny and lots of it from the manual:

whichLineage <- reactive({    
if (input$select1 == "Custom")
{
   if (input$get1 == 0 ) {    finalTree <- subtr[[N.tip+1]] }
   else {    
    isolate({
      finalTree <- subtr[[mrca.phylo(tr, 
        c(input$select2:input$select3))]]
           })
        }    
}    
else {
   finalTree <- switch(input$select1,
      "Raphid diatoms" = subtr[[mrca.phylo(tr, c(101:136))]],
      "Pennate diatoms" = subtr[[mrca.phylo(tr, c(75:136))]],
      "All diatoms" = subtr[[mrca.phylo(tr, c(1:136))]])
}
return(finalTree)
})

Ok, there are three “if – else” statements there. The one on the highest level is controlling if the user wants a custom tree or one of the predefined trees I incorporated. Then, if the user wants a custom tree, the app uses

reactive({}) and isolate({}) to monitor if the user has changed the input values for the species that define the sub-tree (input$select2 and input$select3). The if (input$get1 == 0 ) bit makes the app wait until the user has pressed a submit button. The next few lines are executed if the user wants one of the predefined trees rather than a custom one. Here instead of concatenating else if I used R’s switch() function which I learned by going through Shiny examples. The switch() function is reactive to the input from three options available to the user and assigns different output (sub-tree) for each input value. The plotting code, Shiny function renderPlot, waits for input from the reactive whichLineage() function and plots that custom or predefined tree.

output$Tree <- renderPlot({
 plot(ladderize(whichLineage()),
     label.offset=0.001,
     cex=0.8,
     no.margin=TRUE,
     edge.width=2,
     edge.color="darkblue",
     tip.color="darkred")
})

Currenty, the only way to run the “diatom phylogeny browser” is from within R. I hope to find a place to host it online removing the reliance on R. For now, assuming the

ape, phangorn and shiny libraries are intalled and loaded all we need to do is:

shiny::runGitHub('InteractiveDiatomPhylogeny', 'teofiln')

It is really cool how these thirty-ish lines of code produce a decent functionality on the web. Neat stuff.


Comments are closed.