I am trying to build an R Shiny dashboard that displays a couple of pages for my exercise data. I am stuck on how to write the code for a dashboard of boxplots displaying the distribution of Calories burned per Trainer. What I want to happen is to have a selectInput that allows a user to select from a list of Trainers and this selection will update the boxplot. But, the variable selected will be a dummy variable where I have the selected Trainer boxplot compared against "All other" trainers side by side.
Here is an example of my dataset:
VisitNum VisitNumMonth Date ClassLength Calories AvgHR Location Trainer Visits_Trainer
1 1 12/15/19 56 602 128 A Mike 4
2 1 12/16/19 55 610 130 A Mike 4
3 2 01/04/20 52 550 120 A Sally 2
4 2 01/05/20 61 575 134 B Jennie 5
5 2 01/10/20 57 654 133 A Tim 1
6 2 01/17/20 55 592 119 A Rachael 1
7 3 02/04/20 50 632 129 B Jennie 5
8 3 02/22/20 48 630 125 B Jennie 5
9 3 02/28/20 59 609 136 B Marshall 6
10 4 03/03/20 53 598 134 A Mike 4
Here is my code:
library(RSQLite)
library(sqldf)
library(shiny)
library(shinydashboard)
library(DT)
library(ggplot2)
library(shiny)
data=as.data.frame(read_excel("mydata.xlsx",sheet=1))
#Create "Other" value for Trainers with less than 3 visits
data$Trainer2=ifelse(data$Visits_Trainer>=3,data$Trainer,"Other")
#Remove "Other" as possible selection in SelectInput
TrainerChoices=unique(data$Trainer2)
TrainerChoices=TrainerChoices[!TrainerChoices %in% "Other"]
Table1=sqldf("select VisitNum as 'Visit #', Date, Location as 'Studio', Trainer, Calories, AvgHR
from data
group by VisitNum, Date, Location, Trainer")
# Define UI for application
ui <- fluidPage(
titlePanel("Exercise Data Analysis"),
dashboardPage(
dashboardHeader(title=""),
dashboardSidebar(
sidebarMenu(
menuItem("All Data",
tabName = "AllData",
icon=icon("table")
),
menuItem("Trainer Boxplots",
tabName = "trainbox",
icon=icon("dumbbell")
),
selectInput(inputId = "trainerselect",label="Select a Trainer:",choices=TrainerChoices)
)
),
dashboardBody(
tabItems(
tabItem(
tabName = "AllData",
DTOutput("alldata")
),
tabItem(
tabName = "trainbox",
plotOutput("trainbox")
))
)
)
)
# Define server logic
server <- function(input, output) {
#----------ALL DATA TABLE----------#
output$alldata=renderDT({
datatable(Table1,options=list(pageLength=10,
lengthMenu=c(10,15,20,25)
),rownames = FALSE)
})
#---------- TRAINER BOXPLOTS ----------#
TrainData=reactive({
NewDummy=ifelse(data$Trainer2==input$TrainerChoices,input$TrainerChoices,"Other")
return(NewDummy)
})
output$trainbox=renderPlot({
plot=ggplot(TrainData(),aes(y=Calories,x=as.factor(NewDummy)))+geom_boxplot(aes(col=as.factor(NewDummy)))
plot
})
}
# Run the application
shinyApp(ui = ui, server = server)
When I run this code, the All Data tab appears just fine, but I can't get the Trainer Boxplots to show up appropriately. The page appears with an error that reads:
`data` must be a data frame, or other object coercible by `fortify()`, not a logical vector
Can someone please help point me in the right direction? Any help would be appreciated! Thank you!
I'm not sure this is what you intended, but perhaps this will be helpful.
First, your selectInput
in ui
has an id of trainerselect
, so you need to access through input$trainerselect
not TrainerChoices
.
Your TrainData
reactive expression will return a character value (a trainer name or "Other"); I assume you want to use data
for your source of data, not this. NewDummy
is a local variable in the reactive expression. Perhaps that is what you want from TrainData()
.
If I'm mistaken/confused, please let me know.
server <- function(input, output) {
#----------ALL DATA TABLE----------#
output$alldata=renderDT({
datatable(Table1,options=list(pageLength=10,
lengthMenu=c(10,15,20,25)
),rownames = FALSE)
})
#---------- TRAINER BOXPLOTS ----------#
TrainData=reactive({
NewDummy=ifelse(data$Trainer2==input$trainerselect,input$trainerselect,"Other")
return(NewDummy)
})
output$trainbox=renderPlot({
NewDummy <- TrainData()
plot=ggplot(data,aes(y=Calories,x=as.factor(NewDummy)))+
geom_boxplot(aes(col=as.factor(NewDummy)))
plot
})
}