Hide button created with modules within server - shiny

I have an app that has lots of tabItems and for each one of them I specify which files should be placed in a certain directory (in the example below I use getwd()) so that the app can run certain procedures.
These files will be listed in a "table", along with buttons and other features.
At times a file produced in one tabItem will be used as an input in another..
and I would like to hide the button created dynamically in the module for this file in the tabItem that uses the file as an input.
I've found how this can be done from within the module , but I would like to know if it possible to do it from the server.
Here is the small version of this app with what I've tried:
## global ----
library(shiny)
library(shinydashboard)
library(shinyBS)
library(shinyjs)
find_file_flex <- function(dir, extension, name_pattern, temp.rm=FALSE) {
files <- list.files(dir, pattern = name_pattern)
exts <- stringr::str_sub(files, -nchar(extension))
files <- files[exts == extension]
if(temp.rm) {
temp <- stringr::str_detect(files, pattern = "^([~][$])")
files <- files[!temp]
}
if (length(files) == 1){
file.path(dir, files)
} else if (length(files) > 1) {
date <- gsub(pattern = "-", replacement = "", basename(dir))
time_start <- unlist(gregexpr(pattern = date, files))
times <- stringr::str_sub(files, time_start, time_start + 13)
file.path(dir, files[times == max(times)])
} else { NA }
}
## dir_files ----
dir_files <- list(
file1 = list(
name_pattern = "-name_pattern1",
extension = ".txt",
sep = ";",
dec = ".",
label = "File1"
),
file2 = list(
name_pattern = "-name_pattern2",
extension = ".txt",
sep = ";",
dec = ".",
label = "File2"
)
)
## files_ui ----
files_ui <- tagList(
file1 = list(
button_icon = icon("download"),
info_modal_content = div("1. Much info! Such knowledge!")
),
file2 = list(
button_icon = icon("refresh"),
info_modal_content = div("2. Much info! Such knowledge!")
)
)
## chores_info ----
chores_info <- list(
home = list(
label = "Homez!",
input = c("file1","file2"),
output = "file2"
)
)
## modules ----
tr_fileOutput <- function(id) {
ns <- NS(id)
tagList(
tagList(
tags$tr(
# id = ns("tr"),
tags$td(uiOutput(ns("info_actionLink")), colspan = "1"),
tags$td(uiOutput(ns("labelLink")), colspan = "7"),
tags$td(uiOutput(ns("button")), colspan = "1")
),
tags$tr(
tags$td(uiOutput(ns("warn")), colspan = "10")
)
),
uiOutput(ns("info_modal"))
)
}
tr_file <- function(input, output, session, file, path) {
ns <- session$ns
file_path <- reactive({
invalidateLater(2000, session)
obj <- dir_files[[file]]
if(is.null(obj$dir)) obj$dir <- path()
find_file_flex(obj$dir, obj$extension, obj$name_pattern, temp.rm = TRUE)
})
output$info_actionLink <- renderUI({
actionLink(ns("info_actionLink"), label = NULL, icon = icon("info-circle"))
})
output$labelLink <- renderUI({
label <- dir_files[[file]]$label
if(is.na(file_path())) return(label)
actionLink(ns("labelLink"), label = label)
})
output$button <- renderUI({
icon <- files_ui[[file]]$button_icon
if(is.null(icon)) return(NULL)
bsButton(ns("button"), label = NULL, icon = icon,
size = "extra-small", class = "bvmf-blue")
})
output$info_modal <- renderUI({
content <- files_ui[[file]]$info_modal_content
title <- dir_files[[file]]$name_pattern
title <- div("Give me the Info ", tags$small(span("(", title, ")")))
bsModal(ns("info_modal"), title = title, trigger = NULL, content)
})
# trigger info_modal
observeEvent(input[["info_actionLink"]],
toggleModal(session, "info_modal", toggle = "open"))
# hyperlink para o labelLink
observeEvent(input[["labelLink"]], shell.exec(file_path()))
}
table_filesOutput <- function(id) {
ns <- NS(id)
tagList(
uiOutput(ns("info_modal")),
htmlOutput(ns("table"))
)
}
table_files <- function(input, output, session, files, path) {
ns <- session$ns
observe({
lapply(files, function(file) {
callModule(module = tr_file, id = file,
file = file, path = path)
})
})
output$table <- renderUI({
x <- lapply(files, function(file) tr_fileOutput(ns(file))[1] )
tags$table(x, id = ns("table"), style = "width: 100%;")
})
output$info_modal <- renderUI({
lapply(files, function(file) tr_fileOutput(ns(file))[2] )
})
}
## ui ----
ui <- dashboardPage(
skin = "blue",
dashboardHeader(
title = format(Sys.Date(), "%d/%m/%Y")
),
dashboardSidebar(
sidebarMenu(
id = "sidebarMenu",
menuItem("Home", tabName = "home", icon = icon("home"))
)
),
dashboardBody(
id = "dashboardBody",
useShinyjs(),
tabItems(
tabItem(
tabName = "home",
column(
width = 3,
wellPanel(
table_filesOutput("home-input")
),
wellPanel(
table_filesOutput("home-output")
)
)
)
)
)
)
## server ----
server <- shinyServer(function(input, output, session) {
date <- reactive({ Sys.Date() })
dir_date <- reactive({ getwd() })
callModule(table_files, "home-input",
files = chores_info[["home"]]$input, path = dir_date)
callModule(table_files, "home-output",
files = chores_info[["home"]]$output, path = dir_date)
observe({
# not sure why this is not hiding the button :(
hide("home-input-file2-button")
})
# code to deal with buttons and such
session$onSessionEnded(stopApp)
})
## ----
shinyApp(ui = ui, server = server)

Related

Save results from dynamically filtered data to a csv file

I'm trying to save the result of dynamically filtered data into a csv file ; I created a button etc but the app freezes up when i press it... any help would be much appreciated i'm new to Shiny unfortunately
library(dplyr)
library(shinyWidgets)
fpath <- '/dbfs/May2022'
# Define UI
ui <- fluidPage(theme = shinytheme("spacelab"),
navbarPage(
"Display Data",
tabPanel(
"Select File",
sidebarPanel(
selectInput('selectfile','Select File',choice = list.files(fpath, pattern = ".csv")),
mainPanel("Main Panel",dataTableOutput("ftxtout"),style = "font-size:50%") # mainPanel
), #sidebarPanel
), #tabPanel
tabPanel("Subset Data",
sidebarPanel(
dropdown(
label = "Please Select Columns to Display",
icon = icon("sliders"),
status = "primary",
pickerInput(
inputId = "columns",
# label = "Select Columns",
choices = NULL,
multiple = TRUE
)#pickerInput
), #dropdown
selectInput("v_attribute1", "First Attribute to Filter Data", choices = NULL),
selectInput("v_attribute2", "Second Attribute to Filter Data", choices = NULL),
selectInput("v_filter1", "First Filter", choices = NULL),
selectInput("v_filter2", "Second Filter", choices = NULL),
textInput("save_file", "Save to file:", value=""),
actionButton("doSave", "Save Selected Data")
), #sidebarPanel
mainPanel(tags$br(),tags$br(),
h4("Data Selection"),
dataTableOutput("txtout"),style = "font-size:70%"
) # mainPanel
), # Navbar 1, tabPanel
tabPanel("Create Label", "This panel is intentionally left blank")
) # navbarPage
) # fluidPage
# Define server function
server <- function(input, output, session) {
output$fileselected<-renderText({
paste0('You have selected: ', input$selectfile)
})
info <- eventReactive(input$selectfile, {
fullpath <- file.path(fpath,input$selectfile)
read.csv(fullpath, header = TRUE, sep = ",")
})
observeEvent(info(), {
df <- info()
vars <- names(df)
# Update select input immediately after clicking on the action button.
updatePickerInput(session, "columns","Select Columns", choices = vars, selected=vars[1:2])
})
observeEvent(input$columns, {
vars <- input$columns
updateSelectInput(session, "v_attribute1","First Attribute to Filter Data", choices = vars)
updateSelectInput(session, "v_attribute2","Second Attribute to Filter Data", choices = vars, selected=vars[2])
})
observeEvent(input$v_attribute1, {
choicesvar1=unique(info()[[input$v_attribute1]])
req(choicesvar1)
updateSelectInput(session, "v_filter1","First Filter", choices = choicesvar1)
})
observeEvent(input$v_attribute2, {
choicesvar2=unique(info()[[input$v_attribute2]])
req(choicesvar2)
updateSelectInput(session, "v_filter2","Second Filter", choices = choicesvar2)
})
output$ftxtout <- renderDataTable({
head(info())
}, options =list(pageLength = 5))
output$txtout <- renderDataTable({
f <- info() %>% subset(select = input$columns)
f$var1 <- f[[input$v_attribute1]]
f$var2 <- f[[input$v_attribute2]]
ff <- f %>% dplyr::filter(var1 == input$v_filter1 & var2 == input$v_filter2)
fff <- ff %>% subset(select=-c(var1,var2))
head(fff)
}, options =list(pageLength = 5)
) #renderDataTable
#Saving data
observeEvent(input$doSave, {
req(input$columns,input$v_attribute1,input$v_attribute2,input$v_filter1,input$v_filter2)
f <- info() %>% subset(select = input$columns)
f$var1 <- f[[input$v_attribute1]]
f$var2 <- f[[input$v_attribute2]]
ff <- f %>% dplyr::filter(var1 == input$v_filter1 & var2 == input$v_filter2)
fff <- ff %>% subset(select=-c(var1,var2))
fullfpath <- paste0(file.path(fpath,input$save_file),".csv",sep="")
write.csv(fff,fullfpath, row.names = True)
Save_done <- showNotification(paste("Data Has been saved"), duration = NULL)
})
} # server
# Create Shiny object
shinyApp(ui = ui, server = server)
I've tried a few different things but can't get it work, i'm not sure what i'm doing wrong here!
You have a typo when calling write.csv. The argument row.names should be TRUE and not True.
I also took the time to write the last observeEvent used to save the data to avoid creating two columns just for doing the subsetting.
observeEvent(input$doSave, {
req(
input$columns, input$v_attribute1,
input$v_attribute2, input$v_filter1,
input$v_filter2, input$save_file
)
df <- info() %>% select(all_of(input$columns))
df_filtered <- df %>%
dplyr::filter(
.data[[input$v_attribute1]] == input$v_filter1 &
.data[[input$v_attribute2]] == input$v_filter2
)
fullfpath <- paste0(file.path(fpath, input$save_file), ".csv", sep = "")
write.csv(df_filtered, fullfpath, row.names = TRUE)
Save_done <- showNotification(paste("Data Has been saved"), duration = NULL)
})
Full app:
library(dplyr)
library(shinyWidgets)
library(shinythemes)
fpath <- "sample_datasets"
# Define UI
ui <- fluidPage(
theme = shinytheme("spacelab"),
navbarPage(
"Display Data",
tabPanel(
"Select File",
sidebarPanel(
selectInput("selectfile", "Select File", choice = list.files(fpath, pattern = ".csv")),
mainPanel("Main Panel", dataTableOutput("ftxtout"), style = "font-size:50%") # mainPanel
), # sidebarPanel
), # tabPanel
tabPanel(
"Subset Data",
sidebarPanel(
dropdown(
size = "xs",
label = "Please Select Columns to Display",
icon = icon("sliders"),
status = "primary",
pickerInput(
inputId = "columns",
# label = "Select Columns",
choices = NULL,
multiple = TRUE
) # pickerInput
), # dropdown
selectInput("v_attribute1", "First Attribute to Filter Data", choices = NULL),
selectInput("v_attribute2", "Second Attribute to Filter Data", choices = NULL),
selectInput("v_filter1", "First Filter", choices = NULL),
selectInput("v_filter2", "Second Filter", choices = NULL),
textInput("save_file", "Save to file:", value = ""),
actionButton("doSave", "Save Selected Data")
), # sidebarPanel
mainPanel(
tags$br(),
tags$br(),
h4("Data Selection"),
dataTableOutput("txtout"),
style = "font-size:70%"
) # mainPanel
), # Navbar 1, tabPanel
tabPanel("Create Label", "This panel is intentionally left blank")
) # navbarPage
) # fluidPage
# Define server function
server <- function(input, output, session) {
output$fileselected <- renderText({
paste0("You have selected: ", input$selectfile)
})
info <- eventReactive(input$selectfile, {
fullpath <- file.path(fpath, input$selectfile)
read.csv(fullpath, header = TRUE, sep = ",")
})
observeEvent(info(), {
df <- info()
vars <- names(df)
# Update select input immediately after clicking on the action button.
updatePickerInput(session, "columns", "Select Columns", choices = vars, selected = vars[1:2])
})
observeEvent(input$columns, {
vars <- input$columns
updateSelectInput(session, "v_attribute1", "First Attribute to Filter Data", choices = vars)
updateSelectInput(session, "v_attribute2", "Second Attribute to Filter Data", choices = vars, selected = vars[2])
})
observeEvent(input$v_attribute1, {
choicesvar1 <- unique(info()[[input$v_attribute1]])
req(choicesvar1)
updateSelectInput(session, "v_filter1", "First Filter", choices = choicesvar1)
})
observeEvent(input$v_attribute2, {
choicesvar2 <- unique(info()[[input$v_attribute2]])
req(choicesvar2)
updateSelectInput(session, "v_filter2", "Second Filter", choices = choicesvar2)
})
output$ftxtout <- renderDataTable(
{
head(info())
},
options = list(pageLength = 5)
)
output$txtout <- renderDataTable(
{
f <- info() %>% subset(select = input$columns)
f$var1 <- f[[input$v_attribute1]]
f$var2 <- f[[input$v_attribute2]]
ff <- f %>% dplyr::filter(var1 == input$v_filter1 & var2 == input$v_filter2)
fff <- ff %>% subset(select = -c(var1, var2))
head(fff)
},
options = list(pageLength = 5)
) # renderDataTable
# Saving data
observeEvent(input$doSave, {
req(
input$columns, input$v_attribute1,
input$v_attribute2, input$v_filter1,
input$v_filter2, input$save_file
)
df <- info() %>% select(all_of(input$columns))
df_filtered <- df %>%
dplyr::filter(
.data[[input$v_attribute1]] == input$v_filter1 &
.data[[input$v_attribute2]] == input$v_filter2
)
fullfpath <- paste0(file.path(fpath, input$save_file), ".csv", sep = "")
write.csv(df_filtered, fullfpath, row.names = TRUE)
showNotification(paste("Data Has been saved"), duration = NULL)
})
} # server
# Create Shiny object
shinyApp(ui = ui, server = server)

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)

In shiny How to create a DT table, where i can add rows and delete the rows simultaneously

I have tried this in different ways and achieved one task, either add or delete., but i couldn't get complete solution in one, i might be missing some small concept somewhere.. I am adding the code , please help me complete my basic app.
library(shiny)
library(DT)
x<- data.frame(v1 = NA,
v2 = NA
),
ui = shinyUI(
fluidPage(
sidebarLayout(
sidebarPanel(
textInput("v1","v1","a"),
numericInput("V2","V2","1"),
# Row selection
numericInput(inputId = "row.selection", label = "Select row to be
deleted", min = 1, max = 100, value = "")
# Add button
actionButton(inputId = "add.button", label = "Add", icon =
icon("plus")),
# Delete button
actionButton(inputId = "delete.button", label = "Delete", icon =
icon("minus")),
),
mainPanel(
dataTableOutput('table')
)
)
)
),
Server side code
server = function(input, output, session) {
values <- reactiveValues()
values$df <- x
newEntry <- observe({
cat("newEntry\n")
if(input$add.button > 0) {
newRow <- data.frame(input$v1, input$v2)
isolate(values$df <- rbind(values$df,newRow))
}
})
deleteEntry <- observe({
cat("deleteEntry\n")
if(input$delete.button > 0) {
if(is.na(isolate(input$row.selection))){
values$df <- isolate(values$df[-nrow(values$df), ])
} else {
values$df <- isolate(values$df[-input$row.selection, ])
}
}
})
output$table = renderDataTable({
values$df
})
}
Try to use observeEvent rather than obser with actionbutton
and also, you have uppercase and lowercase issue with input$v2 (should be input$V2)
Try this modified code:
library(shiny)
library(DT)
x<- data.frame(v1 = NA,
v2 = NA
)
ui = shinyUI(
fluidPage(
sidebarLayout(
sidebarPanel(
textInput("v1","v1","a"),
numericInput("V2","V2","1"),
# Row selection
numericInput(inputId = "row.selection", label = "Select row to be
deleted", min = 1, max = 100, value = ""),
# Add button
actionButton(inputId = "add.button", label = "Add", icon =
icon("plus")),
# Delete button
actionButton(inputId = "delete.button", label = "Delete", icon =
icon("minus"))
),
mainPanel(
dataTableOutput('table')
)
)
)
)
server = function(input, output, session) {
values <- reactiveValues()
values$df <- x
observeEvent(input$add.button,{
cat("addEntry\n")
print(input$v1)
print(input$V2)
newRow <- data.frame(input$v1, input$V2)
colnames(newRow)<-colnames(values$df)
values$df <- rbind(values$df,newRow)
print(nrow(values$df))
})
observeEvent(input$delete.button,{
cat("deleteEntry\n")
if(is.na(input$row.selection)){
values$df <- values$df[-nrow(values$df), ]
} else {
values$df <- values$df[-input$row.selection, ]
}
})
output$table = renderDataTable({
values$df
})
}
shinyApp(ui,server)
Just run all the code above, and it should work properly.

Allow User to change input selection in selectizeInput

This app is creating a vector of standardised names which I create given some user input (number of channels and replicates). An example of the standard names given the number of channels = 4 and and replicates = 1 is as follows:
c("rep1_C0","rep1_C1","rep1_C2","rep1_C3")
I would like to allow the user to replace the value of the selection with their own custom value. For example to change the input "rep1_C0" to "Control_rep1". And then for it to then update the reactive vector in question. Here is my code:
library(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(column(5, numericInput("chans","# Channels",value = 4, min = 1)),
column(5, numericInput("reps","# Replicates",value = 1,min = 1))
),
uiOutput("selectnames")
),
mainPanel(
tableOutput("testcols")
)
)
))
server <- shinyServer(function(input, output) {
standardNames <- reactive({
paste("rep",rep(1:input$reps,each = input$chans),"_",
rep(paste("C",0:(input$chans - 1), sep = ""),input$reps),sep = "")
})
output$selectnames <- renderUI({
selectizeInput("selectnames", "Change Names", choices = standardNames(),
options = list(maxOptions = input$reps * input$chans))
})
## output
output$testcols <- renderTable({
standardNames()
})
})
shinyApp(ui = ui, server = server)
Is there some kind of option I can pass in the options sections that will allow this?
With selectizeInput you can set options = list(create = TRUE) to allow the user to add levels to the selection list, but I don't think that is what you want.
Instead, here is code that generates a text input box for each of the standard names, and allows the user to enter a label for them. It uses lapply and sapply to loop over each value and generate/read the inputs.
library(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(column(5, numericInput("chans","# Channels",value = 4, min = 1)),
column(5, numericInput("reps","# Replicates",value = 1,min = 1))
),
uiOutput("setNames")
),
mainPanel(
tableOutput("testcols")
)
)
))
server <- shinyServer(function(input, output) {
standardNames <- reactive({
paste("rep",rep(1:input$reps,each = input$chans),"_",
rep(paste("C",0:(input$chans - 1), sep = ""),input$reps),sep = "")
})
output$setNames <- renderUI({
lapply(standardNames(), function(thisName){
textInput(paste0("stdName_", thisName)
, thisName
, thisName)
})
})
labelNames <- reactive({
sapply(standardNames()
, function(thisName){
input[[paste0("stdName_", thisName)]]
})
})
## output
output$testcols <- renderTable({
data.frame(
stdName = standardNames()
, label = labelNames()
)
})
})
shinyApp(ui = ui, server = server)
If you want to hide the list unless the user wants to add labels, you can use a simple checkbox, like this, which hides the label making list until the use checks the box to show it.
library(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(column(5, numericInput("chans","# Channels",value = 4, min = 1)),
column(5, numericInput("reps","# Replicates",value = 1,min = 1))
)
, checkboxInput("customNames", "Customize names?")
, uiOutput("setNames")
),
mainPanel(
tableOutput("testcols")
)
)
))
server <- shinyServer(function(input, output) {
standardNames <- reactive({
paste("rep",rep(1:input$reps,each = input$chans),"_",
rep(paste("C",0:(input$chans - 1), sep = ""),input$reps),sep = "")
})
output$setNames <- renderUI({
if(!input$customNames){
return(NULL)
}
lapply(standardNames(), function(thisName){
textInput(paste0("stdName_", thisName)
, thisName
, thisName)
})
})
labelNames <- reactive({
if(!input$customNames){
return(standardNames())
}
sapply(standardNames()
, function(thisName){
input[[paste0("stdName_", thisName)]]
})
})
## output
output$testcols <- renderTable({
data.frame(
stdName = standardNames()
, label = labelNames()
)
})
})
shinyApp(ui = ui, server = server)
Alternatively, if you think the user may want to only change one or a small number of labels, here is a way to allow them to choose which standard name they are applying a label to:
library(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(column(5, numericInput("chans","# Channels",value = 4, min = 1)),
column(5, numericInput("reps","# Replicates",value = 1,min = 1))
)
, uiOutput("setNames")
),
mainPanel(
tableOutput("testcols")
)
)
))
server <- shinyServer(function(input, output) {
vals <- reactiveValues(
labelNames = character()
)
standardNames <- reactive({
out <- paste("rep",rep(1:input$reps,each = input$chans),"_",
rep(paste("C",0:(input$chans - 1), sep = ""),input$reps),sep = "")
vals$labelNames = setNames(out, out)
return(out)
})
output$setNames <- renderUI({
list(
h4("Add labels")
, selectInput("nameToChange", "Standard name to label"
, names(vals$labelNames))
, textInput("labelToAdd", "Label to apply")
, actionButton("makeLabel", "Set label")
)
})
observeEvent(input$makeLabel, {
vals$labelNames[input$nameToChange] <- input$labelToAdd
})
## output
output$testcols <- renderTable({
data.frame(
stdName = standardNames()
, label = vals$labelNames
)
})
})
shinyApp(ui = ui, server = server)

Input 2nd file in R Shiny only if results from 1st Input file satisfies requirement

I am relatively new on using R Shiny, I am trying to build Shiny app for predictive modeling.
I have R code ready with me and have loaded them in R Shiny.
Please refer to below ui.r and server.r which I have prepared.
shinyUI(
fluidPage(
titlePanel("Prediction"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose Past CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
conditionalPanel(
condition = "output.fileUploaded",
fileInput('file2', 'Choose Future CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
downloadButton("downloadData", "Download Prediction")
)
),
mainPanel(
tabsetPanel(type = "tabs",
tabPanel('Results', (DT::dataTableOutput('table'))),
tabPanel("Model Summary",
verbatimTextOutput("summary"))
)
)
)
)
)
shinyServer(function(input, output) {
# hide the output
output$fileUploaded <- reactive({
return(!is.null(input$file1))
})
outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)
data <- reactive({
File <- input$file1
if (is.null(File))
return(NULL)
complete <- read.csv(File$datapath,header=T,na.strings=c(""))
File1 <- input$file2
if (is.null(File1))
return(NULL)
raw.data <- read.csv(File1$datapath,header=T,na.strings=c(""))
#Change all variable to factor
complete[] <- lapply(complete, factor)
complete$Target <- recode(complete$Target," 'YES' = 1; 'Yes' = 1; 'NO' = 0 " )
set.seed(33)
splitIndex <- createDataPartition(complete$Target, p = .75, list = FALSE, times = 1)
trainData <- complete[ splitIndex,]
testData <- complete[-splitIndex,]
fitControl <- trainControl(method = "repeatedcv", number = 4, repeats = 4)
set.seed(33)
gbmFit1 <- train(as.factor(Target) ~ ., data = trainData, method = "gbm", trControl = fitControl,verbose = FALSE)
pred <- predict(gbmFit1, testData,type= "prob")[,2]
perf = prediction(pred, testData$Target)
pred1 = performance(perf, "tpr","fpr")
acc.perf <- performance(perf, "acc")
ind = which.max( slot(acc.perf, "y.values")[[1]])
acc = slot(acc.perf, "y.values")[[1]][ind]
output$summary <- renderPrint({
print(c(Accuracy=acc))
})
raw.data[] <- lapply(raw.data, factor)
testpred <- predict(gbmFit1, raw.data,type= "prob")[,2]
final = cbind(raw.data, testpred)
final
})
output$table = DT::renderDataTable({
final <- data()
DT::datatable(
data(), options = list(
pageLength = 5)
)
})
output$downloadData <- downloadHandler(
filename = function() { paste('SLA Prediction', '.csv', sep='') },
content = function(file) {
write.csv(data(),file)
}
)
return(output)
})
Model is created using first Input file, my requirement is user should asked to upload 2nd input file (for which they want to predict results) only if model Accuracy which calculated using first input file stored in variable acc should be more than 0.9, I am not able to get solution for this, can anyone help me in this.
Now the second file input depends on the variable acc and shows up only when it is bigger than 0.9. I additionally did some changes, mainly because your code didn't work on my laptop :). Instead of return(NULL) you can use the function req to ensure that the values are available.
library(shiny)
library(shinysky)
library(shinythemes)
library(caret)
library(gbm)
library(ROCR)
library(car)
ui <- shinyUI(
fluidPage(
theme = shinytheme("united"), # added new theme from the package 'shinythemes'
titlePanel("Prediction"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose Past CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
uiOutput("dynamic")
),
mainPanel(
# added busyIndicator
busyIndicator(text = "Calculation in progress..",
img = "shinysky/busyIndicator/ajaxloaderq.gif", wait = 500),
tabsetPanel(type = "tabs",
tabPanel('Results',
(DT::dataTableOutput('table'))),
tabPanel("Model Summary",
verbatimTextOutput("summary")),
tabPanel("Predictions",
DT::dataTableOutput('tablePred'))
)
)
)
)
)
server <- shinyServer(function(input, output) {
# hide the output
output$fileUploaded <- reactive({
return(!is.null(input$file1))
})
outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE)
data <- reactive({
File <- input$file1
req(File)
complete <- read.csv(File$datapath,header=T,na.strings=c(""))
complete
})
model <- reactive({
complete <- lapply(data(), factor)
complete$Target <- recode(data()$Target," 'YES' = 1; 'Yes' = 1; 'NO' = 0 " )
set.seed(33)
splitIndex <- createDataPartition(data()$Target, p = .75, list = FALSE, times = 1)
trainData <- data()[ splitIndex,]
testData <- data()[-splitIndex,]
fitControl <- trainControl(method = "repeatedcv", number = 4, repeats = 4)
set.seed(33)
gbmFit1 <- train(as.factor(Target) ~ ., data = trainData, method = "gbm", trControl = fitControl,verbose = FALSE)
pred <- predict(gbmFit1, testData, type= "prob")[,2]
perf = prediction(pred, testData$Target)
pred1 = performance(perf, "tpr","fpr")
acc.perf <- performance(perf, "acc")
ind = which.max( slot(acc.perf, "y.values")[[1]])
acc = slot(acc.perf, "y.values")[[1]][ind]
retval <- list(model = gbmFit1, accuracy = acc)
return(retval)
})
output$summary <- renderPrint({
req(model())
print(model())
})
output$dynamic <- renderUI({
req(model())
if (model()$accuracy >= 0.9)
list(
fileInput('file2', 'Choose Future CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
downloadButton("downloadData", "Download Prediction")
)
})
data2 <- reactive({
req(input$file2)
File1 <- input$file2
raw.data <- read.csv(File1$datapath,header=T,na.strings=c(""))
raw.data
})
preds <- reactive({
raw.data <- data2()
testpred <- predict(model()$model, raw.data,type= "prob")[,2]
print(testpred)
final = cbind(raw.data, testpred)
final
})
output$table = DT::renderDataTable({
DT::datatable(data(), options = list(pageLength = 15))
})
output$tablePred = DT::renderDataTable({
req(input$file2)
DT::datatable(preds(), options = list(pageLength = 15))
})
output$downloadData <- downloadHandler(
filename = function() { paste('SLA Prediction', '.csv', sep='') },
content = function(file) {
write.csv(preds(),file)
}
)
return(output)
})
shinyApp(ui, server)