Shiny app: nothing changes when clicking on action button - r

Building on multiple stackoverflow questions, I tried to build this app which contains two action buttons the first one shows a data table the second one should open another sourced app but actually, nothing changes but in the global environment all list, functions, and dataframes are reflecting.
the used code.
#UI.R
library(shiny)
library(shinydashboardPlus)
library(DT)
library(readxl)
library(dplyr)
library(formattable)
library(shinydashboard)
library(shinyjqui)
library(shinyjs)
library(shinythemes)
library(markdown)
title <- "emblem"
ui = fluidPage(theme=shinytheme("superhero"),
dashboardPage(dashboardHeader(title = title, titleWidth = 200),
dashboardSidebar(selectInput("listofitems","Items List",c("Home","Group","Clients"), selected = "Home")),
dashboardBody(
useShinyjs(),
uiOutput("ui_myHome"))))
#SERVER.R
Clientsbutton<-fluidPage(theme=shinytheme("yeti"),
DT::dataTableOutput("mytable"))
shinyServer(function(input, output, session){
output$mytable = DT::renderDataTable({
mtcars
})
output$ui_myHome<-renderUI({
if (input$listofitems == 'Home'){(fluidPage(
widgetUserBox(title = "Clients",
shiny::actionButton(inputId='clientsmainbuttonId', label="Click here"),
type = 2, src = "https://adminlte.io/themes/AdminLTE/dist/img/user7-128x128.jpg", color = "yellow"),
widgetUserBox(title = "Group",
shiny::actionButton(inputId='GroupbuttonId', label="Click here"),
type = 2, src = "https://adminlte.io/themes/AdminLTE/dist/img/user7-128x128.jpg", color = "green")))}
else if (input$listofitems == 'Clients'){(Clientsbutton)}
else if (input$listofitems == 'Group'){(source("testsource.R",local = T)$value)}
})
observeEvent (input$GroupbuttonId,{
#browser
source("testsource.R",local = T)$value
})
observeEvent(input$clientsmainbuttonId,{updateSelectInput(session,"listofitems","Items List", choices =c("Home","Group","Clients"), selected = "Clients")},ignoreInit = TRUE)
observeEvent(input$logo,{updateSelectInput(session,"listofitems","Items List", choices =c("Home","Group","Clients"), selected = "Home")},ignoreInit = TRUE)
})
#TO BE SOURCED APP
File name testsource.R
rm(list = ls())
library(shiny)
shinyApp(
ui=shinyUI(basicPage(
actionButton("go", "Go"),
numericInput("n", "n", 50),
plotOutput("plot")
)),
server=shinyServer(function(input, output, session){
randomVals <- eventReactive(input$go, {
runif(input$n)
})
output$plot <- renderPlot({
hist(randomVals())
})
})
)

Related

How do I combine Shiny and esquisse together?

I want to create a shiny app that allows me to upload a file then make some change on the data uploaded (very important step) and then finally use esquisse to visualize the data.
My code doesn't work. can someone see the problem?
library(esquisse)
library(shiny)
ui <- fluidPage(
titlePanel("Use esquisse as a Shiny module"),
sidebarLayout(
sidebarPanel(
fileInput("file", "Data", buttonLabel = "Upload..."),
),
mainPanel(
tabsetPanel(
tabPanel(
title = "Data analysis",
esquisse_ui(
id = "esquisse",
header = FALSE # dont display gadget title
)),))))
server <- function(input, output, session) {
data_r = reactive({
req(input$file)
dt = read.csv(input$file$datapath, header = T, sep = ",")
dt
})
esquisse_res <- callModule(
module = esquisse_server,
id = "esquisse",
data = data_r()
)
}
shinyApp(ui, server)

How to create Popup window of DataTable/plot in ShinyDashboard?

I am creating ShinyDashboard which reads the csv file inputted by user and displays 2 plots at the top and datatable at the bottom of dashboards. For this I used box to built my Dashboard. Next, I would like create popup for each boxes so the box output displays bigger in size to the enduser. For this I am following the post mentioned here. However, whenever I use ModalDialog under ui code as suggested by Pork Chop. The table output doesn't return anything. Not sure if I am using ModalDialog correctly ? Below is my ui and server code.
Thank in advance for help and effort!
ui
library(shiny)
library(shinydashboard)
library(dplyr)
library(ggplot2)
library(shinyBS)
library(DT)
ui<-dashboardPage(
dashboardHeader(title="Missing",titleWidth = 230),
dashboardSidebar(
fileInput("file1", "Upload CSV File below",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
)),
dashboardBody(
fluidRow(
box(plotOutput("Plot1"),collapsible = TRUE,title="Columns ",solidHeader = TRUE,status = "primary"),
box(plotOutput("Plot2"),collapsible=TRUE,title="Columns data Type",solidHeader = TRUE,status = "primary"),
fluidRow(column(width=12,box( bsModal("modalExample", "Data Table", "My_datatable", size = "large",dataTableOutput("My_datatable")),width = NULL,collapsible = TRUE))
)
)
)
)
Server:
server<- function(input, output,session) {
output$Plot1 <- renderPlot({
plot(cars)
})
output$Plot2 <- renderPlot({ plot(pressure)})
output$My_datatable <- renderDT({iris[1:7,]})
}
# Run the application
shinyApp(ui = ui, server = server)
As shown in the answer you need to wrap each item you want to popout in a div() and give an id. Then use that id to popout and display what you wish. Try this
library(shiny)
library(shinydashboard)
library(dplyr)
library(ggplot2)
library(shinyBS)
library(DT)
#library(visdat)
ui<-dashboardPage(
dashboardHeader(title="Missing",titleWidth = 230),
dashboardSidebar(
fileInput("file1", "Upload CSV File below",
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv")
)),
dashboardBody(
fluidRow(
div(id="popme1", box(plotOutput("Plot1"),collapsible = TRUE,title="Columns with null",solidHeader = TRUE,status = "primary")),
bsModal("modalExample1", "Plot1", "popme1", size = "large", plotOutput("Plot11")),
div(id="popme2", box(plotOutput("Plot2"),collapsible=TRUE,title="Data Types of columns",solidHeader = TRUE,status = "primary")),
bsModal("modalExample2", "Plot2", "popme2", size = "large", plotOutput("Plot22")),
div(id="popme3", fluidRow(column(width=8,box(DTOutput("Missing_datatable"), width = NULL,collapsible = TRUE)) )),
bsModal("modalExample3", "Data Table", "popme3", size = "large", DTOutput("Missing_datatable2"))
)
)
)
server<- function(input, output,session) {
output$Plot1 <- renderPlot({
plot(cars)
})
output$Plot11 <- renderPlot({
plot(cars)
})
output$Plot22 <- renderPlot({ plot(pressure)})
output$Plot2 <- renderPlot({ plot(pressure) })
output$Missing_datatable <- renderDT({iris[1:7,]})
output$Missing_datatable2 <- renderDT({iris[1:7,]})
}
# Run the application
shinyApp(ui = ui, server = server)

Unable to clear the displayed output in ShinyApp using actionButton

I'm building a shinyApp on mtcars data. I got 2 actionButtons (Go & Clear).
The Go button is for displaying the output on mainPanel whereas the Clear button is for clearing that output.
My Clear button isn't working due to some unforeseen reason. Can somebody please have a look at my codes. I shall be extremely grateful.
library(shiny)
library(DT)
library(dplyr)
library(shinythemes)
library(htmlwidgets)
library(shinyWidgets)
library(shinydashboard)
data_table<-mtcars
#ui
ui = fluidPage(
sidebarLayout(
sidebarPanel (
uiOutput("cyl_selector"),
uiOutput("disp_selector"),
actionButton(inputId = "go", label = "Go"),
actionButton(inputId = "reset", label = "Clear")),
mainPanel(
DT::dataTableOutput('mytable') )))
#server
server = function(input, output, session) {
output$cyl_selector <- renderUI({
selectInput(inputId = "cyl",
label = "cyl:", multiple = TRUE,
choices = c( unique(as.character(data_table$cyl))),
selected = c('4')) })
output$disp_selector <- renderUI({
available <- data_table[c(data_table$cyl %in% input$cyl ), "disp"]
selectInput(
inputId = "disp",
label = "disp:",
multiple = TRUE,
choices = c('All',as.character(unique(available))),
selected = 'All') })
thedata <- eventReactive(input$go,{
data_table<-data_table[data_table$cyl %in% input$cyl,]
if(input$disp != 'All'){
data_table<-data_table[data_table$disp %in% input$disp,]
}
data_table
})
# thedata <- eventReactive(input$reset,{
# data_table<-NULL
# })
output$mytable = DT::renderDataTable({
DT::datatable( filter = "top", rownames = FALSE, escape = FALSE,
options = list(pageLength = 50, autowidth=FALSE,
dom = 'Brtip' ),
{
thedata() # Call reactive thedata()
})
})}
shinyApp(ui = ui, server = server)
I didn't analyze your script completly, but i can see that it doesn't call the second button at all (Clear). You made an eventReactive() using input$go for the first button to make the plot, but you need to call input$reset too if you want to make it work.

Modify my rChart based on a reactive input?

I am having trouble with some code that I've written.
Here is a sample of the dataset: https://docs.google.com/spreadsheets/d/1C_P5xxzYr7HOkaZFfFiDhanqDSuSIrd2UkiC-6_G2q0/edit?usp=sharing
Objective:
I have a dataset that contains a column of Purchase_Month, candy and freq of the number of times that type of candy was purchased in that given month.
I have an rPlot which I was to change based on the chosen Candy bar in the SelectInput. And output a line chart based on the number of times that candy was purchased that month.
I have my current code below, but it tells me that candyCount is not found.
## ui.R ##
library(shinydashboard)
library(rCharts)
dashboardPage(
dashboardHeader(title = "Dashboard"),
dashboardSidebar(
width = 150,
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("bar-chart"))
)
),
dashboardBody(
sidebarPanel(
htmlOutput("candy")
),
mainPanel(
showOutput("plot2", "polycharts")
))
)
##server.R##
library(rCharts)
library(ggplot2)
library(ggvis)
server <- function(input, output, session) {
output$candy <- renderUI({
available2 <- dataset[(dataset$candy == input$candy), "candy"]
selectInput(
inputId = "candy",
label = "Choose a candy: ",
choices = sort(as.character(unique(available2))),
selected = unique(available2[1])
)
})
observeEvent(input$candy, {
candyChoice<- toString(input$customer_issue)
print(candyChoice)
candyCount<- dataset[dataset$candy == candyChoice, ]
})
})
output$plot2 <- renderChart2({
p2 <- rPlot(freq~purchase_month, data = candyCount, type = 'line')
p2$guides(y = list(min = 0, title = ""))
p2$guides(y = list(title = sprintf("%s Claims",input$candy)))
p2$addParams(height = 300, dom = 'chart2')
return(p2)
})
}
Updated Data: Why wouldn't this work?
candyCount<- reactive({
dataset[dataset$candy == input$candy, ]
})
output$plot2 <- renderChart2({
p2 <- rPlot(freq~purchase, data = candyCount(), type = 'line')
p2$guides(y = list(min = 0, title = ""))
p2$guides(y = list(title = ""))
p2$addParams(height = 300, dom = 'chart2')
return(p2)
})
output$candy <- renderUI({
available2 <- dataset[(dataset$candy == input$candy), "candy"]
selectInput(
inputId = "candy",
label = "Choose a candy: ",
choices = sort(as.character(unique(available2))),
selected = unique(available2[1])
)
})
In the above you are trying to subset by an input, which is inside your output. The selectInput needs to be inside UI.R.
A working basic example you may find useful.
library(shiny)
df <- read.csv("/path/to/my.csv")
ui <- shinyUI(pageWithSidebar(
headerPanel('Candy Data'),
sidebarPanel(
selectInput('candy', 'Candy', unique(as.character(df[,2])), selected = "Twix")
),
mainPanel(
plotOutput('plot1')
)
))
server <- shinyServer(function(input, output, session) {
selectedData <- reactive({
df[which(df[,2] == input$candy),3]
})
output$plot1 <- renderPlot({
barplot(selectedData())
})
})
shinyApp(ui, server)
In the above example the ui renders a selectInput which has the ID candy. The value, i.e the candy selected is now assigned to input$candy scope. In server we have a reactive function watching for any input change. When the user selects a new candy this function, df[which(df[,2] == input$candy),3] is saying "subset my data frame, df, by the new input$candy". This is now assigned to the selectedData(). Finally we render then boxplot.
EDIT
server.R
require(rCharts)
options(RCHART_WIDTH = 500)
df <- read.csv("path/to/my.csv")
shinyServer(function(input, output, session) {
selectedData <- reactive({
df[which(df[,2] == input$candy),]
})
output$plot1 <- renderChart({
p <- rPlot(freq~purchase_month, data = selectedData(), type = "line")
p$addParams(dom = 'plot1')
return(p)
})
})
ui.R
require(rCharts)
options(RCHART_LIB = 'polycharts')
shinyUI(pageWithSidebar(
headerPanel('Candy Data'),
sidebarPanel(
selectInput('candy', 'Candy', unique(as.character(df[,2])), selected = "Twix")
),
mainPanel(
showOutput('plot1', 'polycharts')
)
))
save files in directory and then runApp.
At available2 you're filtering the data about a selected candy with dataset$candy == input$candy. But you use the same available2 to determine which are the choices at selectInput. I'm guessing you wanted: available2 <- dataset[, "candy"].

How to set a conditional panel to a selectinput in shiny?

I am trying to add a second inputpanel in my shiny application which content depend on the input of the first inputpanel choice, I tried tout use condional panel with no luck.
ui.R
TO <- read.csv("~/TO/TO/TO.csv", sep=";")
library(shiny)
shinyUI(fluidPage(
# Application title
titlePanel("dasboard"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
selectInput("country", label = h4("Pays"),
choices = levels(as.factor(TO$Pays))),
conditionalPanel(
condition = "input.country == 'Allemagne'",
selectInput("to", label = h4("Tour opérateur"),
choices = levels(as.factor(as.character(TO[as.character(TO$Pays)=="Allemagne",]$TO))))),
conditionalPanel(
condition = "input.country == 'Angleterre'",
selectInput("to", label = h4("Tour Operator"),
choices = levels(as.factor(as.character(TO[as.character(TO$Pays)=="Angleterre",]$TO)))))
...
The solution that I found is to create a conditionalPanel for every value of the first inputPanel But is the second inputPanel output is only correct for the first value.
Does anyone have a solution?
I know the approach below is not via the conditional panels, as I think it would be simpler to do it via examples given below.
First you can use updateSelectInput to update your entries, something like this
rm(list = ls())
library(shiny)
runApp(list(
ui = bootstrapPage(
selectInput('data', 'Data', c('mtcars', 'iris')),
selectInput('Cols', 'Columns', "")
),
server = function(input, output, session){
outVar <- reactive({
mydata <- get(input$data)
names(mydata)
})
observe({
updateSelectInput(session, "Cols",choices = outVar()
)})
}
))
Other way you can use renderUI to create the selectInput and populate it like so:
rm(list = ls())
library(shiny)
runApp(list(
ui = bootstrapPage(
selectInput('data', 'Data', c('mtcars', 'iris')),
uiOutput('columns')
),
server = function(input, output){
output$columns <- renderUI({
mydata <- get(input$data)
selectInput('columns2', 'Columns', names(mydata))
})
}
))
Edit: how to add multiple widgets inside the renderUI
You need to wrap your divs inside the tagList() like so:
rm(list = ls())
library(shiny)
runApp(list(
ui = bootstrapPage(
selectInput('data', 'Data', c('mtcars', 'iris')),
uiOutput('columns')
),
server = function(input, output){
output$columns <- renderUI({
mydata <- get(input$data)
tagList(
selectInput('columns2', 'Columns', names(mydata)),
selectInput('columns3', 'Columns 2', names(mydata)))
})
}
))

Resources