2

I'm working on an R Shiny App that plots monthly percent changes in political party registrations. I'm still pretty new to interactive web apps (and Stack Overflow), and just haven't been able to find answers to these quesions -- thanks/sorry in advance.

In an older version of the app (here) I was able to let the user select the region, and I had manually put % monthly changes directly in the original dataframe.

What I'm trying to do now is enable the app to:

  1. Allow the user to choose/input a specific political party, which are each stored as columns in my df
  2. Then have the app itself calculate and add a new column with % monthly change for the selected party & region, so I don't have to do that manually for each party in the original df.

I can't figure out how to let the user select by party name / df column. I've tried:

selectizeInput(inputId = 'Party', label= 'Party',
                             choices = colnames(df_2016)

but that doesn't work.

I also have no clue how to do 2 lol.

Thanks in advance for any help you can provide; would realy appreciate if anyone could point me in the right direction or toward resources to learn how to do this. The relevant files are here if needed.

Here's the code for my UI and Server:

UI:

library(shiny)
library(shinydashboard)
library(ggplot2)
library(dplyr)
library(ggthemes)
library(shinythemes)
library(lubridate)

df_2016 = read.csv('df_2016.csv')
df_2020 = read.csv('df_2020.csv')

# Define UI for application
fluidPage(theme = shinytheme('cerulean'),
          
          # Application title
          titlePanel("NJ Voter Registration"),
          
          sidebarLayout(
              # Drop-down menu with region options
              
              mainPanel(
                  selectizeInput(inputId = 'County', label= 'Region',
                                 choices = df_2016$County),
            
              ),
              
              mainPanel(
                  tabsetPanel(
                      
                      tabPanel('Home',
                               "Data is sourced from the NJ Division of Elections Voter Registration Statistics Archive, which can be accessed at https://www.state.nj.us/state/elections/election-information-svrs.shtml",
                               "Please use the drop-down menu above to select whether to view statewide statistics, or data for a specific county.",
                      ),
                      
                      tabPanel('2016 Data',
                               'The dataframe for your selection is provided here.',
                               tableOutput('tableonesix')
                      ),

                      tabPanel('2020 Data',
                               'The dataframe for your selection is provided here.',
                               tableOutput('tabletwozero')
                      )
                      
                  )
              )
          )
          
)

Server:

library(shiny)
library(shinydashboard)
library(ggplot2)
library(dplyr)
library(ggthemes)
library(shinythemes)
library(lubridate)

df_2016 = read.csv('df_2016.csv')
df_2020 = read.csv('df_2020.csv')


function(input, output) {
    
    output$tableonesix=renderTable(
        df_2016 %>%
            filter(County==input$County)
    )
    
    output$tabletwozero=renderTable(
        df_2020 %>%
            filter(County==input$County)
    )
    
}
1
  • What error message are you getting? Your selectizeInput looks wrong, 1. you probably want unique(df_2016$County), 2. put a initially selected value by adding select = ... otherwise the default is NULL. Also, this is unrelated -- but you should move the copy-pasted code at the top of ui.R and server.R to a new file called global.R. This is a better practice for loading libraries and data. Edit: it looks like the default is actually the first value in the list -- so I don't think this is the error. Commented Jan 22, 2021 at 20:45

1 Answer 1

2

This sample app shows how it can be done.

  • Your idea using selecizeInput was correct. However, I would not recommend declaring the data frames as global variables. The usual approach would be to keep the data in the server and feed only the data we want to show to the client.
  • Use updateSelectizeInput to set the choices once the data frames have been loaded. The observerwill do that every time dfchanges.
  • Finally, renderTablefilters the relevant part of the data frame and sends it to the client.
library(shiny)

ui <- fluidPage(
    titlePanel("Party Sample"),

    sidebarLayout(
        sidebarPanel(
            selectizeInput("Party", "Party", choices = NULL),
            selectizeInput("County", label= "Region", choices = NULL),
        ),

        mainPanel(
           tableOutput("tableonesix")
        )
    )
)

# 
server <- function(input, output, session) {
  # DUMMY DATA
  df <- reactiveVal(data.frame(Democrats = 1:10, Republicans = 10:1, 
                               Libertarians = 1:10, GreenParty = 10:1,
                               County = sample(c("A", "B", "C"), 10, TRUE)))

  observe({
    # select only the party columns 1-4; 5 is the county column
    updateSelectizeInput(session, "Party", choices = colnames(df()[1:4])) 
    # Get counties without duplicates
    updateSelectizeInput(session, "County", choices = unique(df()$County))
  })
  
  output$tableonesix <- renderTable({
    # Do not run unless selects have a usable value
    req(input$Party, input$County)
    # Select: here in base R (not dplyr)
    df()[df()$County == input$County, input$Party]
  })
  
}

# Run the application 
shinyApp(ui = ui, server = server)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.