Shinyapp mapping by species and color - r

I should create in my shiny app this conditions:
In the UI setup add a selectInput field: the first argument is
the name (how to access the selection in the server setup, we will
call this "species"), the second argument is the label (appears on
the app), and the third argument should list the choices: here we
want to choose between the three different species (can you
obtain the three choices from the data directly?).
I receive this error in my code:
I receive this error:
Error in match.arg(position) : 'arg' must be NULL or a character vector
CODE:
library(shiny)
library(palmerpenguins)
library(ggplot2)
# Define UI for application that draws a plot
ui <- fluidPage(
# Application title
titlePanel("Penguins"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput(inputId = "VarX",
label = "Select X-axis Variable",
choices = list("flipper_length_mm","species","island",
"bill_length_mm","bill_depth_mm","body_mass_g",
"sex","year")),
selectInput(inputId = "VarY",
label = "Select Y-axis Variable",
choices = list("flipper_length_mm","species","island",
"bill_length_mm","bill_depth_mm","body_mass_g",
"sex","year")),
selectInput(
inputId = "varColor",
label = "Color",
choices = c("species"),
selected = "species")),
selectInput(
inputId = "species",
label = "select species",
choices = list("adelie","gentoo","chinstrap")),
# Show a plot
mainPanel(
plotOutput("scatter")
)
)
)
#Define server logic required to draw a scatter
server <- function(input, output) {
pengu <- reactive({ggplot(penguins,
aes(y = bill_depth_mm, x = bill_length_mm))+
geom_point(aes(color = .data[[input$species]]))})
output$scatter <- renderPlot({
pengu()
})
}
# Run the application
shinyApp(ui = ui, server = server)

Related

Show selectInput in rshiny based on condition (conditionalPanel)

I want to create an app that allows you to select one variable based on a condition.
So I have create a switchInput with conditions Yes, and No, and as you can see, a stratify SelectInput should appear in case Yes is marked.
However, no new SelectInput is displayed:
# Shiny
library(shiny)
library(shinyWidgets)
library(shinyjqui)
# Data
library(readxl)
library(dplyr)
# Plots
library(ggplot2)
not_sel <- "Not Selected"
# User interface
ui <- navbarPage(
main_page <- tabPanel(
title = "",
titlePanel(""),
sidebarLayout(
sidebarPanel(
title = "Inputs",
fileInput("xlsx_input", "Select XLSX file to import", accept = c(".xlsx")),
selectInput("num_var_1", "Variable X axis", choices = c(not_sel)),
selectInput("num_var_2", "Variable Y axis", choices = c(not_sel)),
switchInput(
inputId = "Id013",
onLabel = "Yes",
offLabel = "No"
),
conditionalPanel(
condition = "Id013 == 'Yes'", selectInput("Stratify", "Stratify", choices = c(not_sel)), #uiOutput("factor"),
),
actionButton("run_button", "Run Analysis", icon = icon("play"))
),
mainPanel(
tabsetPanel(
tabPanel(
title = "Plot",
br(),
plotOutput("sel_graph")
)
)
)
)
)
)
# Server
server <- function(input, output){
# Dynamic selection of the data. We allow the user to input the data that they want
data_input <- reactive({
#req(input$xlsx_input)
#inFile <- input$xlsx_input
#read_excel(inFile$datapath, 1)
iris
})
}
# Connection for the shinyApp
shinyApp(ui = ui, server = server)
I understand, based on the conditionalPanel function:
Creates a panel that is visible or not, depending on the value of a JavaScript expression. The JS expression is evaluated once at startup and whenever Shiny detects a relevant change in input/output.
That the change on the switchInput value should be enough to generate this changes in the UI interface.
As said in the docs of conditionalPanel():
For example, if you have an input with an id of foo, then you can use input.foo to read its value.
So you need to use input.Id013 instead of Id013 in the condition. Also, even if the labels of the switch are "Yes" or "No", it returns a value TRUE/FALSE (which are written "true" or "false" in Javascript). So the condition you need to use is:
condition = "input.Id013 == true"

condition in conditionalPanel in shiny R not working well

I would like to create a dynamic app that depending on an input pops out other inputs or not. In the code below I want to pop out the checkboxInput with label x when the selectInput with label mdl is "First model". When I run the app and select the First model from the list the other checkboxInput does not appear. I know the condition has to be in javascript but I don't know that language. However I think that one of the conditions is right. Any suggestions? i have tried both codes shown below.
library(shiny)
ui <- fluidPage(
selectInput(inputId = "mdl", label = "Model", choices = list("First model",
"Second model", "Third model"),
conditionalPanel(
condition = "input.mdl == 'First model'",
checkboxInput(inputId = "x", label = "Length")
)
),
)
server <- function(input, output){
}
shinyApp(ui = ui, server = server)
library(shiny)
ui <- fluidPage(
selectInput(inputId = "mdl", label = "Model", choices = list("First model",
"Second model", "Third model"),
conditionalPanel(
condition = "input.mdl == First model",
checkboxInput(inputId = "x", label = "Length")
)
),
)
server <- function(input, output){
}
shinyApp(ui = ui, server = server)

R Shiny - How to update a dependent reactive selectInput before updating dependent reactive plot

App Structure
I have a Shiny app with the typical sidebar panel + mainpanel structure.
Sidebar panel: There are multiple selectInput widgets within the sidebarpanel, where the choices within each selectInput are dependent upon
the previous selectInput's selected value. (i.e., user selects a dataset from selectInput 1 & a variable from selectInput 2, where the variables available as "choices" in selectInput #2 are dependent on Input 1's selection)
Main panel: There is a basic ggplot2 visualization, which is dependent upon the 2 input selections (dataset and variable) made in the sidebar panel.
Problem
When the user chooses a new dataset in selectInput #1, both the selectInput #2 (available variables) and the plot will need to update. I want the selectInput #2 to update first, and then the plot. However, it seems the plot always proceeds to update before the 2nd selectInput has a chance to update. This results in the plot trying to render an invalid plot -- i.e., tries to render a plot of an mtcars variable using the iris dataset, or vice versa.
Is there a way to prioritize the reactive update of the selectInput #2 to occur before the reactive update of the renderPlot?
Notes
As a UX requirement, I am avoiding using a button to render the plot.
I need the plot to update dynamically in real-time based on
selections.
In my reprex, I included print statements to depict how the plot
attempts to update with an invalid combo of selections.
library(shiny)
library(ggplot2)
library(dplyr)
# Define UI for application that draws a histogram
ui <- fluidPage(
titlePanel("Reactivity Test"),
# Sidebar with two input widgets
sidebarLayout(
sidebarPanel(
selectInput(inputId = "dataset",
label = "Input #1 - Dataset",
choices = c("mtcars", "iris")),
selectInput(inputId = "variable",
label = "Input #2 - Variable",
choices = NULL)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output) {
input_dataset <- reactive({
if (input$dataset == "mtcars") {
return(mtcars)
} else {
return(iris)
}
})
mtcars_vars <- c("mpg", "cyl", "disp")
iris_vars <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")
available_vars <- reactive({
if (input$dataset == "mtcars") {
return(mtcars_vars)
} else {
return(iris_vars)
}
})
observe({
updateSelectInput(inputId = "variable", label = "Variable", choices = available_vars())
})
output$distPlot <- renderPlot({
req(input$dataset, input$variable)
print(input$dataset)
print(input$variable)
selected_dataset <- input_dataset()
selected_variable <- input$variable
filtered_data <- selected_dataset %>% select(selected_variable)
ggplot(filtered_data, aes(x = get(selected_variable))) +
geom_histogram()
})
}
# Run the application
shinyApp(ui = ui, server = server)
You can try using the freezeReactiveValue() function, as Hadley Wickham recommends in mastering shiny.
library(shiny)
library(ggplot2)
library(dplyr)
# Define UI for application that draws a histogram
ui <- fluidPage(
titlePanel("Reactivity Test"),
# Sidebar with two input widgets
sidebarLayout(
sidebarPanel(
selectInput(inputId = "dataset",
label = "Input #1 - Dataset",
choices = c("mtcars", "iris")),
selectInput(inputId = "variable",
label = "Input #2 - Variable",
choices = NULL)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("distPlot")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
input_dataset <- reactive({
if(input$dataset == "mtcars") {
return(mtcars)
} else {
return(iris)
}
})
observeEvent(input$dataset, {
freezeReactiveValue(input, "variable")
updateSelectInput(session = session, inputId = "variable", choices = names(input_dataset()))
})
output$distPlot <- renderPlot({
ggplot(input_dataset(), aes(x = .data[[input$variable]])) +
geom_histogram()
})
}
# Run the application
shinyApp(ui = ui, server = server)

Plot the boxplot by using check box in shiny app

I'd like to use check box input to allow to show different island levels (within the categorical variable selected for the x-axis) with separate boxplots and different colors with a legend. But if this check box is not selected, I just want to show boxplot without fill=legend that is:
ggplot(dat(), aes_string(x = isolate(input$xaxis), y = input$yaxis)) +
geom_boxplot()
This R code is what I tried to use but It didn't work. Could you please help me to solve or tell me what makes error with my R code?
Thank you in advance
library(shiny)
library(palmerpenguins)
library(ggplot2)
library(dplyr)
penguin <- penguins
penguin$year <- as.factor(penguin$year)
ui <- fluidPage(
titlePanel("Data Visualisation of Penguins Data"),
sidebarPanel(
selectInput("yaxis",
label = "Choose a y-axis variable to display",
choices = list("bill_length_mm",
"bill_depth_mm",
"flipper_length_mm",
"body_mass_g"),
selected = "bill_length_mm"),
selectInput("xaxis",
label = "Choose a x-axis variable to display",
choices = c("species",
"sex",
"year"),
selected = "sex"),
checkboxGroupInput("islandlevels",
label = "Check to display different island levels",
choices = c("island"),
selected = NULL),
br(), br(),
selectInput("species",
label = "Choose species to view separate plot",
choices = list("Adelie",
"Chinstrap",
"Gentoo"),
selected = NULL)),
mainPanel(
plotOutput("plot1"),
br(), br(),
plotOutput("plot2")
)
)
server <- function(input, output){
dat <- reactive({
if(input$xaxis == "sex") penguin[!is.na(penguin$sex),] else penguin
})
output$plot1 <- renderPlot({
if(input$islandlevels == "island") {
req(penguin, input$xaxis, input$yaxis)
ggplot(dat(), aes_string(x = isolate(input$xaxis), y = input$yaxis, fill=island)) +
geom_boxplot()
}
if(input$islandlevels = NULL) {
req(penguin, input$xaxis, input$yaxis)
ggplot(dat(), aes_string(x = isolate(input$xaxis), y = input$yaxis)) +
geom_boxplot()}
})
}
shinyApp(ui = ui, server = server)
As long as you don't want any other checkbox inputs you could use a checkboxInput instead of a checkboxGroupInput which makes checking a bit easier.
One issue in your server was that you used island instead of "island". Additionally you can simplify your code a little bit by using fill <- if (input$islandlevels) "island" which will return NULL is the the checkbox was not checked and "island" otherwise. This way you can handle both case with only one ggplot statement .
The full reproducible code:
library(shiny)
library(palmerpenguins)
library(ggplot2)
library(dplyr)
penguin <- penguins
penguin$year <- as.factor(penguin$year)
ui <- fluidPage(
titlePanel("Data Visualisation of Penguins Data"),
sidebarPanel(
selectInput("yaxis",
label = "Choose a y-axis variable to display",
choices = list("bill_length_mm",
"bill_depth_mm",
"flipper_length_mm",
"body_mass_g"),
selected = "bill_length_mm"),
selectInput("xaxis",
label = "Choose a x-axis variable to display",
choices = c("species",
"sex",
"year"),
selected = "sex"),
checkboxInput("islandlevels",
label = "Check to display different island levels",
value = FALSE),
br(), br(),
selectInput("species",
label = "Choose species to view separate plot",
choices = list("Adelie",
"Chinstrap",
"Gentoo"),
selected = NULL)),
mainPanel(
plotOutput("plot1"),
br(), br(),
plotOutput("plot2")
)
)
server <- function(input, output){
dat <- reactive({
if(input$xaxis == "sex") penguin[!is.na(penguin$sex),] else penguin
})
output$plot1 <- renderPlot({
req(penguin, input$xaxis, input$yaxis)
fill <- if (input$islandlevels) "island"
ggplot(dat(), aes_string(x = isolate(input$xaxis), y = input$yaxis, fill = fill)) +
geom_boxplot()
})
}
shinyApp(ui = ui, server = server)

Shiny not displaying ggplot data

I am new to working with shiny package. I am trying to use it to display a ggplot2 graph. I get no errors with my code, however data points are not appearing on the graph. When I select the variables from ui, the axes labels changes accordingly but the data is not added to the plot.
Thank you,
Code:
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(inputId = "y",
label = "Y-axis:",
choices = c("P-value", "P-adjust"),
selected = "P-adjust"),
selectInput(inputId = "x" ,
label = "X-axis:",
choices = c("FC", "Mean_Count_PD"),
selected = "FC")
),
mainPanel(plotOutput(outputId = "scatterplot"))
))
server <- function(input, output)
{
output$scatterplot <- renderPlot({
ggplot(data = mir, aes(input$x,input$y)) + geom_point()
})
}
The issue is that you have to tell ggplot that your inputs are names of variables in your dataset. This could be achieved e.g. by making use of the .data pronoun, i.e. instead of using input$x which is simply a string use .data[[input$x]] which tells ggplot that by input$x you mean the variable with that name in your data:
As you provided no data I could not check but this should give you the desired result:
library(shiny)
library(ggplot2)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput(inputId = "y",
label = "Y-axis:",
choices = c("P-value", "P-adjust"),
selected = "P-adjust"),
selectInput(inputId = "x" ,
label = "X-axis:",
choices = c("FC", "Mean_Count_PD"),
selected = "FC")
),
mainPanel(plotOutput(outputId = "scatterplot"))
))
server <- function(input, output) {
output$scatterplot <- renderPlot({
ggplot(data = mir, aes(.data[[input$x]], .data[[input$y]])) + geom_point()
})
}
shinyApp(ui, server)

Resources