Click function not working in shiny at once - shiny

This is the sample application where I have added click to automatically execute the action button
library(shiny)
library(shinyjs)
ui <- basicPage(
useShinyjs(),
fluidRow(
column(
width = 6,
textInput('a', 'Text A',"a1"),
textInput('b', 'Text B',"b1"),
# textInput('c', 'Text A',"c1"),
# textInput('d', 'Text B',"d1"),
# textInput('e', 'Text A',"e1"),
textInput('f', 'Text B',"f1"),
selectInput('gh', "select", choices = c(1,2,5,6,7), selected = 1),
actionButton("sub", "Submit"),
actionButton("ret", "auto click"),
uiOutput('f2'),
uiOutput('f3')
),
column(
width = 6,
tags$p(tags$span(id = "valueA", "")),
tags$script(
"$(document).on('shiny:inputchanged', function(event) {
if (event.name === 'a') {
$('#valueA').text(event.value);
}
});
"
)
,tableOutput('show_inputs')
)
)
)
server <- shinyServer(function(input, output, session){
# output$f2 <- renderUI({
# if(input$a == "a2"){
# textInput('ren', 'ren B',"ren z1")
# } else {
# NULL
# }
# })
AllInputs <- reactive({
x <- reactiveValuesToList(input)
})
asd <- reactiveValues()
observeEvent(input$sub,{
asd$df <- c(6,9)
output$f2 <- renderUI({
selectInput('f2', "select", choices = c(6,9), selected = asd$df)
})
output$f3 <- renderUI({
actionButton("new", "Generate iris table")
})
})
observeEvent(input$new, {
output$show_inputs <- renderTable({
head(iris)
})
})
observeEvent(input$ret,{
asd$df <- 9
sad <- data.frame(a = c("gh"), b = c(7))
updateSelectInput(session, inputId = sad$a, selected = sad$b)
click('sub')
updateSelectInput(session, inputId = "f2", selected = asd$df)
click('new') ### to generate IRIS table
# click('new')
})
})
shinyApp(ui = ui, server = server)
The process, when you click on "auto click", there is a button "Generate iris table" popping up and also this button should be get auto clicked so that iris table gets populated.
But here only "Generate iris table" button is popping up and no iris table getting displayed.
But if you click again on "auto click" button , we can see iris button
Expected output
The moment user clicks on "auto click", both "Generate iris table" button and iris table should be displayed

Nesting reactives causes issues.
Try this
server <- shinyServer(function(input, output, session){
# output$f2 <- renderUI({
# if(input$a == "a2"){
# textInput('ren', 'ren B',"ren z1")
# } else {
# NULL
# }
# })
AllInputs <- reactive({
x <- reactiveValuesToList(input)
})
asd <- reactiveValues(df=NULL)
observe({hide("f3")})
observeEvent(input$sub,{
asd$df <- c(6,9)
show("f3")
})
output$f3 <- renderUI({
actionButton("new", "Generate iris table")
})
output$f2 <- renderUI({
selectInput('f2', "select", choices = asd$df, selected = asd$df)
})
dt <- eventReactive(input$new, {head(iris)})
output$show_inputs <- renderTable({
dt()
})
observe({print(asd$df)})
observeEvent(input$ret,{
asd$df <- 9
sad <- data.frame(a = c("gh"), b = c(7))
updateSelectInput(session, inputId = sad$a, selected = sad$b)
click('sub')
updateSelectInput(session, inputId = "f2", selected = asd$df)
click('new') ### to generate IRIS table
# click('new')
})
})

Related

Shiny actionbutton to set a customized default

In this shiny App (code below), I need that the button labeled 'Customized' returns:
Select var X: disp
Select var Y: drat
Point size: 1.0
This necessity is a bit similar to the reset button available on the R package 'shinyjs', with the diference of that the reset button returns to the code's default.
library(shiny)
library(shinyjs)
shinyApp(
ui <- fluidPage(
sidebarPanel(
fluidRow(
shinyjs::useShinyjs(),
id = "panel_vars",
# Buttons
uiOutput("varx"),
uiOutput("vary"),
numericInput("ptSize", "Point size",
min=.1, max=5, value = 2),
actionButton("p1", 'Reset variables XY'),
helpText(""),
actionButton("p2", 'Customized')
)
),
mainPanel(
plotOutput("plot")
)
),
server <- function(input, output) {
getModel <- reactive({
names(mtcars)
})
output$varx <- renderUI({
selectInput("varsel.x", "Select var X",
choices = as.list(getModel()), multiple = F)
})
output$vary <- renderUI({
selectInput("varsel.y", "Select var Y",
choices = as.list(getModel()), multiple = F)
})
observeEvent(input$p1, {
shinyjs::reset("panel_vars")
})
output$plot <- renderPlot({
p <- mtcars %>% ggplot(aes_string(x=input$varsel.x, y=input$varsel.y))+
geom_point(size=input$ptSize)
p
})
}
)
You can simply use updateSelectInput and updateNumericInput to do so:
library(shiny)
library(shinyjs)
library(dplyr)
library(ggplot2)
shinyApp(
ui <- fluidPage(
sidebarPanel(
fluidRow(
shinyjs::useShinyjs(),
id = "panel_vars",
# Buttons
uiOutput("varx"),
uiOutput("vary"),
numericInput("ptSize", "Point size",
min=.1, max=5, value = 2),
actionButton("p1", 'Reset variables XY'),
helpText(""),
actionButton("p2", 'Customized')
)
),
mainPanel(
plotOutput("plot")
)
),
server <- function(input, output,session) {
getModel <- reactive({
names(mtcars)
})
output$varx <- renderUI({
selectInput("varsel.x", "Select var X",
choices = as.list(getModel()), multiple = F)
})
output$vary <- renderUI({
selectInput("varsel.y", "Select var Y",
choices = as.list(getModel()), multiple = F)
})
observeEvent(input$p1, {
shinyjs::reset("panel_vars")
})
output$plot <- renderPlot({
req(input$varsel.x,input$varsel.y,input$ptSize)
p <- mtcars %>% ggplot(aes_string(x=input$varsel.x, y=input$varsel.y))+
geom_point(size=input$ptSize)
p
})
observeEvent(input$p2, {
updateSelectInput(session,'varsel.x',selected = 'disp')
updateSelectInput(session,'varsel.y',selected = 'drat')
updateNumericInput(session, "ptSize", value = 1.0)
})
}
)

R Shiny problem with inputs belonging to a bsCollapsePanel

In this shiny App (code below), tabPanel 'Scatter plot', note that the plot is correctly rendered only when the user expand the bsCollapsePanel 'Marker settings' for the first time. Before expanding the panel 'Marker settings' at first time, the message Error: argument is of length zero is shown. Can someone find out where the error is in the code?
library(shiny)
library(shinyBS)
library(tidyverse)
shinyApp(
ui = fluidPage(
tabsetPanel(
tabPanel("mtcars",
dataTableOutput("mtcarsDATA")),
tabPanel("Scatter plot",
sidebarPanel(
bsCollapse(id = "Side panel", open = "Variables",
bsCollapsePanel("Variables",
uiOutput("varx"),
uiOutput("vary"))
)
),
mainPanel(
bsCollapsePanel("Marker settings",
uiOutput("showMrk"),
uiOutput("shpMrk"),
uiOutput("forPorForma"),
uiOutput("forPorVar"),
uiOutput("mrkTrsp")),
plotOutput('SctPlot'))
)
)
),
server <- function(input, output) {
output$mtcarsDATA <- renderDataTable({
data <- mtcars
getModel <- reactive({
names(data) })
output$varx <- renderUI({
selectInput("varsel.x", HTML("Select var X<span style='color: red'>*</span>"),
choices = as.list(getModel()), multiple = F) })
getModelnum <- reactive({
filterNumeric <- data[sapply(data, is.numeric)]
names(filterNumeric) })
output$vary <- renderUI({
selectInput("varsel.y", HTML("Select var Y<span style='color: red'>*</span>(numerical only)"),
choices = as.list(getModelnum()), multiple = F) })
output$showMrk <- renderUI({
checkboxInput("show_Mrk", "Show marker", value=T) })
output$shpMrk <- renderUI({
conditionalPanel(condition = "input.show_Mrk == T",
radioButtons("shp_Mrk", "Format marker",
choices = c("by shape", "by variable"))) })
output$forPorForma <- renderUI({
conditionalPanel(condition = "input.shp_Mrk == 'by shape' & input.show_Mrk == T",
sliderInput("for_PorForma", 'Deslize para mudar o formato do marcador',
min = 1, max=25, value = 16)) })
output$mrkTrsp <- renderUI({
conditionalPanel(condition = "input.show_Mrk == T",
sliderInput("mrk_Trsp", 'Slide to change marker transparency',
min = 0, max=1, value = .5, step=.05)) })
getModelcat <- reactive({
filterCaracter <- data[sapply(data, is.character)]
names(filterCaracter) })
output$forPorVar <- renderUI({
conditionalPanel(condition = "input.show_Mrk == 1 & input.shp_Mrk == 'by variable'",
selectInput("forPorVar.sel", "Select var",
choices = as.list(getModelcat()), multiple = F)) })
output$SctPlot <- renderPlot({
if(input$show_Mrk == T){
if(input$shp_Mrk == "by shape") {
geomPoint <- geom_point(alpha=1-input$mrk_Trsp, shape=input$for_PorForma) } else {
geomPoint <- geom_point(alpha=1-input$mrk_Trsp, aes_string(shape=(input$forPorVar.sel))) }} else {
geomPoint <- geom_point(alpha=0) }
p <- data %>%
ggplot(aes_string(x=input$varsel.x, y=input$varsel.y)) +
geomPoint
p
})
data
})
}
)

How to visualise regression's predictions based on selected dataset and variables thereof

I have the following code that basically uploads the data and once you have clicked on the row of the dataset you have uploaded, it reads the file. If you go to the second page in the navbar called regression you can choose variables from the dataset and run linear model. That works with the summary table. I want to achieve is something like here: https://towardsdatascience.com/build-an-interactive-machine-learning-model-with-shiny-and-flexdashboard-6d76f59a37f9
I want the prediction table and plot visualisation based on what has been selected. Appreciate your understanding and helpfulness.
library(shiny)
library(magrittr)
library(shiny)
library(readxl)
library(tidyverse)
library(DT)
library(reactable)
ui <- navbarPage("Demo",
tabPanel("Data Manipulation",
sidebarLayout(
sidebarPanel(
fileInput("upload", "Upload your file", multiple = TRUE, accept = c(".csv", ".xlsx") ),
selectInput('mydropdown', label = 'Select', choices = 'No choices here yet'),
h2("Modify variable type"),
selectInput("var_name", "Select variable", choices = c()),
radioButtons("action", NULL,
choiceNames = c("Make factor", "Make numeric"),
choiceValues = c("factor", "numeric")),
actionButton("modify", "Do it!"),
verbatimTextOutput("str")
),
mainPanel(
DT::DTOutput("files"),
reactable::reactableOutput("uploaded_files")
)
)
),
tabPanel("Regression",
sidebarLayout(
sidebarPanel(
selectInput("dep_var", "Select dependent variable", choices = c()),
selectInput("ind_var", "Select independent variables", choices = c(), multiple = TRUE),
actionButton("submit_reg", "Do it!")),
mainPanel(
verbatimTextOutput(outputId = "regsum")
)
)
),
)
server <- function(input, output, session) {
output$files <- DT::renderDT({
DT::datatable(input$upload, selection = c("single"))
})
selected_file <- reactiveVal()
observe({
## when developing, use a sample file you have on your computer so that you
## can load it immediately instead of going through button clicks
# demofile <- "/path/to/your/file.csv"
# selected_file( read.csv(demofile) )
# return()
req(input$upload, input$files_rows_selected)
idx <- input$files_rows_selected
file_info <- input$upload[idx, ]
if (tools::file_ext(file_info$datapath) == "csv") {
selected_file(read.csv(file_info$datapath))
} else if (tools::file_ext(file_info$datapath) == "xlsx") {
selected_file(readxl::read_xlsx(file_info$datapath))
} else {
stop("Invalid file type")
}
})
output$uploaded_files <- reactable::renderReactable({
req(selected_file())
reactable::reactable(
selected_file(),
searchable = TRUE
)
})
observe({
req(input$upload)
file_names <- input$upload$name
updateSelectInput(
session,
"mydropdown",
choices = file_names
)
})
observe({
req(selected_file())
updateSelectInput(session, "var_name", choices = names(selected_file()))
})
output$str <- renderPrint({
req(selected_file())
str(selected_file())
})
observeEvent(input$modify, {
df <- selected_file()
if (input$action == "factor") {
df[[input$var_name]] <- as.factor(df[[input$var_name]])
} else if (input$action == "numeric") {
df[[input$var_name]] <- as.numeric(df[[input$var_name]])
} else {
stop("Invalid action")
}
selected_file(df)
})
# Second Page
observe({
req(selected_file())
Dependent <- updateSelectInput(session, "dep_var", choices = names(selected_file()))
})
observe({
req(selected_file())
Independent <- updateSelectInput(session, "ind_var", choices = names(selected_file()))
})
observeEvent(input$submit_reg, {
lm1 <- reactive({
req(selected_file())
Model1 <- lm(reformulate(input$ind_var, input$dep_var), data = selected_file())})
options(scipen=999)
output$regsum <- renderPrint({summary(lm1())})
DT::renderDataTable({
df <- req(selected_file())
DT::datatable(df %>% select(input$dep_var, input$ind_var) %>% mutate(predicted = predict(lm1()), residuals = residuals(lm1())) %>% select(input$dep_var, predicted, residuals),
rownames = FALSE, colnames = c('actual value', 'predicted value', 'residuals'), extensions = c('Buttons', 'Responsive'),
options = list(columnDefs = list(list(className = 'dt-center', targets = "_all")), dom = 'Blfrt',
buttons = c('copy', 'csv', 'excel', 'print'), searching = FALSE, lengthMenu = c(20, 100, 1000, nrow(housing)), scrollY = 300, scrollCollapse = TRUE))
})
})
}
shinyApp(ui, server)

How to add dynamic contents under those tabs create using renderUI in shinyR application

I am building an application in shiny R where in required tabs can be selected by the users and data relevant to those tabs will be displayed under it.
For example, in below sample application, mtcars data in .csv will be accepted as input parameter.User can select required column names in tabs field.Those colmns will be created as tabs.
Now, I want to show data pertaining to that column from .csv in the appropriate tab.Say, data from the column 'mpg' will be shown under 'mpg' tab.
But i am stuck here.Appreciate someone could tell me a way to display data from relevant column under appropriate tab ,dynamically.
Sample codes used is shown below:
write.csv(mtcars,'mtcars.csv')
#
library(shiny)
library(plyr)
library(dplyr)
ui <- pageWithSidebar(
headerPanel = headerPanel('data'),
sidebarPanel = sidebarPanel(fileInput(
'mtcars', h4('Uplaodmtcardata in csv format')
),
uiOutput('tabnamesui')),
mainPanel(uiOutput("tabsets"))
)
server <- function(input, output, session) {
mtcarsFile <- reactive({input$mtcars})
xxmtcars <-
reactive({
read.table(
file = mtcarsFile()$datapath,
sep = ',',
header = T,
stringsAsFactors = T
)
})
tabsnames <- reactive({
names(xxmtcars())
})
output$tabnamesui <- renderUI({
req(mtcarsFile())
selectInput(
'tabnamesui',
h5('Tab names'),
choices = as.list(tabsnames()),
multiple = T
)
})
tabnamesinput <- reactive({
input$tabnamesui
})
output$tabsets <- renderUI({
req(mtcarsFile())
tabs <-
reactive({
lapply(tabnamesinput(), function(x)
tabPanel(title = basename(x), dataTableOutput(x)))
})
do.call(tabsetPanel, c(tabs()))
})
output[['mpg']] <-
renderDataTable(as.data.frame(select(xxmtcars(), mpg)))#HOW TO AVOID THIS HARD CODING..?BASED ON THE TAB NAME DATA FROM RELEVANT COLUMN IN THE CSV TO BE RETURNED.
}
runApp(list(ui = ui, server = server))
#
Try this
library(shiny)
library(plyr)
library(dplyr)
library(rlang)
library(DT)
ui <- pageWithSidebar(
headerPanel = headerPanel('data'),
sidebarPanel = sidebarPanel(fileInput(
'mtcars', h4('Uplaodmtcardata in csv format')
),
uiOutput('tabnamesui')),
mainPanel(uiOutput("tabsets"))
)
server <- function(input, output, session) {
mtcarsFile <- reactive({input$mtcars})
xxmtcars <-
reactive({
read.table(
file = mtcarsFile()$datapath,
sep = ',',
header = T,
stringsAsFactors = FALSE
)
})
tabsnames <- reactive({
names(xxmtcars())
})
output$tabnamesui <- renderUI({
req(mtcarsFile())
selectInput(
'tabnamesui',
h5('Tab names'),
choices = as.list(tabsnames()),
multiple = T
)
})
tabnamesinput <- reactive({
input$tabnamesui
})
output$tabsets <- renderUI({
req(mtcarsFile())
tabs <-
reactive({
lapply(tabnamesinput(), function(x)
tabPanel(title = basename(x), dataTableOutput(x)))
})
do.call(tabsetPanel, c(tabs()))
})
observe(
lapply(tabnamesinput(), function(x) {
output[[x]] <- DT::renderDataTable({
t<-as.data.frame(dplyr::select(xxmtcars(), !! sym(x)) )
print(t)
datatable(t)
})
})
)
}
runApp(list(ui = ui, server = server))

Dynamic render UI input and output R shiny

EDITE :
I added one more example that is same as my problem. I want to update the checkboxGroupInput as dataset changes. And also want to render the table with checked column in the checkboxGroupInput options.
SERVER
shinyServer( function(input, output, session) {
dataset_list <- list( "rock" = rock,
"pressure" = pressure,
"cars" = cars
)
observeEvent( input$n_select_input, {
selected_dataset <- reactive({
selected_list <- list()
for( i in 1:input$n_select_input ){
selected_list[[i]] <- dataset_list[[i]]
}
names(selected_list) <- names( dataset_list )[1:input$n_select_input]
selected_list
})
colname_indata_list <- reactive({
colname.indata.list <- list()
for( set in names( selected_dataset() ) ){
colname.indata.list[[set]] <- colnames( selected_dataset()[[set]] )
}
colname.indata.list
})
choice_cand <- reactive({ names(selected_dataset()) })
updateSelectInput( session,
"dataset",
choices = as.character( choice_cand() )
)
choices_cand <- reactive({ colname_indata_list()[[input$dataset]] })
updateCheckboxGroupInput( session,
"column",
choices = as.character( choices_cand() )
)
})
# observeEvent( input$dataset, {
#
# choices_cand <- reactive({ colname_indata_list()[[input$dataset]] })
# updateCheckboxGroupInput( session, "column",
# choices = as.character( choices_cand() ) )
#
# })
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"pressure" = pressure,
"cars" = cars)
})
output$table <- renderTable({
datasetInput()
})
} )
I tried the code above in the ## , it didn't work.
UI
shinyUI(
fluidPage( titlePanel('Downloading Data'),
sidebarLayout(
sidebarPanel( numericInput( "n_select_input", "n select inpur", 1,
min=1, max=3 ),
selectInput("dataset", "Choose a dataset:",
choices = "" ),
checkboxGroupInput( "column", "select column",
choices = "")
),
mainPanel(
tableOutput('table')
)
)
)
)
FIRST WRITE :
I simplified the code below. I want to use updated select input as a output for the updatedCheckboxGroupInput 's choices. But the updated select input, input$select_group is null. I tried varies solutions.. but couldn't solve it.
If you just run this code right away, it doesn't work..
fund_group <- reactive({ # this is the list of fund group including fund name
# for example,
"domestic" = c("a","b", "c"),
"global" = c( "aa", "bb", "cc")
# list name and fund name in the list are changable
})
I want to update selectInput choices as names(fund_group) changes.
So I used code below,
observe({
group_name <- reactive({ names(fund_group()) })
updateSelectInput( session,
"select_group",
choices = group_name() )
fund_list <- reactive({ fund_group()[[input$select_group]] })
updateCheckboxGroupInput( session,
"fund_in_group",
choices = fund_list(),
selected = fund_list() )
})
For the UI,
narvarPage( "narvarTitle",
tabPanel( "tab panel",
fluidRow( column( 3, wellPanel( textOutput( "fixed_anal_date" ),
br(),
br(),
selectInput( "select_group",
label = "Select group",
choices = "" ),
br(),
checkboxGroupInput( "fund_in_group",
label = "Select funds :",
choices = "" ),
br()
) )
) )
Thank you for reading the messy code...
I have edited the code an its working now. You should put the two input in two different observe.
Here is the server. R:
server <- function(input, output, session){
fund_group <- reactive({ # this is the list of fund group including fund name
# for example,
list("domestic" = c("a","b", "c"), "global" = c( "aa", "bb", "cc"))
# list name and fund name in the list are changable
})
observe({
group_name <- reactive({ names(fund_group()) })
updateSelectInput( session,
"select_group",
choices = group_name() )
})
observe({
fund_list <- reactive({ fund_group()[[input$select_group]] })
updateCheckboxGroupInput( session,
"fund_in_group",
choices = fund_list(),
selected = fund_list())
})
}
Here is the ui.R:
ui <- navbarPage( "narvarTitle",
tabPanel( "tab panel",
fluidRow( column( 3, wellPanel( textOutput( "fixed_anual_date" ),
br(),
br(),
selectInput( "select_group",
label = "Select group",
choices = "" ),
br(),
checkboxGroupInput( "fund_in_group",
label = "Select funds :",
choices = "" ),
br()
) )
) )
)
[EDIT]:
As per your latest update I have modified the server code so that checkboxGrouptInput is updated as dataset changes and also the table is rendered for the checked columns.
shinyServer( function(input, output, session) {
dataset_list <- list( "rock" = rock,
"pressure" = pressure,
"cars" = cars
)
observeEvent( input$n_select_input, {
selected_dataset <- reactive({
selected_list <- list()
for( i in 1:input$n_select_input ){
selected_list[[i]] <- dataset_list[[i]]
}
names(selected_list) <- names( dataset_list )[1:input$n_select_input]
selected_list
})
colname_indata_list <- reactive({
colname.indata.list <- list()
for( set in names( selected_dataset() ) ){
colname.indata.list[[set]] <- colnames( selected_dataset()[[set]] )
}
colname.indata.list
})
choice_cand <- reactive({
names(selected_dataset()) })
updateSelectInput( session,
"dataset",
choices = as.character( choice_cand() )
)
######################################Start: Modified#############################
observe({
input$dataset ##Added so that this observe is called when the input$dataset changes
choices_cand <- reactive({
colname_indata_list()[[input$dataset]] })
updateCheckboxGroupInput( session,
"column",
choices = as.character( choices_cand()) ,
selected = as.character( choices_cand())
)
})
})
######################################End: Modified#############################
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"pressure" = pressure,
"cars" = cars)
})
output$table <- renderTable({
datasetInput()[,input$column]##only selected columns are displayed
})
} )
Hope this helps!