How do I updateSelectInput() on the same dataset multiple times - r

Here I'm using 'mtcars' and will like to update my selectInputs based on the unique values in some column. First, we choose the type of engine and subset the data. Then we choose the cylinder but based on the remaining cylinder options in the subsetted data, and so forth. Last, we print the names of the cars. Code, which is not working, is as below:
library(shiny)
df <- mtcars
ui <- fluidPage(
sidebarPanel(
selectInput("engine", "Select engine:", choices = unique(df$vs)),
selectInput("cylinder", "Select cylinder:", choices = ""),
selectInput("gear", "Select gear:", choices = ""),
),
mainPanel(
textOutput("results")
)
)
server <- function(input, output, session) {
data <- reactiveValues()
observeEvent(input$engine, {
tmp <- df
tmp1 <- tmp[tmp$vs == as.numeric(input$engine),]
updateSelectInput(session, "cylinder", choices = unique(tmp1$cyl))
data()$tmp1 <- tmp1
})
observeEvent(input$cylinder,{
tmp1 <- data()$tmp1
tmp2 <- tmp1[tmp1$cyl == as.numeric(input$cylinder),]
updateSelectInput(session, "gear", choices = unique(tmp2$gear))
data()$tmp2 <- tmp2
})
observeEvent(input$gear,{
tmp2 <- data()$tmp2
tmp3 <- tmp2[tmp2$gear == as.numeric(input$gear),]
data()$tmp3 <- tmp3
})
output$results <- renderText({
print(row.names(data()$tmp3))
})
}
shinyApp(ui = ui, server = server)

The issue is that you try to access your reactiveValues data using data(). Instead, to set or get a value use e.g. data$tmp1 without parentheses. See ?reactiveValues.
library(shiny)
df <- mtcars
ui <- fluidPage(
sidebarPanel(
selectInput("engine", "Select engine:", choices = unique(df$vs)),
selectInput("cylinder", "Select cylinder:", choices = ""),
selectInput("gear", "Select gear:", choices = ""),
),
mainPanel(
textOutput("results")
)
)
server <- function(input, output, session) {
data <- reactiveValues()
observeEvent(input$engine, {
tmp <- df
tmp1 <- tmp[tmp$vs == input$engine, ]
updateSelectInput(session, "cylinder", choices = unique(tmp1$cyl))
data$tmp1 <- tmp1
})
observeEvent(input$cylinder, {
tmp1 <- data$tmp1
tmp2 <- tmp1[tmp1$cyl == input$cylinder, ]
updateSelectInput(session, "gear", choices = unique(tmp2$gear))
data$tmp2 <- tmp2
})
observeEvent(input$gear, {
tmp2 <- data$tmp2
tmp3 <- tmp2[tmp2$gear == input$gear, ]
data$tmp3 <- tmp3
})
output$results <- renderText({
print(row.names(data$tmp3))
})
}
shinyApp(ui = ui, server = server)
#>
#> Listening on http://127.0.0.1:5721
#> character(0)
#> [1] "Mazda RX4" "Mazda RX4 Wag"

Related

Filtering data according to column name and respective column's values in shiny

I am new in shiny, and maybe it can be easy but I could not make it, so I want to select column name firstly and in second box, it show unique values for selected column, and when choosing any values data table and plot appearing, plot will based on filtered part, thats why it is not hard but my main difficulties to extract interactive filter for data and and in default version, it should be whole data. I share what I have dont it is not working and not correct (this code is without data, I can not share data), I corrected some codes, now I can filter according to one value, but I want to see whole data in default version.
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
pickerInput("eda_col", "Select variable",
choices = c("col 1", "col 2", "col 3", "col 4"), selected = character(0)),
uiOutput("varselect"),
# selectInput("xSelector", label = "Select x axis", choices = xAxischoices),
# selectInput("ySelector", label = "Select the y axis", choices = yAxischoices),
# selectInput("cyLSelector", label = "Select a cylinder", choices = cylinderChoices),
actionButton("RefreshPlot", label = "Refresh")
),
mainPanel(
dataTableOutput("datatable1")
)
)
)
server <- function(input, output) {
output$varselect <- renderUI({
vars <- d[[as.name(input$eda_col)]]
checkboxGroupInput("level_choice", "Select factors to include", unique(vars))
})
# vars_r <- reactive({
# input$vars
# })
#
#
# res_mod <- callModule(
# module = selectizeGroupServer,
# id = "my-filters",
# data = d,
# vars = vars_r
# )
#
# output$table <- DT::renderDataTable({
# req(res_mod())
# res_mod()
# })
filteredData <- reactive({
filteredData <- d %>% filter((!! rlang:: sym(input$eda_col)) == input$level_choice)
return(filteredData)
})
output$datatable1 <- renderDataTable({
datatable(filteredData())
})
}
shinyApp(ui, server)
Please present a full MRE in the future. I have presented your requirements using available dataset gapminder. If this is not your expectation, please update your question using mtcars or gapminder data. Try this
library(gapminder)
choices <- names(gapminder)[1:2]
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
pickerInput("eda_col", "Select variable",
choices = choices, selected = character(0)),
uiOutput("varselect"),
# selectInput("xSelector", label = "Select x axis", choices = xAxischoices),
# selectInput("ySelector", label = "Select the y axis", choices = yAxischoices),
# selectInput("cyLSelector", label = "Select a cylinder", choices = cylinderChoices),
actionButton("RefreshPlot", label = "Refresh")
),
mainPanel(
dataTableOutput("datatable1")
)
)
)
server <- function(input, output) {
output$varselect <- renderUI({
if (is.null(input$eda_col)) vars <- names(gapminder)[1] ## define your default variable selection
else vars <- gapminder[[as.name(input$eda_col)]]
checkboxGroupInput("level_choice", "Select factors to include", unique(vars))
})
# vars_r <- reactive({
# input$vars
# })
#
#
# res_mod <- callModule(
# module = selectizeGroupServer,
# id = "my-filters",
# data = d,
# vars = vars_r
# )
#
# output$table <- DT::renderDataTable({
# req(res_mod())
# res_mod()
# })
filteredData <- reactive({
filteredData <- gapminder %>% filter((!! rlang:: sym(input$eda_col)) %in% input$level_choice)
return(filteredData)
})
output$datatable1 <- renderDataTable({
datatable(filteredData())
})
}
shinyApp(ui, server)

Hierarchical sidebarLayout() using the selectInput() variables information

I'd like to create a dynamic and hierarchical sidebarLayout using the selectInput
variables information. I have a pet information data frame (myds) and for example, I choose dog option in "selectedvariable1" pet, then in "selectedvariable3" the options need to be "collie" or "pit-bull", not "birman" or "bobtail" because the option in "selectedvariable1"is a dog, not a cat.
In my example:
# Packages
library(shiny)
# Create my data set
pet<-c("dog","dog","cat","cat")
fur<-c("long","short","long","short")
race<-c("collie","pit-bull","birman","bobtail")
sweetness<-c("high","medium","high","medium")
myds<-data.frame(pet,fur,race,sweetness)
# Create the pet shiny dash
ui <- fluidPage(
titlePanel(title="My Pet Dashboard"),
sidebarLayout(
sidebarPanel(
uiOutput("selectedvariable1"),
uiOutput("selectedvariable2"),
uiOutput("selectedvariable3"),
uiOutput("selectedvariable4")
),
mainPanel(
textOutput("idSaida")
)
)
)
server <- function(input, output,session){
currentvariable1 <- reactive({input$selectedvariable1})
currentvariable2 <- reactive({input$selectedvariable2})
currentvariable3 <- reactive({input$selectedvariable3})
currentvariable4 <- reactive({input$selectedvariable4})
output$selectedvariable1 <- renderUI({
selectInput("selectedvariable1",
label = "Pet type",
choices = unique(myds$pet),
selected = TRUE )
})
data2 <- reactive({
data2 <- subset(myds, fur %in% unique(currentvariable2()))
})
output$selectedvariable2 <- renderUI({
data2 <- subset(myds, pet %in% unique(currentvariable1()))
selectInput("selectedvariable2",
label = "Fur style",
choices = unique(data2$fur),
selected = TRUE )
})
data3 <- reactive({
data3 <- subset(data2, fur %in% unique(currentvariable2()))
})
output$selectedvariable3 <- renderUI({
selectInput("selectedvariable3",
label = "Race name",
choices = unique(data3$race),
selected = TRUE )
})
data4 <- reactive({
data4 <- subset(data2, fur %in% unique(currentvariable3()))
})
output$selectedvariable4 <- renderUI({
selectInput("selectedvariable4",
label = "Sweetness behaviour",
choices = unique(data4$sweetness),
selected = TRUE )
})
}
shinyApp(ui, server)
##
Please, anyone can help me with this question?
Try this
server <- function(input, output,session){
# currentvariable1 <- reactive({input$selectedvariable1})
# currentvariable2 <- reactive({input$selectedvariable2})
# currentvariable3 <- reactive({input$selectedvariable3})
# currentvariable4 <- reactive({input$selectedvariable4})
output$selectedvariable1 <- renderUI({
selectInput("selectedvariable1",
label = "Pet type",
choices = unique(myds$pet),
selected = TRUE )
})
data2 <- reactive({
req(input$selectedvariable1)
data2 <- subset(myds, pet %in% input$selectedvariable1)
})
output$selectedvariable2 <- renderUI({
req(data2())
#data2 <- subset(data2(), pet %in% unique(currentvariable1()))
selectInput("selectedvariable2",
label = "Fur style",
choices = unique(data2()$fur),
selected = TRUE )
})
data3 <- reactive({
req(input$selectedvariable2,data2())
data3 <- subset(data2(), fur %in% input$selectedvariable2)
})
output$selectedvariable3 <- renderUI({
req(data2())
selectInput("selectedvariable3",
label = "Race name",
choices = unique(data2()$race), ## use data3() instead of data2(), if you wish to subset from data3()
selected = TRUE )
})
data4 <- reactive({
req(input$selectedvariable3,data2())
data4 <- subset(data2(), race %in% input$selectedvariable3)
})
output$selectedvariable4 <- renderUI({
req(data4())
selectInput("selectedvariable4",
label = "Sweetness behaviour",
choices = data4()$sweetness,
selected = TRUE )
})
}
shinyApp(ui, server)
Something like this should work, add this to server function and adapt to your code:
observeEvent(input$selectedvariable1,{
if (input$selectedvariable1=="dog") {
updateSelectInput("selectedvariable3", choices=c("collie","pit-bull"))
}
})

Subset a dataframe based on columns of another dataframe in a shiny app

I have the dataframe below:
DF2 = data.frame(agency_postcode = factor(rep(c(12345,45678,24124,32525,32325),2)),
car_group=factor(rep(c("Microcar","City car","Supermini","Compact","SUV"),2)),
transmission=factor(rep(c("automatic","manual"),5)))
which I use and display as rhandsontable in order to create a second table. First you are supposed to select one or more options from filter by input and then a level from the selected filter(s). Then you press search. What I basically want to do is subset the second table based on the first row of every selected column of the first table. The issue is in line 30 of server.r in which I should give the input$sel
#ui.r
library(shiny)
library(rhandsontable)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(width=2,
selectInput("sel","Filter by:",
choices = c("agency_postcode","date_start","days","car_group","transmission","driver_age"),
multiple=T,selected = "agency_postcode"),
actionButton("sr","Search")
),
mainPanel(
fluidRow(
column(4,offset = 0, style='padding:0px;',rHandsontableOutput("hot")),
column(8,offset = 0, style='padding:0px;',rHandsontableOutput("hot2"))
)
)
)
)
#server.r
#server.r
library(shiny)
library(rhandsontable)
library(jsonlite)
server <- function(input, output) {
#Create rhandsontable as a reactive expression
DFR2<-reactive({
rhandsontable(DF2[1,1:2], rowHeaders = NULL,height = 200)%>%
hot_col(colnames(DF2)[1:2])
})
#Display the rhandsontable
output$hot <- renderRHandsontable({
DFR2()
})
#Convert the rhandsontable to a daraframe
DFR3<-reactive({
req(input$hot)
hot_to_r(input$hot)
})
#Subset the initial dataframe by value of the 1st row-1st column cell of DF3
DFR4 <- reactive({
req(DFR3())
D<-DF2[ which(DF2[,1] %in% DFR3()[1, 1]), ] #input$sel is supposed to be used here instead of 1
for(i in 1:ncol(D)){
D[,i] <- factor(D[,i])
}
D
})
#Display the new rhandsontable
output$hot2 <- renderRHandsontable({
input$sr
isolate(rhandsontable(DFR4()[1,], rowHeaders = NULL,height = 200)%>%
hot_col(colnames(DFR4())) )
})
}
OK. Here is an app that uses a small table to filter a larger one using inner_join. I am not sure this will match the design you had in mind. It is still unclear to me where the filter levels are coming from, or what the hands on tables are for. But you should be able to adapt this approach to your design. Note also that I am not using hands on tables. A direct replacement of the calls to renderTable with renderRHandsontable should work too.
library(shiny)
library(dplyr)
library(purrr)
sub_cars <- mtcars[, c("cyl", "gear", "am")]
ui <- fluidPage(
column(width=3,
selectInput(
inputId = "sel_col",
label = "Select variables",
multiple = TRUE,
choices = c("cyl", "gear", "am"),
selectize = TRUE),
uiOutput("cyl"),
uiOutput("gear"),
uiOutput("am")
),
column(width = 3,
tableOutput("filter_table")),
column(width = 6,
tableOutput("large_table"))
)
server <- function(input, output) {
output$cyl <- renderUI({
if ("cyl" %in% input$sel_col) {
selectInput(
inputId = "sel_cyl",
label = "Select cylinders",
choices = unique(sub_cars$cyl),
multiple = TRUE,
selectize = TRUE
)
}
})
output$gear <- renderUI({
if ("gear" %in% input$sel_col) {
selectInput(
inputId = "sel_gear",
label = "Select gears",
choices = unique(sub_cars$gear),
multiple = TRUE,
selectize = TRUE
)
}
})
output$am <- renderUI({
if ("am" %in% input$sel_col) {
selectInput(
inputId = "sel_am",
label = "Select am",
choices = unique(sub_cars$am),
multiple = TRUE,
selectize = TRUE
)
}
})
# make a small filter table
filter_df <- reactive({
validate(
need(!is_null(input$sel_col),
message = "Please select a column"))
cols <- input$sel_col
cols_vals <- map(cols, function(x) input[[paste0("sel_", x, collapse="")]])
df <- map2_dfr(cols, cols_vals, function(x, y)
filter(sub_cars,!!as.name(x) %in% y)) %>%
select(one_of(cols)) %>%
distinct()
return(df)
})
output$filter_table <- renderTable({
validate(
need(nrow(filter_df()) > 0,
message = "Please select filter values"))
filter_df()
})
# inner join the larger table
large_df <- reactive({
validate(
need(nrow(filter_df()) > 0,
message = "Please select filter values"))
cols <- input$sel_col
inner_join(x=filter_df(), y=mtcars, by = cols)
})
output$large_table <- renderTable({large_df()})
}
shinyApp(ui, server)
Here is a gif of what it does.

R shiny Error: object 'input' not found, when used in eventReactive and Desctools

I know it might be duplicated, and I have sought for several questions that is similar with, but I still can not find why my code not work on.
The error occurs when two input sources are compiled to the eventReactive part.
My bug code like this:
library(shiny)
library(rio)
library(DescTools)
options(shiny.maxRequestSize=500*1024^2,shiny.usecairo = FALSE)
ui <- fluidPage(
titlePanel("See the file table"),
fluidRow(
column(4,
fileInput("theFile","upload your file")
),
column(4,
radioButtons("encode", "encoding way",
choices = c("Default" = "default",
"UTF-8" = "utf_8"),selected = "default")
),
column(4,
uiOutput("a_input")
),
column(4,
uiOutput("b_input")
),
column(4,
actionButton("choice3", "Show two variables comparing")
),
column(12,
verbatimTextOutput("console_comp")
),
column(12,
plotOutput("plot_Desc_comp")
)
)
)
server <- function(input,output, session){
allData <- reactive({
theFile <- input$theFile
req(input$theFile)
# Changes in read.table
if(input$encode == "default"){
df <- import(theFile$datapath)
} else{
df <- import(theFile$datapath,encoding = "UTF-8")
return(df)
}
})
output$a_input <- renderUI({
cn <- colnames(allData())
selectInput("a_input", "Select A variable to compare with Desc",
choices = cn,
size=10,
multiple=F, selectize=FALSE)
})
output$b_input <- renderUI({
cn <- colnames(allData())
selectInput("b_input", "Select B variable to compare with Desc",
choices = cn,
size=10,
multiple=F, selectize=FALSE)
})
data_Desc_a <- eventReactive(input$choice3, {
req(allData())
dat <- allData()
dat[,input$a_input, drop = FALSE]
})
data_Desc_b <- eventReactive(input$choice3, {
req(allData())
dat <- allData()
dat[,input$b_input, drop = FALSE]
})
output$console_comp <- renderPrint({
dat <- allData()
var_a <- data_Desc_a()
var_b <- data_Desc_b()
mylist2 <- Desc(var_a ~ var_b, dat)
print(mylist2)
})
output$plot_Desc_comp <- renderPlot({
dat <- allData()
var_a <- data_Desc_a()
var_b <- data_Desc_b()
mylist2 <- Desc(var_a ~ var_b, dat)
plot(mylist2)
})
}
shinyApp(ui, server)
The error code occurs when I want to press the "Show two variables comparing" buttom after I uploaded one file and chose two vars, and the error like this:
unused arguments (var_a ~ var_b, dat)
Even if I just use one source, it can work things out.
My work code like this:
ui <- fluidPage(
titlePanel("See the file table"),
fluidRow(
column(6,
fileInput("theFile","upload your file")
),
column(6,
radioButtons("encode", "encoding way",
choices = c("Default" = "default",
"UTF-8" = "utf_8"),selected = "default")
),
column(8,
uiOutput("colToDesc")
),
column(4,
actionButton("choice2", "Show variables Desc")
),
column(12,
verbatimTextOutput("console")
),
column(12,
plotOutput("plot_Desc")
)
)
)
server <- function(input,output, session){
allData <- reactive({
theFile <- input$theFile
req(input$theFile)
# Changes in read.table
if(input$encode == "default"){
df <- import(theFile$datapath)
} else{
df <- import(theFile$datapath,encoding = "UTF-8")
return(df)
}
})
output$colToDesc <- renderUI({
cn <- colnames(allData())
selectInput("colToDesc", "Select variable to Desc",
choices = cn,
size=10,
multiple=T, selectize=FALSE)
})
data_Desc <- eventReactive(input$choice2, {
req(allData())
dat <- allData()
dat[,input$colToDesc, drop = FALSE]
})
output$console <- renderPrint({
variables <- data_Desc()
mylist <- Desc(variables,main = names(variables))
print(mylist)
})
output$plot_Desc <- renderPlot({
variables <- data_Desc()
mylist <- Desc(variables,main = names(variables))
plot(mylist)
})
}
And I can sure the function of Desc from DescTools package can work well like this :
Desc(temp[,91]~temp[,5],temp)
So what's wrong with my bug code.

shiny - omitting a userinput with filter when "All" is selected

In the Ui.R i have some input selects, of which Location is one, I would like to be able to omit the same if "All" is selected,
selectInput('Location', 'Location', choices = c("All", unique(sampleData$Location)), selected = "All"),
I tried using reactive if else, but there is an error which says -
"Evaluation error: operations are possible only for numeric, logical or complex types."
I am new to shiny, can I use inpLocation that way?
Any help is appreciated.
Here's my entire code -
library(plotly)
library(shiny)
load("sample_Data.rdata")
nms <- names(sample_Data)
ui <- (pageWithSidebar(
headerPanel("Demo"),
sidebarPanel(
selectInput('sex', 'Sex', choices = unique(sample_Data$sex), selected = "F"),
selectInput('Location', 'Location', choices = c("All", unique(sample_Data$Location)), selected = "All"),
selectInput('color1', 'Color1', choices = c('None', nms), selected = "region"),
selectInput('color2', 'Color2', choices = c('None', nms), selected = "species")
),
mainPanel(
fluidRow(
column(12, plotlyOutput("p1"))
),
fluidRow(
column(12, plotlyOutput("p2"))
)
)
))
server <- function(input, output, session) {
nms <- row.names(sample_Data)
dataset <- reactive({
inpLocation <- reactive({
if(input$Location == "All"){
sample_Data$Location
}else{
input$Location
}})
sample_Data %>%
filter(sex %in% input$sex, inpLocation())
})
output$p1 <- renderPlotly({
p<-qplot(year,N,data=dataset(),color=species)
if (input$color1 != 'None') p <- p + aes_string(color=input$color1)
p<-ggplotly(p)
p
})
output$p2 <- renderPlotly({
p<-qplot(region,N,data=dataset(),color=species)
if (input$color2 != 'None') p <- p + aes_string(color=input$color2)
p <- ggplotly(p)
p
})
}
shinyApp(ui, server, options = list(display.mode = "showcase"))
you don't need the second reactive inside of the first reactive call. Inside the outer reactive it will already be updated whenever the input$Location is changed.
dataset <- reactive({
if(input$Location == "All"){
inpLocation <- sample_Data$Location
}else{
inpLocation <- input$Location
}
sample_Data %>%
filter(sex %in% input$sex,
Location %in% inpLocation)
})

Resources