```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

##

```{r sample_app, echo=FALSE}


titlePanel("My first app")
  
sidebarLayout(
  sidebarPanel("App input control panel",
               selectInput("x_select", label = h3("Select x-axis"), 
                           choices = list("Sample 1" = "sample1", 
                                          "Sample 2" = "sample2", 
                                          "Sample 3" = "sample3",
                                          "Sample 4" = "sample4",
                                          "Sample 5" = "sample5",
                                          "Sample 6" = "sample6"), 
                           selected = "sample1"),
               selectInput("y_select", label = h3("Select y-axis"), 
                           choices = list("Sample 1" = "sample1", 
                                          "Sample 2" = "sample2", 
                                          "Sample 3" = "sample3",
                                          "Sample 4" = "sample4",
                                          "Sample 5" = "sample5",
                                          "Sample 6" = "sample6"), 
                           selected = "sample2")
  ),
  mainPanel("App output panel",
            plotOutput("my_plot", width = 600, height = 600)
  )
)

output$my_plot <- renderPlot({
    dat <- read.csv("r-more-files/shiny_sample_data.csv", row.names = 1)
    x_ax <- dat[,input$x_select]
    y_ax <- dat[,input$y_select]
    
    plot(x = x_ax, y = y_ax, xlab = input$x_select, ylab = input$y_select)
  })

```

This is the Shiny app we will be building today. It is quite simple, it takes a csv file containing data for 6 samples and the raw counts for 1000 genes. One sample will be plotted on the x-axis and another sample on the y-axis. 

```{r head_data, echo=FALSE}
  dat <- read.csv("r-more-files/shiny_sample_data.csv", row.names = 1)
  head(dat, 10)
```
*Top ten rows of the raw data used to build the shiny app*

## Setting up a shiny app

From the console, install and load Shiny.

```{r, eval=FALSE}
install.packages("shiny")
```

```{r, eval=FALSE}
library(shiny)
```

Firstly, in RStudio create a folder called `ShinyApps`. Make sure you spell the folder name correctly! This directory should created in your home directory. In the files pane, click `Home`, then click `New Folder` and enter in `ShinyApps` as the folder name.

Create a sub-directory in `ShinyApps` called `demo`.

Then, create one blank R script (Click `File` > `New File` > `R Script`). Save it inside the `demo` folder with the name `app.R`. 

Now we're going to create a blank app, to show what is the bare minimum to create a Shiny app. In app.R, type:

```{r, eval = FALSE}

library(shiny)

ui <- fluidPage(
  
)

server <- function(input, output) {
  
}

shinyApp(ui = ui, server = server)

```


This will always be the starting point of a Shiny app, generally everything that will go into the app will end up between the brackets and curly braces of the ui and server objects.

As soon as you saved the file as app.R, a new button appeared in RStudio called `RunApp`. Click the `Run App` button or type `runApp()` on the console. Or copy the code and paste it directly in the console - this will work too. A blank window should open up, congratulations - you've put together the most basic elements of a Shiny app!

Update the ui object to display some text:

```{r, eval = FALSE}

ui <- fluidPage(
  "Hello world"
)

```

Run the app again and have a look at what you get - there should now be some text in the app window.

## Building the UI layout

The ui object controls the appeance of the app. There are a number of layouts and widgets that an app can have. For this tutorial, we will use a title panel with a sidebar layout underneath. This is a common layout for Shiny apps. The sidebar layout will give the app two panels, a sidebar and a main panel. To look up more layouts, check the [Shiny gallery.](http://shiny.rstudio.com/gallery/)

Update the ui object to:
```{r, eval = FALSE}

ui <- fluidPage(
  titlePanel("My first app"),
  
  sidebarLayout(
    sidebarPanel("This is a sidebar panel"),
    mainPanel("And this is the main panel")
  )
)

```
Then run app.

You should be able to make out the layout of the app now. The top of the window is where the title panel is located and beneath it are two panels, laid out with the sidebar to the left and the larger main panel to the right. 

The sidebar can be moved to the right by adding the position argument to `sidebarLayout`:

```{r, eval=FALSE}
sidebarLayout(position = "right",
              sidebarPanel( "This is a sidebar panel on the right"),
              mainPanel("And this is the main panel")
)
```


#### Using widgets

We are going to add two widgets to the ui. These will control which samples gets plotted to the x and y axis of the plot and will be located in the sidebar panel. We will use `selectInput` to create these widgets but these could easily be swapped out for other widgets such radiobuttons. To see what widgets are available, look at the [Shiny widget gallery.](http://shiny.rstudio.com/gallery/widget-gallery.html) or consult the [Shiny cheatsheet](http://shiny.rstudio.com/images/shiny-cheatsheet.pdf).

To start off with, let's add just one widget to the sidebar. 
```{r, eval = FALSE}

ui <- fluidPage(
  titlePanel("My first app"),
  
  sidebarLayout(
    sidebarPanel("This is a sidebar panel",
                 selectInput(inputId = "x_select", label = "Select x-axis", 
                             choices = list("sample1", 
                                            "sample2", 
                                            "sample3",
                                            "sample4",
                                            "sample5",
                                            "sample6"), 
                             selected = "sample1")
    ),
    mainPanel("And this is the main panel")
  )
)

```

This is where Shiny starts to get a little tricky, a lot of ui code will be end up being nested in more code. So far, we have the `selectInput` widget nested inside `sidebarPanel` nested inside `siderbarLayout` **which is nested in** `fluidPage`. So we've stuck a function inside a function inside a function inside a function. Phew, that's a lot to keep track of! Many common problems that'll prevent a shiny app from running simply come from just putting a comma or a bracket in the wrong place. 

>We cannot emphasis this point enough - **keeping track of opening and closing brackets and your commas is a good skill to cultivate when building Shiny apps!** One quick way to check on your brackets is to move the cursor next to a bracket - in RStudio - that will highlight the other bracket paired with if (if one exists, that is!).
>
>![](https://github.com/MonashBioinformaticsPlatform/r-more/blob/gh-pages/figures/full_brackets.png?raw=true)
>
>*Fig 1. The cursor is placed next the opening bracket for `mainPanel` and the closing bracket is highlighted.*
>
>
>![](https://github.com/MonashBioinformaticsPlatform/r-more/blob/gh-pages/figures/missing_bracket.png?raw=true)
>
>*Fig 2. Here, though the cursor is in the same place but the original closing bracket to `mainPanel` is missing. The next closing bracket is used by `mainPanel` instead, which now means `sidebarLayout` does not have a closing bracket. The app would not work in this situation.*


Moving back to our ui, let's break down the `selectInput` function. `inputId` is the name of widget, in this case `x_select` is the name that'll be used in the server object to access the current value of the widget. The `labels` argument takes a string that will be used to label above the widget. 

`choices` takes a list of values and can be a bit confusing to understand. For simplicity's sake, we have given an unnamed list, which will directly display the values themselves. `"sample1"` happens to be a column name in the data the app will be using, so this widget can be used to select which column gets plotted. However, if the names of the choices needs to be different from the values, a named list can be used. 

For example:
```{r, eval = F}
choices = list("Sample 1" = "sample1", 
               "Sample 2" = "sample2", 
               "Sample 3" = "sample3",
               "Sample 4" = "sample4",
               "Sample 5" = "sample5",
               "Sample 6" = "sample6")
```

In `"Sample 1" = "sample1"` the string `"Sample 1"` is the text that will appear in the widget, whereas `"sample1"` is the value that will be returned from the widget. Using this would make a much neater looking widget. Think of the name as purely cosmetic and what you'll see while the value is what's important and will be used behind the scenes for calculations. You could change the names to whatever you wanted without having an effect the app.

Finally, `selected` chooses which value the widget will start on when the app is run.

Now to add the second widget. To show the difference between an unamed and a named list, the second widget will use a named list for `choices`.

```{r, eval = FALSE}

ui <- fluidPage(
  titlePanel("My first app"),
  
  sidebarLayout(
    sidebarPanel("This is a sidebar panel",
                 selectInput(inputId = "x_select", label = "Select x-axis", 
                             choices = list("sample1", 
                                            "sample2", 
                                            "sample3",
                                            "sample4",
                                            "sample5",
                                            "sample6"), 
                             selected = "sample1"),
                 selectInput(inputId = "y_select", label = "Select y-axis", 
                             choices = list("Sample 1" = "sample1", 
                                            "Sample 2" = "sample2", 
                                            "Sample 3" = "sample3",
                                            "Sample 4" = "sample4",
                                            "Sample 5" = "sample5",
                                            "Sample 6" = "sample6"),  
                             selected = "sample2")
    ),
    mainPanel("And this is the main panel")
  )
)

```

This widget is nearly identical to the first, all that has changed is the name of the widget, the use of a named list and which sample has been pre-selected. This widget has been called `y_select` and it will start on the value `sample2` so that the columns selected for the x and y axis will be different. 

#### Adding some outputs

There's one last thing to do before moving onto the server object. The app has inputs now, but it doesn't have any outputs! For this app, we will use three outputs. Two are going to be purely diagnostic so we can check that our `selectInputs` are working. They will not be included in our final app. The one output that will remain in our final app is `plotOutput`, as we want to generate a plot and it will be located in the main panel. There are numerous types of outputs Shiny can generate - to find out what other outputs Shiny is capable of, consult the [Shiny cheatsheet](http://shiny.rstudio.com/images/shiny-cheatsheet.pdf) or the [Shiny website](https://shiny.rstudio.com/reference/shiny/latest/).

```{r, eval = F}

ui <- fluidPage(
  titlePanel("My first app"),
  
  sidebarLayout(
    sidebarPanel("This is a sidebar panel",
                 selectInput(inputId = "x_select", label = "Select x-axis", 
                             choices = list("sample1", 
                                            "sample2", 
                                            "sample3",
                                            "sample4",
                                            "sample5",
                                            "sample6"), 
                             selected = "sample1"),
                 selectInput(inputId = "y_select", label = "Select y-axis", 
                             choices = list("Sample 1" = "sample1", 
                                            "Sample 2" = "sample2", 
                                            "Sample 3" = "sample3",
                                            "Sample 4" = "sample4",
                                            "Sample 5" = "sample5",
                                            "Sample 6" = "sample6"),  
                             selected = "sample2")
    ),
        mainPanel("And this is the main panel",
              textOutput(outputId = "check_x_select"),
              textOutput(outputId = "check_y_select"),
              plotOutput(outputId = "my_plot")
    )
  )
)

```

`my_plot` is the ID of the `plotoutput` and it tells the server object file where to direct data. Same goes for the two textOutputs. Run the app and see what you'll get. Does it look any different?

At the moment, the app will display nothing because we haven't told it do any calculations and generate a plot or display text. To do that, we need to move on to the server side.

## Data processing on the server side

The app now has a full UI but nothing is happening on the backend. To make the app interactive, that's where the server object comes into play. Think of it as the object that contains an R analysis. The structure of this object can vary immensely depending on the complexity of the app itself.

First, we need to check on our two `selectInput` widgets, see if they are working correctly, before we move on to plotting. When building a Shiny app, it's useful to have create outputs to check to see if parts of the app are doing what they should be, for both the ui and the server code. This step can be omitted, but we'll go through it to demonstrate what the `selectInputs` are doing.


```{r, eval = F}

server <- function(input, output) {
  
  output$check_x_select <- renderText({
    print(input$x_select)
  })
  
  output$check_y_select <- renderText({
    print(input$y_select)
  })
}

```

Now run the app.

There are a number of `render` functions in Shiny, `renderTable`, `renderText`, `renderPrint`, etc, depending on what type of data needs to be output. If you want to check what render options exist, got the [Shiny website reference page](http://shiny.rstudio.com/reference/shiny/latest/).

Whenever a `render` function is called, it needs to be directed to an output that exists in the ui object. In the case of `output$check_x_select`, we have pointed the `renderText` function to `check_x_select`, which was the id of a `textOutput` in the UI. This means that the result of `renderText` is sent to the `check_x_select` output.

Inside the `renderText` function, we `print` the value of the `x_select`. To access a value of a input widget, we use `input$input_Id`. Once the app is running, every time the value of the input changes, a render function that depends on it will be re-run. So if we changed the value of the `x_select`, only the first renderText statement is re-calculated but the second one, which doesn't depend on `x_select` will not be re-calculated.

Notice that despite the difference between the two `selectInputs` (one uses a named list and the other doesn't), that the values returned are the same. Once again, using a named list changes the apperance of the ui but not the actual values of the widgets.

Now that we've seen that our widgets are working correctly, we can remove the diagnostic lines of code from both the ui and server. You can either comment them out or delete them. Your app should currently look like this:

```{r, eval = F}
library(shiny)
ui <- fluidPage(
  titlePanel("My first app"),
  
  sidebarLayout(
    sidebarPanel("This is a sidebar panel",
                 selectInput(inputId = "x_select", label = "Select x-axis", 
                             choices = list("sample1", 
                                            "sample2", 
                                            "sample3",
                                            "sample4",
                                            "sample5",
                                            "sample6"), 
                             selected = "sample1"),
                 selectInput(inputId = "y_select", label = "Select y-axis", 
                             choices = list("Sample 1" = "sample1", 
                                            "Sample 2" = "sample2", 
                                            "Sample 3" = "sample3",
                                            "Sample 4" = "sample4",
                                            "Sample 5" = "sample5",
                                            "Sample 6" = "sample6"),  
                             selected = "sample2")
    ),
    mainPanel("And this is the main panel",
              plotOutput(outputId = "my_plot")
    )
  )
)

server <- function(input, output) {
  
}

shinyApp(ui = ui, server = server)

```


The final app will be rather simple. It will take one function, `renderPlot` and send it back to the `my_plot` output in the UI. To get going, let's create an empty `renderPlot`.

```{r, eval = F}

server <- function(input, output) {
  
  output$my_plot <- renderPlot({
    
  })
}

```

Now let's give `renderPlot` some data to display, the first two columns from the csv `shiny_sample_data.csv`.

```{r, eval = F}
server <- function(input, output) {
  
  output$my_plot <- renderPlot({
    
    #Read in the sample csv
    dat <- read.csv("~/r-more-files/shiny_sample_data.csv", row.names = 1)
    
    #Pull out the first and second columns in dat
    x_axis <- dat[, "sample1"]
    y_axis <- dat[, "sample2"]
    
    #Create a basic dot plot
    plot(x = x_axis, y_axis)
  })
}
```

```{r, echo=FALSE}

titlePanel("My first app")

#Changed up the input and output IDs so that they don't conflict with the earlier app.  
sidebarLayout(
  sidebarPanel("App input control panel",
               selectInput("x_select1", label = h3("Select x-axis"), 
                           choices = list("sample1", 
                                          "sample2", 
                                          "sample3",
                                          "sample4",
                                          "sample5",
                                          "sample6"), 
                           selected = "sample1"),
               selectInput(inputId = "y_select1", label = "Select y-axis", 
                           choices = list("Sample 1" = "sample1", 
                                          "Sample 2" = "sample2", 
                                          "Sample 3" = "sample3",
                                          "Sample 4" = "sample4",
                                          "Sample 5" = "sample5",
                                          "Sample 6" = "sample6"),  
                           selected = "sample2")
  ),
  mainPanel("App output panel",
            plotOutput("plot1", width = 600, height = 600)
  )
)

output$plot1 <- renderPlot({
    dat <- read.csv("r-more-files/shiny_sample_data.csv", row.names = 1)
    x_axis <- dat[, "sample1"]
    y_axis <- dat[, "sample2"]
    
    plot(x = x_axis, y = y_axis)
  })

```

The app has a plot now...but it isn't interactive, if we change the widget values, it has no effect on what is plotted on the figure. That's because the first two columns were selected directly in the `renderPlot` function. However, we could change to call the widget values instead using `input`.

```{r, eval = F}
server <- function(input, output) {
  
  output$my_plot <- renderPlot({
    
    #Read in the sample csv
    dat <- read.csv("~/r-more-files/shiny_sample_data.csv", row.names = 1)
    
    #Pull out a column for the x and y axis each
    x_axis <- dat[, input$x_select]
    y_axis <- dat[, input$y_select]
    
    #Create a basic dot plot
    plot(x = x_axis, y_axis)
  })
}
```

```{r, echo=FALSE}

titlePanel("My first app")

#Changed up the input and output IDs so that they don't conflict with the earlier app.  
sidebarLayout(
  sidebarPanel("App input control panel",
               selectInput("x_select2", label = h3("Select x-axis"), 
                           choices = list("sample1", 
                                          "sample2", 
                                          "sample3",
                                          "sample4",
                                          "sample5",
                                          "sample6"), 
                           selected = "sample1"),
               selectInput(inputId = "y_select2", label = "Select y-axis", 
                           choices = list("Sample 1" = "sample1", 
                                          "Sample 2" = "sample2", 
                                          "Sample 3" = "sample3",
                                          "Sample 4" = "sample4",
                                          "Sample 5" = "sample5",
                                          "Sample 6" = "sample6"),  
                           selected = "sample2")
  ),
  mainPanel("App output panel",
            plotOutput("plot2", width = 600, height = 600)
  )
)

output$plot2 <- renderPlot({
  dat <- read.csv("r-more-files/shiny_sample_data.csv", row.names = 1)
  x_axis <- dat[, input$x_select2]
  y_axis <- dat[, input$y_select2]
  
  plot(x = x_axis, y = y_axis)
})

```

Congratulations! You've made your first app! To get it exactly like the example at the start of the lesson, can you figure out how to change the axis titles to the name of the selected sample. One of `selectInput` widgets also need to be changed to a named list. Other than that, you're good to go.

> Hint:
>
> plot(x = blah, y = plah, xlab = "Label for the x-axis", ylab = "Label for the y-axis")


Now imagine you had an experiment where you had many conditions and you needed to plot each one against each other. Instead of plotting each one individually, with a Shiny app, you could easily visualise the different conditions without having to write code for each one of them and then download them. 

If you want to get a shareable link of your app, so that other people can access it over the web: `http://biotraining.erc.monash.edu:3838/your_username/demo/`. 

Make sure to change the url to have your biotraining account name in place of `your_username`.

## Challenge app

```{r, echo = FALSE}
library(ggplot2)

titlePanel("My slightly more complicated app")

#Changed up the input and output IDs so that they don't conflict with the earlier app.  
sidebarLayout(
  sidebarPanel("App input control panel",
               selectInput("x_select3", label = h3("Select x-axis"), 
                           choices = list("sample1", 
                                          "sample2", 
                                          "sample3",
                                          "sample4",
                                          "sample5",
                                          "sample6"), 
                           selected = "sample1"),
               selectInput("y_select3", label = h3("Select y-axis"), 
                           choices = list("sample1", 
                                          "sample2", 
                                          "sample3",
                                          "sample4",
                                          "sample5",
                                          "sample6"),
                           selected = "sample2"),
               sliderInput("n_rows", label = "Select number of rows to show", min = 1, max = 15, value = 1)
  ),
  mainPanel("App output panel",
            plotOutput("plot3", width = 600, height = 600),
            tableOutput("table1")
  )
)

output$plot3 <- renderPlot({
  dat <- read.csv("r-more-files/shiny_sample_data.csv", row.names = 1)
  x_axis <- dat[, input$x_select3]
  y_axis <- dat[, input$y_select3]
  
  plot(x = x_axis, y = y_axis)
})


output$table1 <- renderTable({
  dat <- read.csv("r-more-files/shiny_sample_data.csv", row.names = 1)
  head(dat[, c(input$x_select3, input$y_select3)], input$n_rows)
})
```


> Hint:
>
> 1. The first step is to sort out the ui. Two elements have been added to it, an input widget and the other an output.
>
>
> The input widget is a slider. The code for a slider looks something like this:
>
>      sliderInput("slider1", label = "Slider", min = 0, max = 100, value = 50)
>
> To find out more about how a slider works check the [Shiny widget gallery](http://shiny.rstudio.com/gallery/widget-gallery.html)
> 
> The new output is a `tableOutput`. The code for it looks like:
> 
>     
>      tableOutput(outputId = "table1")

> 2. Once you have your new ui, move on the server object. You'll need to direct the result of a `renderTable` function to the new output
> 
> An important thing to note is that only one thing is returned from inside a render function (usually the last line inside that function). Therefore a variable, such as `dat` created inside the `renderPlot` will not exist outside that `renderPlot` function. You'll need to read the csv of data back in again in the `renderTable` function
>
> The table that is displayed is a subset of the full csv. It shows only the two currently selected columns. Remember that a dataframe can be subsetted to show only certain columns using `x[, c(column_a, column_c, column_z)]`
>
> Inside the `renderTable` call, you'll need a function that shows you the top of a table. The `head` function is ideal for this. If you aren't familiar with how head works, check the help manual for `head` with `?head` to see the arguements it takes.

