```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, error = F, 
                      message = F, warning = F)
library(shiny)
library(emoji)
library(shinyjs)
```

<style>

.myClass {font-size: 14px;}

</style>


```{css echo=FALSE}
pre {
  max-height: 700px;
  overflow-y: auto;
}

pre[class] {
  max-height: 500px;
}

.scroll-100 {
  max-height: 500px;
  overflow-y: auto;
  background-color: inherit;
}
```



## Shiny app logic I {.build} 

<div style="float: left; width: 50%; text-align: center;">

`ui` (**U**ser **I**nterface)

The container, whatever sees the user

</div>

<div style="float: right; width: 50%; text-align: center;">

`server`

It gets the work done

</div> 

<div style="float: center; width: 100%; text-align: left;">

`server` and `ui` talks to each other in a flow: 

> `ui` (input) $\rightarrow$ `server` (elaborate and compute) $\rightarrow$ `ui` (output)
>
>   - Define something in the `ui` and not using in the server: nothing happens, it just doesn't exist
>
  - Calling something in the server that has not been defined in the `ui`: errors everywhere
  
</div>


## Shiny app logic II {.build}

First things first: 

```{r eval = FALSE}
install.packages("shiny") # install
library(shiny) # use it
```

And then: 

```{r eval = FALSE}
ui = fluidPage(          # Define the ui
   [...]
  )

server = function(input, output){ # Define the server
  [...]
}

shinyApp(ui, server)  # create the App
```

Yes... it's **that** easy

## Be tidy, be consistent, save time 

- Use `R` projects with the default for shiny app creations 

- 10 minutes coding $=$ 1 hour of debugging

- If the app is particularly complex and long, it's better to save `ui` and `server` in two different scripts


## To each its own: Input in UI

```{r eval=FALSE, class.source="myClass"}
sliderInput()     # Slider input widget
numericInput()    # Numeric input control
selectInput()     # Select list input control
checkboxInput()   # Checkbox input control
checkboxGroupInput()
dateInput()       # Date input
fileInput()       # File upload control
radioButtons()    # Radio buttons
textInput()       # Text input control
passwordInput()   # Password input control
actionButton()    # Action button
dateInput()       # Date input
dateRangeInput()  # Input a data range
```

[Complete list](https://shiny.rstudio.com/gallery/widget-gallery.html) (with code)


```{r eval=FALSE, class.source="myClass"}
selectInput("mySelection", label = h3("Select box"), 
    choices = list("Choice 1" = 1, "Choice 2" = 2, "Choice 3" = 3), 
    selected = 1)
```



## To each its own: Output in UI

```{r eval=FALSE}
plotOutput()          # Plot output element
textOutput()          # Text output element
verbatimTextOutput()  # Verbatim text output element
tableOutput()         # Table output element
dataTableOutput()     # Data table output element
htmlOutput()          # HTML output element
uiOutput()            # user interface element
downloadButton()      # Download button
Progress()            # Reporting progress (object oriented)
withProgress()        # Reporting progress (functional)
outputOptions()       # Set options for an output object
```

Labels: 

```{r eval = FALSE}
verbatimTextOutput(
  outputId = "myOutput"
)
```


## To each its own: Output containers in server

```{r, eval =FALSE}
renderPlot()        # Plot output
renderText()        # Text output
renderPrint()       # Printable output
renderTable()       # Table output
renderDataTable()   # Data table output
renderImage()       # Image file output
renderUI()          # UI output
downloadHandler()   # File downloads
```

```{r eval=FALSE}
server = function(input, output) {
  output$myOutput = renderText({
    paste(paste("This is my choice"), input$mySelection)
  })
}
```

## App layout

```{r eval=FALSE}
fluidPage()   # rows with columns within 12-unit 
              # wide grid

fluidRow(      # custom the page in two columns
  column(6, ), # of width 6 out of the 12-unit
  column(6)    # on a single row
)    

sidebarLayout(     # automatic layout with
sidebarPanel(...), # sidebar and
mainPanel(...)    # main area
)

# and many more!
```

[Complete list](https://shiny.rstudio.com/gallery/) (look for "Application layout")


## Let's start with an easy (ugly) one: Practice


```{r, eval = TRUE, echo=FALSE}
shinyApp(

  ui = fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset", # name of the input (for the server)
                  label = "Choose a dataset:", # name of the input (for the users)
                  choices = c("rock", "pressure", "cars")) # options (for  both 
                                                          # users & server)
    ),

    mainPanel(
      plotOutput( # define the graphical output (we're telling R that this output 
        "graph"   # container must contain a plot)
      ),
      verbatimTextOutput( # define the graphical output (we're telling R that
        "summary"   # this output container must contain a Verbatim output)
      )
    ) 
  )
),

server = function(input, output){
  output$graph <- renderPlot({
    if(input$dataset == "rock"){ # call the input and its options with their label
      data <- rock
    } else if (input$dataset == "pressure" ){
      data <- pressure
    } else if (input$dataset == "cars") {
      data <- cars
    }
    plot(data[, c(1:2)])
  })

  output$summary <- renderPrint({
    if(input$dataset == "rock"){
      data <- rock
    } else if (input$dataset == "pressure" ){
      data <- pressure
    } else if (input$dataset == "cars") {
      data <- cars
    }
    summary(data[, c(1:2)])
  })
},


  options = list(height = 800)
)
```



##  Let's start with an easy (ugly) one: Code


```{r, echo = TRUE, message = FALSE, eval = FALSE}
shinyApp(

  ui = fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset", # name of the input (for the server)
                  label = "Choose a dataset:", # name of the input (for the users)
                  choices = c("rock", "pressure", "cars")) # options (for  both 
                                                          # users & server)
    ),

    mainPanel(
      plotOutput( # define the graphical output (we're telling R that this output 
        "graph"   # container must contain a plot)
      ),
      verbatimTextOutput( # define the graphical output (we're telling R that
        "summary"   # this output container must contain a Verbatim output)
      )
    ) 
  )
),

server = function(input, output){
  output$graph <- renderPlot({
    if(input$dataset == "rock"){ # call the input and its options with their label
      data <- rock
    } else if (input$dataset == "pressure" ){
      data <- pressure
    } else if (input$dataset == "cars") {
      data <- cars
    }
    plot(data[, c(1:2)])
  })

  output$summary <- renderPrint({
    if(input$dataset == "rock"){
      data <- rock
    } else if (input$dataset == "pressure" ){
      data <- pressure
    } else if (input$dataset == "cars") {
      data <- cars
    }
    summary(data[, c(1:2)])
  })
},


  options = list(height = 800)
)
```


## Don't repeat yourself, use the "shelf" solution


```{r, eval = FALSE}
shinyApp(

  ui = fluidPage( # the UI didn't change at all
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = c("rock", "pressure", "cars"))
    ),

    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) # display output
  )
),

server = function(input, output){ 

values <- reactiveValues() # create the shelf with reactive values 
  dataInput <- reactive({ # create a reactive envrinoment (it reacts to whatever input receives)
    if(input$dataset == "rock"){ # this part is the same as before
      data <- rock
    } else if (input$dataset == "pressure" ){
      data <- pressure
    } else if (input$dataset == "cars") {
      data <- cars
    }
  })
  observe({                      # ta-da, the shelf is in action. To make it works,telling R 
    values$data <- data.frame(dataInput()) #  it has to be called inside an observe function, 
  })                                       # we're using a reactive object


    output$graph <- renderPlot({
       plot(values$data[, c(1:2)]) # call the shelf and you're all set
    })

    output$summary <- renderPrint({
    summary(values$data)
    })
},


  options = list(height = 800)
)
```


## Take things slowly and use the action buttons

There are two ways of using the action buttons: 

1. Use `eventReactive()`
2. Use the shelf we have seen before and adding the action button 

(Throughout the course $\rightarrow$ solution number 2)



## Action button solution 1: Practice

```{r, echo = FALSE, eval= TRUE}
shinyApp(
  ui = fluidPage(
    sidebarLayout(
      sidebarPanel(
        selectInput(inputId = "dataset",
                    label = "Choose a dataset:",
                    choices = list("rock" = 1, 
                                   "pressure" = 2,
                                   "cars" = 3)), 
        actionButton("load", "Select dataset")
      ),
      
      
      mainPanel(
        plotOutput(
          "graph"   
        ), 
        verbatimTextOutput( 
          "summary"   
        )))), 
  server = function(input, output){
    dataInput = eventReactive(input$load, {
      if(input$dataset == 1){
        data <- rock
      } else if (input$dataset == 2 ){
        data <- pressure
      } else if (input$dataset == 3) {
        data <- cars
      } 
      
    } 
    )
    output$graph <- renderPlot({
      data = dataInput()
      plot(data[, c(1:2)])
    })
    
    output$summary <- renderPrint({
      data = dataInput()
      summary(data[, c(1:2)])
    })
  }, 
  options = list(height = 800)
  
)
```


## Action button solution 1: Code

```{r, echo = TRUE, eval= FALSE}
shinyApp(
  ui = fluidPage( # same as before
    sidebarLayout(
      sidebarPanel(
        selectInput(inputId = "dataset",
                    label = "Choose a dataset:",
                    choices = list("rock" = 1, # we add numbers to the choices 
                                   "pressure" = 2, # (more convenient)
                                   "cars" = 3)), 
        actionButton("load", "Select dataset")
      ),
      
      
      mainPanel(
        plotOutput( 
          "graph"   
        ), 
        verbatimTextOutput( 
          "summary"   
        )))), 
  server = function(input, output){         # new shelf 
    dataInput = eventReactive(input$load, { # here's the action for the button
      if(input$dataset == 1){ # call the input and its options with their label
        data <- rock
      } else if (input$dataset == 2 ){
        data <- pressure
      } else if (input$dataset == 3) {
        data <- cars
      } 
      
    } 
    )
    output$graph <- renderPlot({
      data = dataInput()
      plot(data[, c(1:2)])
    })
    
    output$summary <- renderPrint({
      data = dataInput()
      summary(data[, c(1:2)])
    })
  }, 
  options = list(height = 800)
  
)
```


## Action button solution 2: Practice

```{r, echo = FALSE, eval= TRUE}
shinyApp(

  ui = fluidPage(
   sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = list("rock" = 1, 
                                   "pressure" = 2,
                                   "cars" = 3)),

      actionButton("load", "Upload data")
      ),
    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) # display output
  )
),

server = function(input, output){
 values <- reactiveValues()
  dataInput <- reactive({
    if(input$dataset == 1){
      data <- rock
    } else if (input$dataset == 2 ){
      data <- pressure
    } else if (input$dataset == 3) {
      data <- cars
    }
  })
  observeEvent(input$load, { 
    values$data <- data.frame(dataInput())
  })

  output$graph <- renderPlot({
    plot(values$data[, c(1:2)])
  })

  output$summary <- renderPrint({
    summary(values$data)
  })
},


  options = list(height = 800)
)
```


## Action button solution 2: Code

```{r, echo = TRUE, eval= FALSE}
shinyApp(

  ui = fluidPage(
   sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = list("rock" = 1, 
                                   "pressure" = 2,
                                   "cars" = 3)),

      actionButton("load", "Upload data")
      ),
    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) # display output
  )
),

server = function(input, output){
 values <- reactiveValues()
  dataInput <- reactive({
    if(input$dataset == 1){
      data <- rock
    } else if (input$dataset == 2 ){
      data <- pressure
    } else if (input$dataset == 3) {
      data <- cars
    }
  })
  observeEvent(input$load, { # Use the observeEvent function to make the UI and 
    values$data <- data.frame(dataInput()) # server communicate again
  })

  output$graph <- renderPlot({
    plot(values$data[, c(1:2)])
  })

  output$summary <- renderPrint({
    summary(values$data)
  })
},


  options = list(height = 800)
)
```




## Don't scare the users: Practice

```{r echo=FALSE, eval=TRUE}
shinyApp(

  ui = fluidPage( # same as before
   sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = list("rock" = 1, 
                                   "pressure" = 2,
                                   "cars" = 3)),

      actionButton("load", 
                   "Upload data")
      ),
    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) # display output
  )
),

server = function(input, output){
   values <- reactiveValues()
    dataInput <- reactive({
      if(input$dataset == 1){
        data <- rock
      } else if (input$dataset == 2 ){
        data <- pressure
      } else if (input$dataset == 3) {
        data <- cars
      }
    })
    observeEvent(input$load, {
      values$data <- data.frame(dataInput())
    })

  output$graph <- renderPlot({
    validate( 
      need(input$load > 0, 
           "Waiting for data") 
    )
    plot(values$data[, c(1:2)])
  })

  output$summary <- renderPrint({
    validate(
      need(input$load > 0, "Waiting for data") 
    )
    summary(values$data)
  })
},


  options = list(height = 800)
)
```

## Don't scare the users: Code

```{r echo=TRUE, eval=FALSE}
shinyApp(

  ui = fluidPage( # same as before
   sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = list("rock" = 1, 
                                   "pressure" = 2,
                                   "cars" = 3)),

      actionButton("load", 
                   "Upload data")
      ),
    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) # display output
  )
),

server = function(input, output){
   values <- reactiveValues()
    dataInput <- reactive({
      if(input$dataset == 1){
        data <- rock
      } else if (input$dataset == 2 ){
        data <- pressure
      } else if (input$dataset == 3) {
        data <- cars
      }
    })
    observeEvent(input$load, {
      values$data <- data.frame(dataInput())
    })

  output$graph <- renderPlot({
    validate( # validate function: I need something to be validated for letting 
      need(input$load > 0, # you see what's hidden behind me
           "Waiting for data") # If it's not validated, I'll show you this message
    )
    plot(values$data[, c(1:2)])
  })

  output$summary <- renderPrint({
    validate(
      need(input$load > 0, "Waiting for data") # Waiting message
    )
    summary(values$data)
  })
},


  options = list(height = 800)
)
```




## Let the users use their own data: Practice

```{r echo = FALSE,eval=TRUE}
shinyApp(

  ui = fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = list("rock" = 1, 
                                 "pressure" = 2,
                                 "cars" = 3,
                                 "I want to use my data!!" =4)), # we add an option
      # Let me introduce you Mr. Conditional Panel
      conditionalPanel(
        condition = "input.dataset == '4'", # What is the condition for which I should show up?
        # What should be displayed inside me once I show up?
        fileInput("example",  # label for the server
                  "Wow my data set!", 
                  accept = c("csv")) # what format do we accept?
      ),
      actionButton("load", "Upload data")
    ),

    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) 
  )
),

server = function(input, output){
    values <- reactiveValues()
  dataInput <- reactive({
    if(input$dataset == 1){ 
      data <- rock
    } else if (input$dataset == 2 ){
      data <- pressure
    } else if (input$dataset == 3) {
      data <- cars
    } else if (input$dataset == 4) {
      data <- read.csv(input$example$datapath) # we call the input for the data 
            #import by its label and we ask for the data path selected by the user
    }
  })
  observeEvent(input$load, # we load the data set (whatever it is only once the 
                                       #  user has hit the button)
               {
    values$data <- data.frame(dataInput())
  })

  output$graph <- renderPlot({
    validate(
      need(input$load > 0, "Waiting for data")
    )
    if (any(colnames(values$data) == "condition") ){ # I had to change the code 
      #just for the new data set, which is different from all the others
      # check if there are characters
      if (any(sapply(values$data, is.character)) == TRUE) {
  values$data[, sapply(values$data, is.character) == T] = lapply(values$data[, sapply(values$data, is.character) == T], 
                                                 as.factor)
} else {
  values$data = values$data
}
      plot(values$data$tr ~ values$data$condition,
           xlab = "Condition", ylab = "TR")
    } else {
      plot(values$data[, c(1:2)])
    }
  })

  output$summary <- renderPrint({
    validate(
      need(input$load > 0, "Waiting for data")
    )
    if (any(colnames(values$data) == "condition") ){
      summary(values$data[, c(2:3)])
    } else {
      summary(values$data[, c(1:2)])
    }
  })
},


  options = list(height = 800)
)
```


## Let the users use their data: Code

```{r echo = TRUE,eval=FALSE}
shinyApp(

  ui = fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = list("rock" = 1, 
                                 "pressure" = 2,
                                 "cars" = 3,
                                 "I want to use my data!!" =4)), # we add an option
      # Let me introduce you Mr. Conditional Panel
      conditionalPanel(
        condition = "input.dataset == '4'", # What is the condition for which I should show up?
        # What should be displayed inside me once I show up?
        fileInput("example",  # label for the server
                  "", # no displayed label for users
                  accept = c("csv")) # what format do we accept?
      ),
      actionButton("load", "Upload data")
    ),

    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) # display output
  )
),

server = function(input, output){
    values <- reactiveValues()
  dataInput <- reactive({
    if(input$dataset == 1){ # now we use the number associated with each dataset 
      data <- rock
    } else if (input$dataset == 2 ){
      data <- pressure
    } else if (input$dataset == 3) {
      data <- cars
    } else if (input$dataset == 4) {
      data <- read.csv(input$example$datapath) # we call the input for the data 
            #import by its label and we ask for the data path selected by the user
    }
  })
  observeEvent(input$load, # we load the data set (whatever it is only once the 
                                       #  user has hit the button)
               {
    values$data <- data.frame(dataInput())
  })

  output$graph <- renderPlot({
    validate(
      need(input$load > 0, "Waiting for data")
    )
    if (any(colnames(values$data) == "condition") ){ # I had to change the code 
      #just for the new data set, which is different from all the others
      # check if there are characters
      if (any(sapply(values$data, is.character)) == TRUE) {
  values$data[, sapply(values$data, is.character) == T] = lapply(values$data[, sapply(values$data, is.character) == T], 
                                                 as.factor)
} else {
  values$data = values$data
}
      plot(values$data$tr ~ values$data$condition,
           xlab = "Condition", ylab = "TR")
    } else {
      plot(values$data[, c(1:2)])
    }
  })

  output$summary <- renderPrint({
    validate(
      need(input$load > 0, "Waiting for data")
    )
    if (any(colnames(values$data) == "condition") ){
      summary(values$data[, c(2:3)])
    } else {
      summary(values$data[, c(1:2)])
    }
  })
},


  options = list(height = 800)
)
```

## Code has to be fluid and adapt to everything (like a cat)

```{r, out.width = "15%", fig.align='center', echo = FALSE}
knitr::include_graphics("liquid-cats1.jpg")
```


We have the code for uploading a data frame. 

The code I provided for the previous app is specifically designed to work for that specific data frame 

If only we had a way to explore the data frame columns and choose the ones we would like to plot `r emoji("thinking")`



## Practice

```{r echo=FALSE, eval=TRUE}
shinyApp(

 ui = fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = list("rock" = 1,
                                 "pressure" = 2,
                                 "cars" = 3,
                                 "I want to use my data!!" =4)),
      
      conditionalPanel(
        condition = "input.dataset == '4'",
        fileInput("example",
                  "", accept = c("csv"))
      ), 
      actionButton("load", "Upload data"), # This is the button for uploading 
                                            # the data
      conditionalPanel(                    # It appears only when the data are 
        condition = "input.load >= '1'",   # loaded
        uiOutput("var1"),                 # contains the name for variable 1
        uiOutput("var2"),                 # contains the name for variable 2
        actionButton("select", "Select & Display") # This is the button for 
      ),                              # selecting the variables and actually see
                                      # something
    ),
    
    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) # display output
  )
),

server = function(input, output){
  values <- reactiveValues()
  dataInput <- reactive({
    if(input$dataset == 1){
      data <- rock
    } else if (input$dataset == 2 ){
      data <- pressure
    } else if (input$dataset == 3) {
      data <- cars
    } else if (input$dataset == 4) {
      data <- read.csv(input$example$datapath)
    }
  })
  observeEvent(input$load, {
    values$data <- data.frame(dataInput())
    # check the characters
    if (any(sapply(values$data, is.character)) == TRUE) {
      values$data[, sapply(values$data, is.character) == T] = lapply(values$data[, sapply(values$data, is.character) == T], as.factor)
    } else {
      values$data = values$data
      }
  })
  
  output$var1 <- renderUI({    # remember variable 1? here it is how we extract it
    nam <- colnames(values$data) # from the data set
    selectInput("var1", label = "Select x:", # create the input
                choices = c(nam), multiple = FALSE,
                selected = nam[1])
  })
  
  output$var2 <- renderUI({
    nam2 <- colnames(values$data) # create the input for variable 2
    selectInput("var2", label = "Select y:",
                choices = c(nam2), multiple = FALSE,
                selected = nam2[1])
  })
  
  newdata <- observeEvent(input$select, # use observe event so that the app will 
                          { # wait for you to decide before acting
                            # Besides, you're creating a new (smaller) object
                            values$df <- values$data[c(input$var1, input$var2)]
                          })
  output$graph <- renderPlot({
    validate(
      need(input$select > 0, "Waiting for data") # I changed the validation from
    )                                        # load to select
    
    df <- values$df # store the new object into an R object
    plot(df[, c(1:2)]) # use it normally


  })

  output$summary <- renderPrint({
    validate(
      need(input$select > 0, "Waiting for data")
    ) 
    df <- values$df # same 
    summary(df[, c(1:2)])

  })
},


  options = list(height = 800)
)

```


## Code

```{r echo=TRUE, eval=FALSE}
shinyApp(

 ui = fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "dataset",
                  label = "Choose a dataset:",
                  choices = list("rock" = 1,
                                 "pressure" = 2,
                                 "cars" = 3,
                                 "I want to use my data!!" =4)),
      
      conditionalPanel(
        condition = "input.dataset == '4'",
        fileInput("example",
                  "", accept = c("csv"))
      ), 
      actionButton("load", "Upload data"), # This is the button for uploading 
                                            # the data
      conditionalPanel(                    # It appears only when the data are 
        condition = "input.load >= '1'",   # loaded
        uiOutput("var1"),                 # contains the name for variable 1
        uiOutput("var2"),                 # contains the name for variable 2
        actionButton("select", "Select & Display") # This is the button for 
      ),                              # selecting the variables and actually see
                                      # something
    ),
    
    mainPanel(
      plotOutput(
        "graph"
      ),
      verbatimTextOutput(
        "summary"
      )
    ) # display output
  )
),

server = function(input, output){
  values <- reactiveValues()
  dataInput <- reactive({
    if(input$dataset == 1){
      data <- rock
    } else if (input$dataset == 2 ){
      data <- pressure
    } else if (input$dataset == 3) {
      data <- cars
    } else if (input$dataset == 4) {
      data <- read.csv(input$example$datapath)
    }
  })
  observeEvent(input$load, {
    values$data <- data.frame(dataInput())
    # check the characters
    if (any(sapply(values$data, is.character)) == TRUE) {
      values$data[, sapply(values$data, is.character) == T] = lapply(values$data[, sapply(values$data, is.character) == T], as.factor)
    } else {
      values$data = values$data
      }
  })
  
  output$var1 <- renderUI({    # remember variable 1? here it is how we extract it
    nam <- colnames(values$data) # from the data set
    selectInput("var1", label = "Select x:", # create the input
                choices = c(nam), multiple = FALSE,
                selected = nam[1])
  })
  
  output$var2 <- renderUI({
    nam2 <- colnames(values$data) # create the input for variable 2
    selectInput("var2", label = "Select y:",
                choices = c(nam2), multiple = FALSE,
                selected = nam2[1])
  })
  
  newdata <- observeEvent(input$select, # use observe event so that the app will 
                          { # wait for you to decide before acting
                            # Besides, you're creating a new (smaller) object
                            values$df <- values$data[c(input$var1, input$var2)]
                          })
  output$graph <- renderPlot({
    validate(
      need(input$select > 0, "Waiting for data") # I changed the validation from
    )                                        # load to select
    
    df <- values$df # store the new object into an R object
    plot(df[, c(1:2)]) # use it normally


  })

  output$summary <- renderPrint({
    validate(
      need(input$select > 0, "Waiting for data")
    ) 
    df <- values$df # same 
    summary(df[, c(1:2)])

  })
},


  options = list(height = 800)
)
```




## Interactive plots: Practice

```{r echo = FALSE, eval=TRUE}
library(shinyjs)
shinyApp(

 ui = fluidPage(
      useShinyjs(),  # Set up shinyjs (this is just for nice visual effects)
  sidebarLayout(
    sidebarPanel(style = "background-color: 		#e1e9f9;",
                    a(id = "imp_det", 
                      h3("Choose a dataset", 
                         style = "font-style: normal; font-size: 14pt;"), 
                      href = "#"),
          shinyjs::hidden(div(
            id = "details_import",
            helpText(
              h5("You can also upload your data!")
            )
          )),
      selectInput(inputId = "dataset",
                  label = "",
                  choices = list("rock" = 1,
                                 "pressure" = 2,
                                 "cars" = 3,
                                 "I want to use my data!!" =4)),

      conditionalPanel(
        condition = "input.dataset == '4'",
        fileInput("example",
                  "", accept = c("csv"))
      ),
      actionButton("load", "Upload data"), 
      conditionalPanel(                    
        condition = "input.load >= '1'",  
        uiOutput("var1"),                
        uiOutput("var2"),                 
        actionButton("select", "Select & Display") 
      ),                              
                                      
    ),

    mainPanel(
      plotOutput(
        "graph",
        click = clickOpts(id = "plot_click"), # when we click we select a point
        brush = brushOpts(id = "plot_brush") # when we highlight an area we select
      ),     # many rows
      fluidRow( # it displays on the same row multiple arguments
      column(4, # first column with the summary verbatim output
             verbatimTextOutput(
        "summary"
      )),
      column(4,  # second column with another verbatim output for the points
             verbatimTextOutput(
               "points"
             )
             ),
      column(4,
             verbatimTextOutput(
               "brush"
             ))
      )

    ) # display output
  )
),

server = function(input, output){
  values <- reactiveValues()
  dataInput <- reactive({
    if(input$dataset == 1){
      data <- rock
    } else if (input$dataset == 2 ){
      data <- pressure
    } else if (input$dataset == 3) {
      data <- cars
    } else if (input$dataset == 4) {
      data <- read.csv(input$example$datapath)
    }
  })
     observeEvent(input$load, {
    values$data <- data.frame(dataInput())
    # check the characters
    if (any(sapply(values$data, is.character)) == TRUE) {
      values$data[, sapply(values$data, is.character) == T] = lapply(values$data[, sapply(values$data, is.character) == T], as.factor)
    } else {
      values$data = values$data
      }
  })
   shinyjs::onclick("imp_det",  # here the nice visual effect
                   shinyjs::toggle(id = "details_import", anim = TRUE))
  output$var1 <- renderUI({    
    nam <- colnames(values$data) 
    selectInput("var1", label = "Select x:", 
                choices = c(nam), multiple = F,
                selected = nam[1])
  })

  output$var2 <- renderUI({
    nam2 <- colnames(values$data) 
    selectInput("var2", label = "Select y:",
                choices = c(nam2), multiple = F,
                selected = nam2[1])
  })

  newdata <- observeEvent(input$select, 
                          { # wait for you to decide before acting
                            # Besides, you're creating a new (smaller) object
                            values$df <- values$data[c(input$var1, input$var2)]
                          })
  output$graph <- renderPlot({
    validate(
      need(input$select > 0, "Waiting for data") 
    )                                        # load to select
  
    df = values$df
    plot(df[, c(1:2)]) # use it normally


  })

  output$summary <- renderPrint({
    validate(
      need(input$select > 0, "Waiting for data")
    )
    df <- values$df # same
    summary(df[, c(1:2)])

  })

  output$points <- renderPrint({
    df <- values$df # store the data frame in an object
    pointID <- nearPoints(df, # the data frame
                          input$plot_click, # the command for a reaction
                           xvar = names(df)[colnames(df) == input$var1], # xvar of the graph
                          yvar = names(df)[colnames(df) == input$var2], # yvar of the graph,
                          addDist = FALSE)
    validate(
      need(nrow(pointID) != 0, "Click on a point") # Waiting message
    )
    pointID
  })

   output$brush <- renderPrint({
    df <- values$df # store the data frame in an object
    brushID <- brushedPoints(df,# the  data frame
                             input$plot_brush, # the command for a reaction
                          xvar = names(df)[colnames(df) == input$var1], # xvar of the graph
                          yvar = names(df)[colnames(df) == input$var2], # yvar of the graph
                             )
    validate(
      need(nrow(brushID) != 0, "Highlight Area") # Waiting message
    )
      brushID
  })

},


  options = list(height = 800)
)
```


## Interactive plots: Code

```{r echo = TRUE, eval=FALSE, message=FALSE, warning=FALSE}
library(shinyjs)
shinyApp(

 ui = fluidPage(
      useShinyjs(),  # Set up shinyjs (this is just for nice visual effects)
  sidebarLayout(
    sidebarPanel(style = "background-color: 		#e1e9f9;",
                    a(id = "imp_det", 
                      h3("Choose a dataset", 
                         style = "font-style: normal; font-size: 14pt;"), 
                      href = "#"),
          shinyjs::hidden(div(
            id = "details_import",
            helpText(
              h5("You can also upload your data!")
            )
          )),
      selectInput(inputId = "dataset",
                  label = "",
                  choices = list("rock" = 1,
                                 "pressure" = 2,
                                 "cars" = 3,
                                 "I want to use my data!!" =4)),

      conditionalPanel(
        condition = "input.dataset == '4'",
        fileInput("example",
                  "", accept = c("csv"))
      ),
      actionButton("load", "Upload data"), 
      conditionalPanel(                    
        condition = "input.load >= '1'",  
        uiOutput("var1"),                
        uiOutput("var2"),                 
        actionButton("select", "Select & Display") 
      ),                              
                                      
    ),

    mainPanel(
      plotOutput(
        "graph",
        click = clickOpts(id = "plot_click"), # when we click we select a point
        brush = brushOpts(id = "plot_brush") # when we highlight an area we select
      ),     # many rows
      fluidRow( # it displays on the same row multiple arguments
      column(4, # first column with the summary verbatim output
             verbatimTextOutput(
        "summary"
      )),
      column(4,  # second column with another verbatim output for the points
             verbatimTextOutput(
               "points"
             )
             ),
      column(4,
             verbatimTextOutput(
               "brush"
             ))
      )

    ) # display output
  )
),

server = function(input, output){
  values <- reactiveValues()
  dataInput <- reactive({
    if(input$dataset == 1){
      data <- rock
    } else if (input$dataset == 2 ){
      data <- pressure
    } else if (input$dataset == 3) {
      data <- cars
    } else if (input$dataset == 4) {
      data <- read.csv(input$example$datapath)
    }
  })
   observeEvent(input$load, {
    values$data <- data.frame(dataInput())
    # check the characters
    if (any(sapply(values$data, is.character)) == TRUE) {
      values$data[, sapply(values$data, is.character) == T] = lapply(values$data[, sapply(values$data, is.character) == T], as.factor)
    } else {
      values$data = values$data
      }
  })
   shinyjs::onclick("imp_det",  # here the nice visual effect
                   shinyjs::toggle(id = "details_import", anim = TRUE))
  output$var1 <- renderUI({    
    nam <- colnames(values$data) 
    selectInput("var1", label = "Select x:", 
                choices = c(nam), multiple = F,
                selected = nam[1])
  })

  output$var2 <- renderUI({
    nam2 <- colnames(values$data) 
    selectInput("var2", label = "Select y:",
                choices = c(nam2), multiple = F,
                selected = nam2[1])
  })

  newdata <- observeEvent(input$select, 
                          { # wait for you to decide before acting
                            # Besides, you're creating a new (smaller) object
                            values$df <- values$data[c(input$var1, input$var2)]
                          })
  output$graph <- renderPlot({
    validate(
      need(input$select > 0, "Waiting for data") 
    )                                        # load to select
    df <- values$df # store the new object into an R object
    plot(df[, c(1:2)]) # use it normally


  })

  output$summary <- renderPrint({
    validate(
      need(input$select > 0, "Waiting for data")
    )
    df <- values$df # same
    summary(df[, c(1:2)])

  })

  output$points <- renderPrint({
    df <- values$df # store the data frame in an object
    pointID <- nearPoints(df, # the data frame
                          input$plot_click, # the command for a reaction
                           xvar = names(df)[colnames(df) == input$var1], # xvar of the graph
                          yvar = names(df)[colnames(df) == input$var2], # yvar of the graph,
                          addDist = FALSE)
    validate(
      need(nrow(pointID) != 0, "Click on a point") # Waiting message
    )
    pointID
  })

   output$brush <- renderPrint({
    df <- values$df # store the data frame in an object
    brushID <- brushedPoints(df,# the  data frame
                             input$plot_brush, # the command for a reaction
                          xvar = names(df)[colnames(df) == input$var1], # xvar of the graph
                          yvar = names(df)[colnames(df) == input$var2], # yvar of the graph
                             )
    validate(
      need(nrow(brushID) != 0, "Highlight Area") # Waiting message
    )
      brushID
  })

},


  options = list(height = 800)
)
```

## Useful things

- [Shiny Gallery](https://shiny.rstudio.com/gallery/): You can find a gallery of different apps developed and deployed with `shiny`
- [Shiny widgets](https://shiny.rstudio.com/gallery/widget-gallery.html): All the possible inputs you can use in `shiny`
- [Shiny server](https://rstudio.com/products/shiny/shiny-server/): How to deploy your `shiny` app 
- [Shiny server for dummies](https://deanattali.com/2015/05/09/setup-rstudio-shiny-server-digital-ocean/#shiny-git) How to deploy your `shiny` app **for free** on your own server (but not necessarily in an easy way, sorry)
- [shinjs](https://deanattali.com/shinyjs/example): Animate your `shiny` app with some Javascript without knowing **anything** about Java
- [CSS for dummies](https://www.w3schools.com/css/): Make your app looks better with css





