First things first: activation of packages + load the data.

library(tidyverse)        # Just to be sure it's the first thing that is done...
library(shiny)
library(shinydashboard)
library(DT)
library(plotly)

load("movies.RData")

# Songs dataset: exercises

A simple dashboard is given below:

ui <- dashboardPage(                                                   # FULL PAGE: don't touch!
dashboardSidebar(sliderInput("pop", h4("Popularity"),
min = 0, max = 100,
value = c(0, 100), step = 1, sep = ""),
sliderInput("energy", h4("Energy"),
min = 0, max = 1,
value = c(0,1), step = 0.1, sep = "")
),
dashboardBody(plotOutput("plot"),                                  # Body
dataTableOutput("table")
)
)

server <- function(input, output){                                     # Server: computations!
data <- reactive(
songs %>% filter(popularity >= input$pop[1], popularity <= input$pop[2],
energy >= input$energy[1], energy <= input$energy[2])
)
output$table <- renderDataTable(data()) output$plot <- renderPlot({
data() %>%
group_by(artist) %>%
summarise(energy = mean(energy),
popularity = mean(popularity),
valence = mean(valence),
nb = n()) %>%
filter(nb > 2) %>%
ggplot(aes(x = energy, y = popularity, color = valence, label = artist)) +
geom_point(size = 0.7) + xlim(0,1)
})
}

# Run the app ----
shinyApp(ui = ui, server = server)  # Aggregates the app.

1. In the body, separate the two outputs (plot and table) and put each one of them in two separate tabs (one for the graph, one for the table). Also, transform the simple plot into a plotly graph. You can: increase the plot height and also change the size of the points (they are too big in plotly).

2. Boxes & rows & columns!
a) Within the tabBox of the body, add a new tabPanel (& choose a name).
b) In the server, create a new valueBox that counts the number of songs after the filter. You can find an icon if you want.
c) In the body and inside the new tab you created, insert the valueBox.
d) In the server, create a new infoBox that computes the average popularity of the songs after the filter.
e) In the body, insert a fluidRow. In this fluidRow, insert two columns (choose the widths you prefer) and inside each column, include the valueBox & infoBox generated by the server.

# Movies dataset

A simple dashboard is given below.

ui <- dashboardPage(                                                   # FULL PAGE: don't touch!
dashboardSidebar(sliderInput("duration", h4("Duration (min)"),
min = 37, max = 330,
value = c(37, 330), step = 1, sep = ""),
checkboxGroupInput("color", h4("Color"),
choices = list("Color" = "Color",
"Black and White" = "Black and White"),
selected = c("Color", "BW"))),
dashboardBody(plotOutput("plot"),
dataTableOutput("table"))
)

server <- function(input, output){                                     # Server: computations!
data <- reactive(                                                  # Reactive data!
movies %>% filter(duration >= input$duration[1], duration <= input$duration[2],
color %in% input$color) ) output$table <- renderDataTable(data())                            # Reactive!
output\$plot <- renderPlot(
data() %>% group_by(year) %>%
summarise(avg_score = mean(imdb_score)) %>%
ggplot(aes(x = year, y = avg_score)) + geom_line() + geom_point()
)
}

# Run the app ----
shinyApp(ui = ui, server = server)  # Aggregates the app.

1. In the body, separate the two outputs via two menus: one output in each menu. The table is a bit large: you can remove the actors’ names from the output.

2. Create two boxes:
a) In the body, inside the first menu, on top of the graph, add a fluidRow. (you can change the title of the tab later on)
b) Split this fluidRow into two components (columns).
c) In the server, create a info box that displays the movie with the highest IMDB score (along with this rating). Technical note: it should be unique. If conflict because several movies have max rating, pick one. d) Likewise, create an value box that computes the average budget (post filter: reactive) of the movies. Use a nice icon! e) Integrate the boxes into the fluidRow defined in a).