How to dynamically populate dropdown box choices in shiny dashboard - r

I am developing one app in shiny dashboard in that I want to dynamically populate dropdown box once csv is uploaded. Dropdown will contain top 10 cities by user registrations which I get from following code.
final_data %>%
group_by(registrant_city) %>%
summarise(Total = n()) %>%
arrange(desc(Total)) %>%
top_n(n = 10)
These cities should go into dropdown box.
tabItem("email",
fluidRow(
box(
width = 4, status = "info",solidHeader = TRUE,
title = "Send Emails",
selectInput("email_select",
"Select Email Content",
choices = c("Price" = "price",
"Services" = "service"
)),
selectInput("cities",
"Select City",
choices = ??
))
))
Please help..

Use updateSelectInput in your server like below and set choices = NULL in your ui :
function(input, output, session) {
# If this isn't reactive you can put it in your global
choices_cities <- final_data %>%
group_by(registrant_city) %>%
summarise(Total = n()) %>%
arrange(desc(Total)) %>%
top_n(n = 10)
updateSelectInput(session = session, inputId = "cities", choices = choices_cities$registrant_city)
}
Or if final_data is reactive something like this :
function(input, output, session) {
choices_cities <- reactive({
final_data %>%
group_by(registrant_city) %>%
summarise(Total = n()) %>%
arrange(desc(Total)) %>%
top_n(n = 10)
})
observeEvent(choices_cities(), {
updateSelectInput(session = session, inputId = "cities", choices = choices_cities()$registrant_city)
})
}
A working example :
library("dplyr")
library("shiny")
data("world.cities", package = "maps")
ui <- fluidPage(
sliderInput(inputId = "n", label = "n", min = 10, max = 30, value = 10),
selectInput(inputId = "cities", label = "Select City", choices = NULL)
)
server <- function(input, output, session) {
choices_cities <- reactive({
choices_cities <- world.cities %>%
arrange(desc(pop)) %>%
top_n(n = input$n, wt = pop)
})
observe({
updateSelectInput(session = session, inputId = "cities", choices = choices_cities()$name)
})
}
shinyApp(ui = ui, server = server)

I got the answer for above. Here is what I did.
ui.R
uiOutput("city_dropdown")
And my server.R looks like following
output$city_dropdown <- renderUI({
city <- reg_city(final_data)
city <- city$registrant_city
city <- as.list(city)
selectInput("email_select",
"Select Email Content",
choices = city
)
})
reg_city() gives me the top 10 cities which I want to populate into drop down box,then converting it to a list gives me desired output.

Related

How to render Data Table in R Shiny using Dropdown input to filter Dataframe?

In continuation to my previous post where this was applied on map, I am trying to filter a table in R Shiny using Dropdown input: How to build dynamic Leaflet Map in RShiny?
Code:
library(shiny)
library(shinydashboard)
library(tidyverse)
library(leaflet)
library(readxl)
library(RCurl)
library(DT)
URL <- "https://www.mohfw.gov.in/pdf/PMJAYPRIVATEHOSPITALSCONSOLIDATED.xlsx"
download.file(URL, destfile = "../../timesnow_PMJAYPRIVATEHOSPITALSCONSOLIDATED.xlsx",method = "curl")
# Data
ind_vaccination_center <- readxl::read_xlsx(path = "../../timesnow_PMJAYPRIVATEHOSPITALSCONSOLIDATED.xlsx",
sheet = 1)
ind_vaccination_leaflet <- ind_vaccination_center %>%
mutate(label_display = paste(
"<h2>", ind_vaccination_center$`Name of the Vaccination Site*`, "</h2>",
"<h4>",ind_vaccination_center$`District*`,",", ind_vaccination_center$`State*`, "</h4>",
"<p>", "Address: ", ind_vaccination_center$Address,",", ind_vaccination_center$`PinCode*`, "</p>",
"<p>", "Mobile: ", ind_vaccination_center$`Mobile Number`, "</p>",
"<p>", "Contact Person: ", ind_vaccination_center$`Contact Person`, "</p>"
)
)
# Define UI for application
ui <- fluidPage(
# Application title
titlePanel("Covid19 Vaccination Centers in India"),
# Sidebar with a Dropdown
sidebarLayout(
sidebarPanel(
selectInput(inputId = "state_selection",
label = "Select State",
choices = ind_vaccination_center$`State*`),
h3("List of Vaccination Centers is plotted on Map & also listed in searchable table."),
"source of list:",
a("https://www.timesnownews.com/india/article/covid-19-vaccination-in-uttar-pradesh-check-complete-list-of-govt-and-private-hospitals-for-jab/726412"),
br(),
br(),
a("https://www.oneindia.com/india/full-list-of-private-hospitals-where-the-covid-19-vaccine-will-be-administered-3223706.html"),
br(),
br(),
"P.S - There might be more center's added to this list, kindly recheck from other sources as well like:",
br(),
a("https://www.cowin.gov.in/home")
),
# Show Map & table
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Map", leafletOutput("map",height = 800, width = "100%")),
tabPanel("Data Table", tableOutput("mytable"))
)
)
)
)
# Define server logic
server <- function(input, output) {
# solution from: https://stackoverflow.com/questions/66732758/how-to-build-dynamic-leaflet-map-in-rshiny/66733086#66733086
output$map <- renderLeaflet({
req(input$state_selection)
data <- ind_vaccination_leaflet %>%
filter(`State*` == input$state_selection)
# Creating map object & adding layers
leaflet(data) %>%
setView(lat = 26.64510, lng = 80.17012, zoom = 4) %>%
addTiles(group = "OSM") %>%
addProviderTiles(providers$CartoDB.DarkMatter, group = "Dark") %>%
addProviderTiles(providers$CartoDB.Positron, group = "Light") %>%
addProviderTiles("Stamen.Terrain", group = "Terrain") %>%
addProviderTiles("Esri.WorldImagery", group = "WorldImagery") %>%
addLayersControl(baseGroups = c("OSM","WorldImagery","Dark","Light","Terrain")) %>%
addCircleMarkers(
lng = ~`Longitude*`,
lat = ~`Latitude*`,
label = lapply(data$label_display, htmltools::HTML),
color = "midnightblue",
weight = 1,
radius = 8
)%>%
addMiniMap(tiles = providers$OpenStreetMap, width = 120, height=80)
})
output$mytable = DT::renderDataTable({
req(input$state_selection)
data <- ind_vaccination_leaflet %>%
filter(`State*` == input$state_selection)
data
})
}
# Run the application
shinyApp(ui = ui, server = server)
You need to do two changes.
tabPanel("Data Table", dataTableOutput("mytable"))
and
output$mytable = DT::renderDataTable({
req(input$state_selection)
data <- ind_vaccination_leaflet %>%
filter(`State*` == input$state_selection)
datatable(data)
})

Shiny - adding/appending user-selected observations to a list of observations to analyze

The user interface of the Shiny app I'm working on is supposed to work in the following manner:
User finds the desired observation(s) after applying a set of filters.
User clicks "Add" action button, so selected observation(s) are added to a running list/vector/etc of observations to be analyzed.
User modifies filters to find other observations which are to be included as well.
Loop back to step 1 as many times as user desires.
I cannot seem to find a way to save this list of observations to be analyzed. In the example I attached, the "observation ID" is the name of the model of the car (mtcars is used). I also did not include any data analysis, since I do not think that's necessary. In essence, the entire dataset (mtcars) should be filtered using dplyr in a reactive environment to only include the running list of selected observations.
Here's the code:
data("mtcars")
mtcars$model <- rownames(mtcars)
ui <- fluidPage(
titlePanel("sample"),
sidebarLayout(
sidebarPanel(
uiOutput("disp"),
uiOutput("qsec"),
uiOutput("model"),
actionButton("add", "Add"),
uiOutput("selectedModel")
),
mainPanel(
plotOutput("data_analysis")
)
)
)
server <- function(input, output) {
output$disp <- renderUI({
selectInput(
"disp_sel",
"Select disp:",
unique(mtcars$disp),
selected = NULL,
multiple = T,
selectize = T
)
})
output$qsec <- renderUI({
temp = mtcars
if (!is.null(input$disp_sel)){temp = temp %>% filter(disp %in% input$disp_sel)}
selectInput(
"qsec_sel",
"Select qsec:",
unique(temp$qsec),
selected = NULL,
multiple = T,
selectize = T
)
})
output$model <- renderUI({
temp = mtcars
if (!is.null(input$disp_sel)){temp = temp %>% filter(disp %in% input$disp_sel)}
if (!is.null(input$qsec_sel)){temp = temp %>% filter(qsec %in% input$qsec_sel)}
selectInput(
"model_sel",
"Select model:",
unique(temp$model),
selected = NULL,
multiple = T,
selectize = T
)
})
output$selectedModel <- renderUI({
req(input$add)
selectInput(
"list_of_selections",
"Selected models:",
unique(mtcars$model),
selected = NULL, # this should change when "Add" is pressed
multiple = T,
selectize = T
)
})
r_data = eventReactive(input$add,{
mtcars %>% filter(model %in% input$list_of_selections)
})
output$data_analysis <- renderPlot({
# do something with r_data (filtered data)
})
}
# Run the application
shinyApp(ui = ui, server = server)
I've looked into modular code, reactive lists, and other stuff I don't even remember... Any help is greatly appreciated.
Try this
data("mtcars")
mtcars$model <- rownames(mtcars)
df1 <- mtcars
ui <- fluidPage(
titlePanel("sample"),
sidebarLayout(
sidebarPanel(
uiOutput("disp"),
uiOutput("qsec"),
uiOutput("model"),
actionButton("add", "Add"),
uiOutput("selectedModel")
),
mainPanel(
DTOutput("selecteddata"),
plotOutput("data_analysis")
)
)
)
server <- function(input, output) {
output$disp <- renderUI({
selectInput(
"disp_sel",
"Select disp:",
unique(mtcars$disp),
selected = NULL,
multiple = T,
selectize = T
)
})
output$qsec <- renderUI({
temp = mtcars
if (!is.null(input$disp_sel)){temp = temp %>% filter(disp %in% input$disp_sel)}
selectInput(
"qsec_sel",
"Select qsec:",
unique(temp$qsec),
selected = NULL,
multiple = T,
selectize = T
)
})
output$model <- renderUI({
temp = mtcars
if (!is.null(input$disp_sel)){temp = temp %>% filter(disp %in% input$disp_sel)}
if (!is.null(input$qsec_sel)){temp = temp %>% filter(qsec %in% input$qsec_sel)}
selectInput(
"model_sel",
"Select model:",
unique(temp$model),
selected = NULL,
multiple = T,
selectize = T
)
})
selected_data <- eventReactive(input$add,{
df1 %>% filter(model %in% input$model_sel)
})
output$selecteddata <- renderDT(
selected_data(), # reactive data
class = "display nowrap compact", # style
filter = "top", # location of column filters
options = list( # options
scrollX = TRUE # allow user to scroll wide tables horizontally
)
)
output$selectedModel <- renderUI({
req(input$add)
selectInput(
"list_of_selections",
"Selected models:",
choices = unique(selected_data()$model),
selected = unique(selected_data()$model), # this should change when "Add" is pressed
multiple = T,
selectize = T
)
})
r_data = eventReactive(input$add,{
mtcars %>% filter(model %in% input$list_of_selections)
})
output$data_analysis <- renderPlot({
ggplot(data=selected_data(), aes(x=disp, y=qsec)) + geom_point()
# do something with r_data (filtered data)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Found the answer. I included
selected <- reactiveValues(s = NULL)
observeEvent(input$add,{selected$s = c(selected$s, input$model})
into the server part. Then the selected models are stored in selected$s.

DT output takes me to 1st page when i edit a reactive DT

I have a toy version of my code below. I have one of the columns (column 7) in my shiny DT output as editable. When i edit the a cell of the column it takes me back to the first row of of the column. I checked the data table object in environment, the edited cell does get update. So, that is good. But i want to stay on the same page after editing the cell. This is because a user may have applied a few filters to reach a certain page and then when he edits a cell he would like to continue from there rather than going back to start.
I am new to R so any help would be greatly appreciated.
I am using DT 0.7
My data frame has 7 columns: Continent, State, Country, Date, Rate (Pollution), Vehicles, Remark (editable column)
A user can filter the table output by select input, range and slider input. I want to make that output editable.
Thanks in advance!
library(shiny)
library(DT)
ui <- navbarPage("Hello",
tabPanel("Tab1",
sidebarLayout(
sidebarPanel( width = 4,
selectInput("continent", "Select:",
choices = ""),
selectInput("country" , "Select:",
choices = ""),
selectInput("state" , "Select:",
choices = ""),
dateRangeInput("date", "Select:",
startview = "month",
minview = "months",
maxview = "decades",
start = as.Date('1999-01-01'),
end = as.Date(today()),
separator = "-"),
sliderInput("rate", "Select:",
min = 1, max = 5, value = c(1,5),
dragRange = TRUE)),
mainPanel(
tabsetPanel(
tabPanel("Analysis",
dataTableOutput("Table1")
)))))
#server
server <- function(input, output, session)
{
observe({
updateSelectInput(session, "continent",
choices = c("All", unique(Df$Continent)))
})
observe({
updateSelectInput(session, "country",
choices = c("All", Df %>%
filter(`Continent` == input$continent) %>%
select(Country)))
})
observe({
updateSelectInput(session, "state",
choices = c("All", Df %>%
filter(`Continent` == input$continent &
`Country` == input$country) %>%
select(State)))
})
#create reactive table
RecTable <- reactive({
Df
if(input$continent != "All") {
Df <- Df[Df$Continent == input$continent,]
}
if(input$country != "All") {
Df <- Df[Df$Country == input$country,]
}
if(input$state != "All") {
Df <- Df[Df$State == input$state,]
}
Df <- Df %>%
filter(Date >= input$date[1] & Date <= input$date[2]) %>%
filter(Rate >= input$rate[1] & Rate <= input$rate[2])
Df})
output$Table1 <- DT::renderDT({
DT::datatable(RecTable(),
rownames = FALSE ,
editable = list(target = 'cell', disable = list(columns = c(0:6))))
})
proxy1 <- dataTableProxy('Table1')
observeEvent(input$Table1_cell_edit, {
Df <<- editData(Df, input$Table1_cell_edit, 'Table1', rownames = FALSE, resetPaging = FALSE)
})}
#run
shinyApp(ui = ui, server = server)

updatePickerInput default select all choices

I know that there is a very similar question on StackExchange (pickerInput default select all choices), however, the solution can not be applied to my problem.
I have a updatePickerInput which is based on two Inputs. on the updatePickerInput I have the selectAll and clearAll buttons from shinyWidgets. I want selectAll to be the default, but since it is dynamically, I dont know how to pass my choices into the selected option.
Here is my relevant ui code:
radioButtons(inputId = 'selected_group', label = 'group', choices = '')
This is my observeEvent code:
observeEvent(c(input$selected_tab,input$selected_group),{
req(input$selected_group)
updatePickerInput(
session,
'selected_subgroup',
choices = df %>%
filter(tab == input$selected_tab) %>%
filter(group == input$selected_group) %>%
select(subgroup) %>%
distinct(subgroup) %>%
arrange(subgroup) %>%
.[[1]]
)
})
To have all options selected dynamically you'll need to pass the same information to updatePickerInput's choices and selected arguments:
library(shiny)
library(datasets)
library(shinyWidgets)
statesDF <- data.frame(region = state.region, name = state.name, area = state.area, stringsAsFactors = FALSE)
ui <- fluidPage(
radioButtons(inputId = 'selected_group', label = 'group', choices = unique(statesDF$region)),
pickerInput(inputId = 'selected_subgroup', label = 'subgroup', choices = NULL, selected = NULL, multiple = TRUE)
)
server <- function(input, output, session) {
filteredChoices <- reactive({
statesDF$name[statesDF$region == input$selected_group]
})
observeEvent(filteredChoices(), {
updatePickerInput(session, inputId = 'selected_subgroup', label = 'subgroup', choices = filteredChoices(), selected = filteredChoices())
})
}
shinyApp(ui = ui, server = server)

Chart display for two R Versions

I am trying to run the code below on two R versions, and do not have the same display. I want to display one value ('10') with one category only ('Feb') and this is not working for one of the versions, here you can see the output comparison:
And here is the code :
library("shiny")
library("highcharter")
data(citytemp)
ui <- fluidPage(
h1("Highcharter EXAMPLE"),
fluidRow(
column(width = 8,
highchartOutput("hcontainer",height = "500px")
),
selectInput("option", label = "", width = "100%",
choices = c("Tokyo", "NY"))
)
)
server <- function(input, output) {
data <- citytemp[,c("month","tokyo","new_york")]
data = data[data$month%in%c("Dec","Jan","Feb","Mar"),]
choose_Option <- reactive({
sort_option <- input$option
if(sort_option=="Tokyo"){
data = data[order(data$tokyo),]
}
else{
data = data[order(data$new_york),]
}
return(data)
})
output$hcontainer <- renderHighchart({
data = choose_Option()
data = data[data$month=="Feb",]
chart <- highchart() %>%
hc_chart(type = "bar") %>%
hc_title(text = "Monthly Average Temperature for main cities") %>%
hc_subtitle(text = "Source: WorldClimate.com") %>%
hc_xAxis(categories = data$month) %>%
hc_yAxis(title = list(text = "Temperature (C)"),stackLabels=list(enabled=FALSE))%>%
hc_plotOptions(
series=list(stacking="normal"))
hc <- chart %>% hc_add_series(yAxis=0,name="Tokyo",data = 10,colorByPoint=TRUE,dataLabels = list(enabled = TRUE) )
return(hc)
})
}
shinyApp(ui = ui, server = server)
Do you have any suggestions about how I could correct my display in the version 3.2.0 ? Thank you, best regards, Madzia

Resources