I have two SelectInput Drowpdown controls but I can't make the first one reactive. My second control works fine. Consider this small toy example: On my first dropdown (which it doesn't work), I have 5 options. I want this control to react when the selection changes. I basically want both of my dropdown controls to be reactive to the type of model or type of graphic selected.
library(shiny)
library(ggplot2)
library(tidyverse)
library(shinythemes)
library(plotly)
library(scales)
library(shinyWidgets)
library(shinydashboard)
library(DT)
library(shinyjs)
library(shinycssloaders)
# Define input choices
type <- c("lambda","indices")
model <- c("Output_21yr_noStock","Output_21yr_yesStock","Output_82yr_bdc_noStock","Output_82yr_ppp_noStock","Output_82yr_woa_nostock")
#############Lambda######Table
olddir <- getwd()
table <- structure(list(year = 1991:2010, lambda = c(0.73392, 0.75659,
1.33665, 1.06641, 1.27145, 1.01077, 0.66983, 1.6427, 0.96414,
0.55648, 0.50556, 1.08024, 0.8706, 0.89665, 1.00807, 1.01967,
0.73131, 1.1161, 1.10219, 1.35085)), row.names = c(NA, -20L), class = "data.frame")
table
# Define UI
ui <- fluidPage(
useShinyjs(), # to initialise shiny
theme = shinytheme("superhero"),
navbarPage("Species: Pink Salmon",
windowTitle = "Salmon Model Application",
sidebarPanel(width = 3,
h3("Select Model Output"),
selectInput(inputId = "model",
label = "Model to Run",
choices = model,
selected = "Output_21yr_noStock"),
selectInput(inputId = "graphtype",
label = "Graphic",
choices = type,
selected = "lambda"),
#Slider to select custom years
chooseSliderSkin("Square"),
setSliderColor(c("LightSeaGreen ", "#FF4500", "", "Teal"), c(1, 2, 4)),
#tags$style(type = "text/css", ".irs-grid-pol.small {height: 0px;}"), #hide small ticks
sliderInput(inputId = "Yearslider",
label = "Years to plot",
sep = "",
min = min(table$year), #min and max values of spawner_maturity table6
max = max(table$year),
step = 1,
value = c(min = min(table$year),max = max(table$year))
)),
#Graphic Area mainPanel. Graphic on top and table right below it
mainPanel(
plotOutput("plot")
)))
server<- function (input, output, session) {
session$onSessionEnded(function() {
stopApp()
})
plot_data <- reactive({
table[table$year >= input$Yearslider[1] & table$year <= input$Yearslider[2], ]
})
dataInput <- reactive({
switch(input$graphtype,
"lambda" = plot_data())
})
#How can I make the "model" SelectInput drowpdown control reactive when I select a different model? The "modelInput" below is not reacting.
modelInput <- reactive({
switch(input$model,
"Output_21yr_noStock" = input$model,
"Output_21yr_yesStock" = input$model)
})
# Plot data
create_plots <- reactive({
theme_set(theme_classic(14))
xlabels <- c(min(table$year):max(table$year))
if (input$graphtype == "lambda") {
ggplot(plot_data(),aes(year,lambda)) + geom_line(size=1.5,colour="blue") +
geom_point(colour="orange",size=4) + geom_hline(yintercept=1,color="hotpink",linetype="dashed") +
scale_x_continuous("",breaks = xlabels) + legendTheme +
theme(axis.text.x = element_text(angle = 45, vjust = 0.5)) +
labs(x="",y=expression("Lambda ("~lambda *")"),
title= paste0("Modeled Population growth rate of Delta Smelt cohort years ",
table[table$year >= input$Yearslider[1] & table$year <= input$Yearslider[2], ]))
}
})
#Render plots
output$plot <- renderPlot({
create_plots()
},height = 475)
}
# Run the application
shinyApp(ui = ui, server = server)
Related
I would like click-select points and group them based on color.
I can save selected points with color information into a new data frame and plot it, however I would like to keep track and see what was already selected on the interactive plot.
How can I show/label already selected points or make it permanent after "Add selection"?
library(shiny)
library(tidyverse)
library(DT)
library(colourpicker)
ui = fluidPage(
colourInput("col", "Select colour", "purple"),
actionButton("addToDT", "Add selection", icon = icon("plus")), hr(),
plotOutput("plot", click = "plot_click", dblclick = "plot_reset"),
DT::dataTableOutput('plot_DT'), hr(),
textOutput("clickcoord"),
DT::dataTableOutput('final_DT'),
plotOutput("plotSelected")
)
server = function(input, output, session) {
selectedPoint = reactiveVal(rep(FALSE, nrow(mtcars)))
output$clickcoord <- renderPrint({
print(input$plot_click)
})
observeEvent(input$plot_click, {
clicked = nearPoints(mtcars, input$plot_click, allRows = TRUE)$selected_
selectedPoint(clicked | selectedPoint())
})
observeEvent(input$plot_reset, {
selectedPoint(rep(FALSE, nrow(mtcars)))
})
output$plot_DT = DT::renderDataTable({
mtcars$sel = selectedPoint()
mtcars = dplyr::filter(mtcars, sel == TRUE) %>% mutate(group_color = input$col)
})
final_DT = reactiveValues()
final_DT$df = data.frame()
FinalData = eventReactive(input$addToDT, {
mtcars$sel = selectedPoint()
mtcars = dplyr::filter(mtcars, sel == TRUE) %>% mutate(group_color = input$col)
final_DT$df = bind_rows(final_DT$df, mtcars)
})
output$final_DT = renderDataTable({FinalData()})
output$plot = renderPlot({
mtcars$sel = selectedPoint()
ggplot(mtcars, aes(wt, mpg, color = mtcars$sel, fill=mpg)) +
geom_point(shape = 21, size = 6, stroke = 2) +
scale_color_manual(values = c("#ffffff00", input$col)) +
scale_fill_viridis_c() +
theme_bw()
})
output$plotSelected = renderPlot({
sel_df = FinalData()
ggplot(sel_df, aes(wt, mpg, fill = group_color, colour = group_color)) +
geom_point(shape = 21, size = 6, stroke = 2) +
scale_color_manual(values = unique(sel_df$group_color)) +
scale_fill_manual(values = unique(sel_df$group_color)) +
theme_bw()
})
observeEvent(input$addToDT, {
selectedPoint(rep(FALSE, nrow(mtcars)))
})
}
shinyApp(ui, server)
I think this is the "crux" of what your are looking for. I used a very similar example that I found in the help for entitled:
A demonstration of clicking, hovering, and brushing
(https://shiny.rstudio.com/reference/shiny/0.13.1/plotoutput)
It is very similar to your example.
I create a matrix of T/F elements where the rows are the observations and the columns are in which batch the observation is selected. So when you launch the whole matrix is False, but as you click on observations the switch to positive in the first column. Then if you click addSelection and continue you start switching the observations in the next column.
Could you confirm that this what you are looking for?
Below is the code.
shinyApp(
ui = basicPage(
fluidRow(
column(
width = 4,
plotOutput("plot",
height = 300,
click = "plot_click", # Equiv, to click=clickOpts(id='plot_click')
),
actionButton("addToDT", "Add selection", icon = icon("plus")), hr(),
h4("Clicked points"),
tableOutput("plot_clickedpoints"),
),
column(
width = 4,
verbatimTextOutput("counter"),
),
)
),
server = function(input, output, session) {
data <- reactive({
input$newplot
# Add a little noise to the cars data so the points move
cars + rnorm(nrow(cars))
})
output$plot <- renderPlot({
d <- data()
plot(d$speed, d$dist, main = paste("No of Sets Chosen", input$addToDT))
})
output$plot_clickinfo <- renderPrint({
cat("Click:
")
str(input$plot_click)
})
selectedPoints <- reactiveVal(rep(FALSE, nrow(cars)))
selectionMatrix <- reactiveVal(matrix(data = F, nrow = nrow(cars), ncol = 7))
observeEvent(input$plot_click, {
clicked <- nearPoints(data(), input$plot_click, "speed", "dist", allRows = TRUE)$selected
selectedPoints(clicked | selectedPoints())
tmp <- unlist(selectionMatrix())
tmp[, (input$addToDT + 1)] <- selectedPoints()
selectionMatrix(tmp)
})
observeEvent(input$addToDT, {
selectedPoints(rep(FALSE, nrow(cars)))
})
output$plot_clickedpoints <- renderTable({
# if (input$addToDT==0) {
res <- selectionMatrix()
return(res)
})
}
)
New to shiny. I am trying to create a plot based on chosen x and y values. Basically, whatever the user selects for the select1 and select2 selectInput function will graph it accordingly. My original data has many columns, not just two. When I try to graph very specific things, my code works great, but when I try to graph what the user "selects" it does not work.
library(shiny)
library(readr)
library(ggplot2)
library(dplyr)
data0 <- rnorm(n = 10, mean = 100, sd = 5)
data1 <- rnorm(n = 10, mean = 50, sd = 10)
data2 <- data.frame(data0, data1)
attach(data2)
ui <- fluidPage(
selectInput(inputId = "select1",
label = "select the x-axis",
choices = c(" ", "data0", "data1")
),
selectInput(inputId = "select2",
label = "select the y-axis",
choices = c(" ", "data0", "data1")
),
submitButton(text = "Apply Changes", icon = NULL, width = NULL),
plotOutput(outputId = "myplot")
)
server <- function(input, output) {
output$myplot <- renderPlot({
data2 %>%
ggplot(aes(input$select1 ~ input$select2))+
geom_point(alpha = 0.8)
})
}
shinyApp(ui = ui, server = server)
I had to add ggplot(aes(x = get(paste(input$select1)), y = get(paste(input$select2)) to make the input selects work.
library(shiny)
library(readr)
library(ggplot2)
library(dplyr)
data0 <- read_csv("DeltaX_Soil_Properties_Fall2020_Spring2021_Fall2021.csv")
data1 <- data0[!(data0$time_marker_sampled == "-9999"),]
attach(data1)
ui <- fluidPage(
selectInput(inputId = "select1",
label = "select the x-axis",
choices = c(" ", "elevation_navd88", "sediment_accretion", "days_between_sampling_and_deployment", "normalized_accretion", "soil_bulk_density", "soil_organic_matter_content", "soil_organic_carbon", "soil_organic_carbon_density")
),
selectInput(inputId = "select2",
label = "select the y-axis",
choices = c(" ", "elevation_navd88", "sediment_accretion", "days_between_sampling_and_deployment", "normalized_accretion", "soil_bulk_density", "soil_organic_matter_content", "soil_organic_carbon", "soil_organic_carbon_density")
),
submitButton(text = "Apply Changes", icon = NULL, width = NULL),
plotOutput(outputId = "myplot")
)
server <- function(input, output) {
output$myplot <- renderPlot({
data1 %>%
ggplot(aes(x = get(paste(input$select1)), y = get(paste(input$select2)), col = hydrogeomorphic_zone))+
geom_point(alpha = 0.8)
})
}
shinyApp(ui = ui, server = server)
If you want to use a variable as x or y, you can alternatively use aes_() instead of aes().
This would then result in:
ggplot(aes_(x = input$select1, y = input$select2))
Beware, that you need to add a tilde if you want to use a normal column name with aes_(), e.g.:
ggplot(aes_(x = ~elevation_navd88, y = input$select2))
Good morning,
in my dashboard I inserted a checkbox to select one or more output to display. In the ui I entered the checkbox and in the server all the conditions (if ... else if ...). When I launch the app it only shows me a plot, even when I select more than one choice in the checkbox. In addition it gives me this error in console:
"Warning in if (input$checkGroup == 1) { :the condition has length > 1 and only the first element will be used"
I suppose it's telling me that I can't handle more than one choice, how do I view all the plots I choose?
ui <- fluidPage(titlePanel("IULM Dashboard"), sidebarLayout(sidebarPanel(
selectInput("selection", "Choose a Dataset:",
choices = datasets),
("Barplot","Network",'Wordcloud', "LDA-Latent topic"),
#selected = "Barplot", inline = TRUE),
checkboxGroupInput("checkGroup", label = ("Checkbox group"),
choices = list("Barplot" = 1, "Network" = 2), selected = 1, inline = TRUE),
actionButton("update", "Change"))
, mainPanel(
uiOutput("plot")))
server <- function(input, output){
datasetInput <- reactive({
input$update
isolate({
withProgress({
setProgress(message = "Processing corpus...")
getTermMatrix(input$selection)
})
})
})
output$plot <- renderUI({
if(input$checkGroup== 1 ){
output$barplot <- renderPlot({
v=datasetInput()
dtm1 = removeSparseTerms(v, 0.992)
freq <- colSums(as.matrix(dtm1))
wf = data.frame(term = names(freq), occurrences = freq)
wf <- wf[order(wf$occurrences, decreasing = TRUE),]
wf2 = subset(wf[1:input$maxB,])
ggplot(wf2, aes(term, occurrences)) +
geom_bar(stat="identity", fill="darkred", colour="black", width=0.5)+
theme(axis.text.x=element_text(angle=45, hjust=1))+
ggtitle("Word barplot")})
plotOutput(outputId = "barplot", width = 600, height = 400)
}
else if(input$checkGroup== 2 ){
output$network <- renderPlot({
v=datasetInput()
dtm1 = removeSparseTerms(v, 0.992)
rowTotals <- apply(dtm1 , 1, sum)
dtm2 <- dtm1[rowTotals> 0, ]
wdtm <- weightTf(dtm2)
dtm1 <- removeSparseTerms(wdtm, 0.96)
dfm <- as.dfm(dtm1)
textplot_network(dfm, min_freq = 0.5, omit_isolated = TRUE,
edge_color = "#1F78B4", edge_alpha = 0.5, edge_size = 2,
vertex_color = "#4D4D4D", vertex_size = 2,
vertex_labelsize = 5, offset = NULL)})
plotOutput(outputId = "network", width = 600, height = 600)}
})
}
shinyApp(ui = ui, server = server)
You can try
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput("variable", "Variables to show:",
c("Cylinders" = "cyl",
"Transmission" = "am",
"Gears" = "gear"))
),
mainPanel(
uiOutput("plots")
)))
server <- function(input, output) {
output$plots <- renderUI({
req(input$variable)
output = tagList()
if(any(input$variable %in% "cyl")){
tmp <- mtcars$cyl
output[[1]] <- renderPlot({plot(mtcars$mpg, tmp)})
}
if(any(input$variable %in% "am")){
tmp <- mtcars$am
output[[2]] <- renderPlot({boxplot(mtcars$mpg, tmp)})
}
output
})
}
shinyApp(ui = ui, server = server)
I have this shiny code and the plot is not showing for some reason. Can you please extend me a hand?
Is a basic shiny plot to render in the Main Panel. Checked loads of times and still not plotting.
library(shiny)
library(plotly)
library(ggplot2)
ui <- fluidPage(
(titlePanel("APP & MEP | Size (m2) ~ Hours", windowTitle = "app")),
sidebarLayout(
sidebarPanel(
checkboxGroupInput(inputId = "checkgroup",
label = "Select Deparments",
choices = c("All", "ELE", "HVAC", "MAN", "PH", "LV"),
selected = "All", inline = F),
radioButtons(inputId = "radio",
label = "ADD Stat_Smooth?",
choices = c("YES","NO"),
inline = T),
sliderInput(inputId = "slider",
label = "SPAN Setting",
min = 0.2, max = 2, value = 1,
ticks = T)
),
mainPanel(plotOutput(outputId = "plot33"))
)
)
server <- function(input, output){
output$plot33 <- renderPlotly({
gg <- ggplot(sizedf, aes(SIZE, Hours)) + geom_point(aes(color = Department)) + ggtitle("Size(m2) vs Hours per department")
p <- ggplotly(gg)
p
})
}
shinyApp(ui = ui, server = server)
I have seen this same mistake a few time already.
plotlyOutput() should be used, not plotOutput()
In my shiny app,I want to change the ggplot barChart that I wish to construct. selectinput should allow to change the month (see dataset below) and so my plot should change accordingly.
problem: The isssue is, i am unable to use my reactive function or even just simple input$monthid within ggplot function.
Dataset:
Month Orders
1 Feb 984524
2 Jan 1151303
3 Mar 575000
> dput(b)
structure(list(Month = c("Feb", "Jan", "Mar"), Orders = c(984524L,
1151303L, 575000L)), .Names = c("Month", "Orders"), class = "data.frame", row.names = c(NA,
-3L))
ui.R
library(shiny)
library(shinythemes)
b<-read.csv("b.csv",header=TRUE,sep=",",stringsAsFactors=TRUE)
shinyUI(fluidPage(theme= shinytheme("flatly"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "monthid", label = "Month",choices = b$Month,selected = b$Month[1])),
mainPanel(plotOutput("plot"))
))
)
server.R
library(shiny)
library(shinythemes)
library(ggplot2)
b<-read.csv("b.csv",header=TRUE,sep=",",stringsAsFactors=TRUE)
shinyServer(function(input, output) {
#making a reactive object
m<-reactive ({
as.character(input$monthid)
})
output$plot<- renderPlot({
#probably I am making a subset error in x inside aes parameter
ggplot(data = b, aes(x = b[,m()] ,y = b$Orders)) + geom_bar(stat="identity")
})
})
Here's a minimal working example you can copy and paste right in your session to run, but a bar chart with a single bar doesn't really make a lot of sense (and looks ugly if you ask me):
library(shiny)
shinyApp(
ui = fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "monthid",
label = "Month",
choices = b$Month,
selected = b$Month[1]
)
),
mainPanel(plotOutput("plot"))
)
),
server = function(input, output) {
DF <- reactive({
b[b$Month == input$monthid, , drop = FALSE]
})
output$plot <- renderPlot({
ggplot(DF(), aes(x = Month, y = Orders)) +
geom_bar(stat = "identity")
})
}
)
It looks somewhat like this:
Since that doesn't look nice IMO, you could do something with highlighting the currently selected bar, for example:
b$highlight <- factor("Not Selected", levels = c("Not selected", "Selected"))
shinyApp(
ui = fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(
inputId = "monthid",
label = "Month",
choices = b$Month,
selected = b$Month[1]
)
),
mainPanel(plotOutput("plot"))
)
),
server = function(input, output) {
DF <- reactive({
b[b$Month == input$monthid, "highlight"] <- "Selected"
b
})
output$plot <- renderPlot({
ggplot(DF(), aes(x = Month, y = Orders, fill = highlight)) +
geom_bar(stat = "identity")
})
}
)
This would look as follows: