Reputation: 33
Edit: Thanks for the help, there were multiple issues with my code but the main issue was that I was missing an Observe statement, the following solved the problem:
get_ddf <- reactive({
filter(poskick, Name == input$player)
})
observe({
updateSelectInput(session, 'fixture', choices =levels(droplevels(get_ddf()$Event)) )
})
I want my Shiny app to have two selectInput dropdowns, the first one selecting a name and the second selcting from the events a person took part in, based on a subset created by the first input. sample data:
PLID Name x_coord y_coord x_coord_end y_coord_end action Event
7046 Sample Name1 35 37 34 25 4 23/07/11
7046 Sample Name1 21 11 0 0 4 23/07/11
7046 Sample Name1 49 60 56 8 4 23/07/11
7046 Sample Name1 46 56 72 34 4 23/07/11
7046 Sample Name1 58 49 24 58 4 23/07/11
7046 Sample Name1 87 57 42 52 4 23/07/11
7046 Sample Name1 14 58 18 37 4 23/07/11
7140 Sample Name2 38 14 11 11 4 23/07/11
7140 Sample Name2 11 11 11 11 4 23/07/11
7140 Sample Name2 56 8 56 8 4 23/07/11
my code UI:
library(shiny)
library(ggplot2)
poskick<-read.csv('poskicks.csv')
shinyUI(pageWithSidebar(
headerPanel("position map"),
sidebarPanel(
selectInput('player', 'Player', choices= attributes(poskick$Name)),
selectInput('fixture', 'Match', choices= attributes(firstsub()$Fixtu))
),
mainPanel(
plotOutput('plot')
)
))
Server Code:
library(shiny)
library(ggplot2)
poskick<-read.csv('poskicks.csv')
shinyServer(function(input, output) {
firstsub <- reactive({
subset(poskick, poskick$Name %in% input$player)
})
secondsub <- reactive({
subset(poskick, poskick$Fixtu %in% input$fixture & poskick$Name %in% input$player )
})
output$plot <- renderPlot({
p <- ggplot(data = secondsub()) + geom_segment(aes(x = x_coord, y = y_coord, xend = x_coord_end, yend = y_coord_end))
print(p) }, height=700)
})
Any suggestions are appreciated, Thank You.
Upvotes: 2
Views: 4334
Reputation: 1200
There were some issues in your code, like using Fixtu, which did not refer to anything. Also, I think that levels() is probably a better choice than attributes() for getting the unique values in a factor variable.
I find that it's helpful to use renderUI in the server.R file when you want the input into one widget to control the input into another. You can then put in return statements to prevent the widget from even showing up before it knows what options to offer. I do this by adding a "pick one" option that causes the next widget to not even show up. It would be better if you could make the selectInput default to NULL, but that is not an option.
Here is what I did:
server.R:
library(shiny)
library(ggplot2)
poskick<-read.csv('poskicks.csv')
shinyServer(function(input, output) {
output$Box1 = renderUI(selectInput('player',
'Player',
c(levels(poskick$Name),"pick one"),
"pick one")
)
output$Box2 = renderUI(
if (is.null(input$player) || input$player == "pick one"){return()
}else selectInput('fixture',
'Match',
c(levels(poskick$Event[which(poskick$Name == input$player)]),"pick one"),
"pick one")
)
subdata1 = reactive(poskick[which(poskick$Name == input$player),])
subdata2 = reactive(subdata1()[which(subdata1()$Event == input$fixture),])
output$plot <- renderPlot({
if (is.null(input$player) || is.null(input$fixture)){return()
} else if(input$player == "pick one" || input$fixture == "pick one") { return()
} else p <- ggplot(data = subdata2()) + geom_segment(aes(x = x_coord, y = y_coord, xend = x_coord_end, yend = y_coord_end))
print(p) })
})
ui.R:
library(shiny)
library(ggplot2)
shinyUI(pageWithSidebar(
headerPanel("position map"),
sidebarPanel(uiOutput("Box1"),uiOutput("Box2")),
mainPanel(plotOutput('plot')
)
))
Upvotes: 0