I have the following R Shiny Application:
library(shiny)
shinyApp(
ui = dashboardPage(
dashboardHeader(
title = "Tweetminer",
titleWidth = 350
),
dashboardSidebar(
width = 350,
sidebarMenu(
menuItem("Menu Item")
)
),
dashboardBody(
fluidRow(
tabBox(
tabPanel("Select tweets",
numericInput("tweet_amount", "Amount of tweets:", 10, min = 1, max = 100),
div(style="display:inline-block",numericInput("tweet_long", "Longitude:", 10, min = 1, max = 100)),
div(style="display:inline-block",numericInput("tweet_lat", "Latitude:", 10, min = 1, max = 100)),
#selectInput("tweet_name", "Account name", choices = c("#realDonaldTrump","#GorgeNails"), width = NULL, placeholder = NULL),
selectInput("tweet_name", "Account name", choices = c("#realDonaldTrump","#Yankees"), selected = NULL, multiple = FALSE,
selectize = TRUE, width = NULL, size = NULL),
actionButton("get_tweets", "Fetch the tweets"),
hidden(
div(id='text_div',
verbatimTextOutput("text")
)
)
)
)
)
)
),
server = function(input, output) {
test_list <- c(1,2,3)
run_function <- reactive({
for(i in test_list){
Sys.sleep(2)
}
})
observeEvent(input$get_tweets, {
run_function()
toggle('text_div')
output$text <- renderText({"You're now connecting to the API"})
})
}
)
This application should allow users to input parameters after which tweets will be scraped. However - because it will take some time Im looking for a way to inform users this will take a while.
Using this function:
observeEvent(input$get_tweets, {
run_function()
toggle('text_div')
output$text <- renderText({"You're now connecting to the API"})
})
I inform the user that the function (run_function() in this example, a mockup but just for reproducing purposes) is ready. However Im looking for a notice after you initiate the function and when its done.
So after you press the first time it should say something like - function initiated and after the function is ready -> "You .. api".
Any thoughts on what I should change to get this working?
You can use withProgress function, check this example:
output$plot <- renderPlot({
withProgress(message = 'Calculation in progress', detail = 'This may take a while...', value = 0, {
for (i in 1:15) {
incProgress(1/15)
Sys.sleep(0.25)
}
})
plot(cars)
})
More info
EDIT: New example:
library(shiny)
ui <- fluidPage(
actionButton(inputId = 'DoSomething', label = 'Do something'),
verbatimTextOutput('t1')
)
server <- function(input, output, session) {
output$t1 <- renderPrint('Doing nothing...')
run_function <- reactive({
withProgress(message = "Starting...", max = 60, value = 0, {
for (i in 1:25) {
incProgress(1)
Sys.sleep(0.25)
}
setProgress(message = "Connected..")
for (i in 1:25) {
incProgress(1)
Sys.sleep(0.25)
}
setProgress(message = "Doing Stuffs...")
for (i in 1:10) {
incProgress(1)
Sys.sleep(0.25)
}
setProgress(message = "Disconecting...")
})
return('Finish')
})
observeEvent(input$DoSomething, {
output$t1 <- renderPrint(run_function())
})
}
shinyApp(ui, server)
Related
I have a shiny app to load pictures and I should be able to select some of the images by clicking on them and the selected images will be recorded.
I want a function that I can select and mark pictures the same way you mark photos in the gallery of a phone.
Currently, I made an app that the selected images are replaced by an empty icon. Here is what I have tried:
ui <-fluidPage(column(
width=9,
align="center",
imageOutput(outputId = "img1", click = clickOpts(id = "img1_click", clip = FALSE),width = 150,height = 150,inline = TRUE)
,imageOutput(outputId = "img2", click = clickOpts(id = "img2_click", clip = FALSE),width = 150,height = 150,inline = TRUE)
))
server <- function(input, output, session) {
empty_img="/empty.jpeg"
vals=reactiveValues(img=list.files("/images/"))
vals2=reactiveValues(img=list.files("/images/"))
empty_img_to_normal_value=reactiveValues(m=1:length(vals$img))
output$img1 <- renderImage({
list(src = vals$img[1], width = "200", height = "200") } ,deleteFile = FALSE)
observeEvent(input$img1_click, {
if(empty_img_to_normal_value$m[1]==1){
vals$img[1]=empty_img
empty_img_to_normal_value$m[1]=0
}else{
vals$img[1]=vals2$img[1]
empty_img_to_normal_value$m[1]=1
}
})
output$img2 <- renderImage({
list(src = vals$img[2], width = "200", height = "200")} ,deleteFile = FALSE)
observeEvent(input$img2_click, {
if(empty_img_to_normal_value$m[2]==1){
vals$img[2]=empty_img
empty_img_to_normal_value$m[2]=0
}else{
vals$img[2]=vals2$img[2]
empty_img_to_normal_value$m[2]=1
}
})
}
Following our comments, I made a proper answer.
# list of images URLs, replace them with your images
lst_urls <- list("data/Rplot1.png", "data/Rplot1.png", "data/Rplot1.png", "data/Rplot1.png",
"data/Rplot5.png","data/Rplot5.png","data/Rplot5.png","data/Rplot5.png")
img_w <- "100%"
img_h <- 200
mod_img_UI <- function(id) {
ns <- NS(id)
tagList(
tags$style(".checkbox{margin-bottom: -40px;}"),
column(
width =2,
checkboxInput(
inputId = ns("select_img"), label = NULL
),
imageOutput(
outputId = ns("img"), width = img_w, height = img_h, inline = TRUE
)
)
)
}
mod_img_SERVER <- function(input, output, session, img_url){
ns <- session$ns
output$img <- renderImage({
list(src = img_url,
alt = "This is alternate text",
width = img_w,
height = img_h,
contentType = "image/png")
}, deleteFile = FALSE)
return(input$select_img)
}
ui <- fluidPage(
uiOutput("images")
)
server <- function(input, output, session) {
output$images <- renderUI({
lapply(
1:length(lst_urls),
function(i) {
mod_img_UI(id = paste0("img", i))
}
)
})
observe({
selected_imgs <- lapply(
1:length(lst_urls),
function(i) {
callModule(
module = mod_img_SERVER,
session = session,
id = paste0("img", i),
img_url = lst_urls[[i]]
)
}
)
print(paste("You picked :",lst_urls[unlist(selected_imgs)]))
})
}
shinyApp(ui, server)
I am setting up a module, with the purpose of having two data tables in the same app, in different tabs.
I would like to be able to edit and save each table separately.
In my code, only the first "save" button works, and it saves both data tables.
Ideally, each save button should work and save only the corresponding table.
Important: I use the modified version of DTedit:
devtools::install_github('DavidPatShuiFong/DTedit#2.2.1')
Here is my problematic code:
library(shiny)
library(DTedit)
myModuleUI <- function(id,nam) {
ns <- shiny::NS(id)
shiny::tagList(
br(),
##### needs corrections!!
tabsetPanel(tabPanel("XXX", dteditmodUI(ns(nam)),actionButton(ns("reset"), "Reset to Saved", styleclass = "warning"), actionButton(ns("saveBtn"), label = "save"), br(),
id=ns('tabset'), type = 'tabs')
)
)
####
}
myModule <- function(input, output, session,df,nam,taby,wb) {
dfr=reactiveVal()
dfr(df)
Grocery_List_Results <- shiny::callModule(
dteditmod,
id = nam,
thedata =dfr)
# ### save part
savd = data.frame(isolate(dfr()))
observeEvent(input$saveBtn, {
print("Q")
## Add worksheets
st = paste(taby,as.character(unclass(Sys.time())),sep="_")
addWorksheet(wb, st)
writeData(x = Grocery_List_Results$thedata,
wb = wb,
sheet = st)
saveWorkbook(wb, "wb.xlsx", overwrite = T)
savd <<- Grocery_List_Results$thedata
shinyalert(title = "Saved!", type = "success")
})
observeEvent(input$reset, {
dfr(savd)
print(dfr)
shinyalert(title = "Reset to saved data!", type = "info")
})
}
########
ui <- fluidPage(
h3('Grocery List'),
myModuleUI('myModule1',nam="groc"),br(),
myModuleUI('myModule1',nam="groc2")
)
server <- function(input, output, session) {
df= data.frame(
Buy = c('Tea', 'Biscuits', 'Apples',"Tea","Apples"),
Quantity = c(7, 2, 5,9,44),
stringsAsFactors = FALSE
)
file = "AICs.xlsx"
wb <- loadWorkbook(file)
shiny::callModule(myModule, 'myModule1',nam="groc",df=df,taby="Tea",wb)
shiny::callModule(myModule, 'myModule1',nam="groc2",df=df,taby="Apples",wb)
}
shinyApp(ui = ui, server = server)
Appreciate your time!
At long last,
and thanks to this thread,
it seems that I managed to solve this:
library( "openxlsx" )
library("shiny" )
library(shinyalert)
library(shinysky)
library(DTedit) ## used the modified version from https://github.com/DavidPatShuiFong/DTedit
#installed with devtools::install_github('DavidPatShuiFong/DTedit#2.2.1')
results_2_UI <- function(id,nam) {
useShinyalert()
ns <- NS(id)
tabPanel(
title = "Export1",
dteditmodUI(ns(nam)),
actionButton(ns("reset"), "Reset to Saved", styleclass = "warning"), actionButton(ns("saveBtn"), label = "save")
)
}
results_3_UI <- function(id,nam) {
useShinyalert()
ns <- NS(id)
tabPanel(
title = "Export2",
dteditmodUI(ns(nam)),
actionButton(ns("reset"), "Reset to Saved", styleclass = "warning"), actionButton(ns("saveBtn"), label = "save")
)
}
results <- function(input, output, session,df,nam,taby,wb) {
## do some complicated data transformations
dfr=reactiveVal()
dfr(df)
Grocery_List_Results <- shiny::callModule(
dteditmod,
id = nam,
thedata =dfr)
# ### save part
savd = data.frame(isolate(dfr()))
observeEvent(input$saveBtn, {
print("Q")
## Add worksheets
st = paste(taby,as.character(unclass(Sys.time())),sep="_")
addWorksheet(wb, st)
writeData(x = Grocery_List_Results$thedata,
wb = wb,
sheet = st)
saveWorkbook(wb, "wb.xlsx", overwrite = T)
savd <<- Grocery_List_Results$thedata
shinyalert :: shinyalert(title = "Saved!", type = "success")
})
observeEvent(input$reset, {
dfr(savd)
print(dfr)
shinyalert::shinyalert(title = "Reset to saved data!", type = "info")
})
}
### module end
ui <- fluidPage(
tabsetPanel(
id = "tabs",
# results_1_UI(id = "test1"),
results_2_UI(id = "test2",nam="groc"),
results_3_UI(id = "test3",nam="groc2")
)
)
server <- function(input, output, session) {
df= data.frame(
Buy = c('Tea', 'Biscuits', 'Apples',"Tea","Apples"),
Quantity = c(7, 2, 5,9,44),
stringsAsFactors = FALSE
)
file = "AICs.xlsx"
wb <- loadWorkbook(file)
callModule(
module = results,
id = "test2",
nam="groc",df=df,taby="groc",wb=wb
)
callModule(
module = results,
id = "test3",
nam="groc2",df=df,taby="groc2",wb=wb
)
}
shinyApp(ui = ui, server = server)
Fingers crossed, it is OK!
I have the following Shiny Application:
library(shiny)
library(shinyjs)
library(shinydashboard)
UI <- fluidPage(
actionButton("get_tweets", "Fetch tweets"),
numericInput("tweet_amount", "Set the amount of Tweets", 10, min = 10, max = 1000),
selectInput("tweet_name", "Select the tweeter", selected = NULL, choices = c("#RealDonaldTrump")),
#Set hidden buttons
hidden(
div(id="status_update",
verbatimTextOutput("status")
)
),
hidden(
div(id="tweet_fetcher",
verbatimTextOutput("status2")
)
)
)
Server <- function(input, output){
list = c(1,2,3)
get_connected <- reactive({
for(i in 1:length(list)){
Sys.sleep(2)
}
})
observeEvent(input$get_tweets, {
get_connected()
toggle("status_update")
output$status <- renderText({"You're now connected to the API"})
toggle("tweet_fetcher")
output$status2 <- renderText("Test")
})
}
shinyApp(ui = UI, server = Server)
Thing is that now I works. However, ideally I would like to make sure a button appears. Therefore I want to change:
output$status2 <- renderText("Test")
and this
verbatimTextOutput("status2") #actionButton("status2", "a_button")
This does not work. Any tips on what I should use if I want JS to let a button appear?
If i understand the question correctly you want to interchange
verbatimTextOutput("status2") with actionButton("status2", "a_button").
Then you should use renderUI():
Server side: output$status2 <- renderUI(actionButton("status2",
"a_button"))
UI side: uiOutput("status2")
Full app would read:
library(shiny)
library(shinyjs)
library(shinydashboard)
UI <- fluidPage(
actionButton("get_tweets", "Fetch tweets"),
numericInput("tweet_amount", "Set the amount of Tweets", 10, min = 10, max = 1000),
selectInput("tweet_name", "Select the tweeter", selected = NULL, choices = c("#RealDonaldTrump")),
#Set hidden buttons
hidden(
div(id="status_update",
verbatimTextOutput("status")
)
),
hidden(
div(id="tweet_fetcher",
uiOutput("status2")
)
)
)
Server <- function(input, output){
list = c(1,2,3)
get_connected <- reactive({
for(i in 1:length(list)){
Sys.sleep(2)
}
})
observeEvent(input$get_tweets, {
get_connected()
toggle("status_update")
output$status <- renderText({"You're now connected to the API"})
toggle("tweet_fetcher")
output$status2 <- renderUI(actionButton("status2", "a_button"))
})
}
shinyApp(ui = UI, server = Server)
I want to place a help text for check-box label as a tooltip.
In the following example I use the shinyBS package - but I only get it to work for the title of the checkbox input group.
Any ideas how it could work after the "Lernerfolg" or "Enthusiasmus" labels?
library(shiny)
library(shinyBS)
server <- function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
output$rendered <- renderUI({
checkboxGroupInput("qualdim", tags$span("Auswahl der Qualitätsdimension",
tipify(bsButton("pB2", "?", style = "inverse", size = "extra-small"),
"Here, I can place some help")),
c("Lernerfolg" = "Lernerfolg" ,
"Enthusiasmus" = "Enthusiasmus"
),
selected = c("Lernerfolg"))
})
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100),
uiOutput("rendered")
),
mainPanel(plotOutput("distPlot"))
)
)
shinyApp(ui = ui, server = server)
Sadly, this is one of these moments, where shiny hides most of the construction, which makes it hard to get what you want into the right places.
But like most of the time, some JavaScript will do the trick. I wrote you a function that inserts the bsButton in the right place and calls a shinyBS function to insert the tooltip. (I mainly reconstructed what tipify and bdButton would have done.) With the function you can modifify your tooltip easily without further knowledge about JavaScript.
If you'd like to know more of the details, just ask in comments.
Note: When you refer to the checkbox, use the value of it (the value that is sent to input$qualdim)
library(shiny)
library(shinyBS)
server <- function(input, output) {
makeCheckboxTooltip <- function(checkboxValue, buttonLabel, Tooltip){
script <- tags$script(HTML(paste0("
$(document).ready(function() {
var inputElements = document.getElementsByTagName('input');
for(var i = 0; i < inputElements.length; i++){
var input = inputElements[i];
if(input.getAttribute('value') == '", checkboxValue, "'){
var buttonID = 'button_' + Math.floor(Math.random()*1000);
var button = document.createElement('button');
button.setAttribute('id', buttonID);
button.setAttribute('type', 'button');
button.setAttribute('class', 'btn action-button btn-inverse btn-xs');
button.appendChild(document.createTextNode('", buttonLabel, "'));
input.parentElement.parentElement.appendChild(button);
shinyBS.addTooltip(buttonID, \"tooltip\", {\"placement\": \"bottom\", \"trigger\": \"hover\", \"title\": \"", Tooltip, "\"})
};
}
});
")))
htmltools::attachDependencies(script, shinyBS:::shinyBSDep)
}
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
output$rendered <- renderUI({
list(
checkboxGroupInput("qualdim", tags$span("Auswahl der Qualitätsdimension",
tipify(bsButton("pB2", "?", style = "inverse", size = "extra-small"), "Here, I can place some help")),
choices = c("Lernerfolg" = "Lernerfolg", "Enthusiasmus" = "Enthusiasmus"),
selected = c("Lernerfolg")),
makeCheckboxTooltip(checkboxValue = "Lernerfolg", buttonLabel = "?", Tooltip = "Look! I can produce a tooltip!")
)
})
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100),
uiOutput("rendered")
),
mainPanel(plotOutput("distPlot"))
)
)
shinyApp(ui = ui, server = server)
Edit:
Added the ShinyBS Dependencies such that the JavaScript API for shinyBS is loaded into the WebSite. Before, this was (more or less accidentally) happening because of the other call to bsButton.
Edit Nr.2: Much more In-Shiny
So this JavaScript thing is quite nice, but is kinda prone to errors and demands the developer to have some additional language skills.
Here, I present another answer, inspired by #CharlFrancoisMarais , that works only from within R and makes things more integrated than before.
Main things are: An extension function to the checkboxGrouInput that allows for adding any element to each of the Checkbox elements. There, one can freely place the bsButton and tooltips, like you would in normal markup, with all function arguments supported.
Second, an extension to the bsButton to place it right. This is more of a custom thing only for #CharlFrancoisMarais request.
I'd suggest you read the Shiny-element manipulation carefully, because this offers so much customization on R level. I'm kinda exited.
Full Code below:
library(shiny)
library(shinyBS)
extendedCheckboxGroup <- function(..., extensions = list()) {
cbg <- checkboxGroupInput(...)
nExtensions <- length(extensions)
nChoices <- length(cbg$children[[2]]$children[[1]])
if (nExtensions > 0 && nChoices > 0) {
lapply(1:min(nExtensions, nChoices), function(i) {
# For each Extension, add the element as a child (to one of the checkboxes)
cbg$children[[2]]$children[[1]][[i]]$children[[2]] <<- extensions[[i]]
})
}
cbg
}
bsButtonRight <- function(...) {
btn <- bsButton(...)
# Directly inject the style into the shiny element.
btn$attribs$style <- "float: right;"
btn
}
server <- function(input, output) {
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
output$rendered <- renderUI({
extendedCheckboxGroup("qualdim", label = "Checkbox", choiceNames = c("cb1", "cb2"), choiceValues = c("check1", "check2"), selected = c("check2"),
extensions = list(
tipify(bsButtonRight("pB1", "?", style = "inverse", size = "extra-small"),
"Here, I can place some help"),
tipify(bsButtonRight("pB2", "?", style = "inverse", size = "extra-small"),
"Here, I can place some other help")
))
})
})
}
ui <- fluidPage(
shinyjs::useShinyjs(),
tags$head(HTML("<script type='text/javascript' src='sbs/shinyBS.js'></script>")),
# useShinyBS
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100),
uiOutput("rendered")
),
mainPanel(plotOutput("distPlot"))
)
)
shinyApp(ui = ui, server = server)
Here is slight change - to add tooltips only to the checkboxes.
library(shiny)
library(shinyBS)
server <- function(input, output) {
makeCheckboxTooltip <- function(checkboxValue, buttonLabel, buttonId, Tooltip){
tags$script(HTML(paste0("
$(document).ready(function() {
var inputElements = document.getElementsByTagName('input');
for(var i = 0; i < inputElements.length; i++) {
var input = inputElements[i];
if(input.getAttribute('value') == '", checkboxValue, "' && input.getAttribute('value') != 'null') {
var button = document.createElement('button');
button.setAttribute('id', '", buttonId, "');
button.setAttribute('type', 'button');
button.setAttribute('class', 'btn action-button btn-inverse btn-xs');
button.style.float = 'right';
button.appendChild(document.createTextNode('", buttonLabel, "'));
input.parentElement.parentElement.appendChild(button);
shinyBS.addTooltip('", buttonId, "', \"tooltip\", {\"placement\": \"right\", \"trigger\": \"click\", \"title\": \"", Tooltip, "\"})
};
}
});
")))
}
output$distPlot <- renderPlot({
hist(rnorm(input$obs), col = 'darkgray', border = 'white')
output$rendered <- renderUI({
checkboxGroupInput("qualdim",
label = "Checkbox",
choiceNames = c("cb1", "cb2"),
choiceValues = c("check1", "check2"),
selected = c("check2"))
})
output$tooltips <- renderUI({
list(
makeCheckboxTooltip(checkboxValue = "check1", buttonLabel = "?", buttonId = "btn1", Tooltip = "tt1!"),
makeCheckboxTooltip(checkboxValue = "check2", buttonLabel = "?", buttonId = "btn2", Tooltip = "tt2!")
)
})
})
}
ui <- fluidPage(
shinyjs::useShinyjs(),
tags$head(HTML("<script type='text/javascript' src='sbs/shinyBS.js'></script>")),
# useShinyBS
sidebarLayout(
sidebarPanel(
sliderInput("obs", "Number of observations:", min = 10, max = 500, value = 100),
uiOutput("rendered"),
uiOutput("tooltips")
),
mainPanel(plotOutput("distPlot"))
)
)
shinyApp(ui = ui, server = server)
I've got a dropdown selector and a slider scale. I want to render a plot with the drop down selector being the source of data. - I've got this part working
I simply want the slider's max value to change based on which dataset is selected.
Any suggestions?
server.R
library(shiny)
shinyServer(function(input, output) {
source("profile_plot.R")
load("test.Rdata")
output$distPlot <- renderPlot({
if(input$selection == "raw") {
plot_data <- as.matrix(obatch[1:input$probes,1:36])
} else if(input$selection == "normalised") {
plot_data <- as.matrix(eset.spike[1:input$probes,1:36])
}
plot_profile(plot_data, treatments = treatment, sep = TRUE)
})
})
ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("Profile Plot"),
sidebarLayout(
sidebarPanel(width=3,
selectInput("selection", "Choose a dataset:",
choices=c('raw', 'normalised')),
hr(),
sliderInput("probes",
"Number of probes:",
min = 2,
max = 3540,
value = 10)
),
mainPanel(
plotOutput("distPlot")
)
)
))
As #Edik noted the best way to do this would be to use an update.. type function. It looks like updateSliderInput doesnt allow control of the range so you can try using renderUI on the server side:
library(shiny)
runApp(list(
ui = bootstrapPage(
numericInput('n', 'Maximum of slider', 100),
uiOutput("slider"),
textOutput("test")
),
server = function(input, output) {
output$slider <- renderUI({
sliderInput("myslider", "Slider text", 1,
max(input$n, isolate(input$myslider)), 21)
})
output$test <- renderText({input$myslider})
}
))
Hopefully this post will help someone learning Shiny:
The information in the answers is useful conceptually and mechanically, but doesn't help the overall question.
So the most useful feature I found in the UI API is conditionalPanel() here
This means I could create a slider function for each dataset loaded and get the max value by loading in the data initially in global.R. For those that don't know, objects loaded into global.R can be referenced from ui.R.
global.R - Loads in a ggplo2 method and test data objects (eset.spike & obatch)
source("profile_plot.R")
load("test.Rdata")
server.R -
library(shiny)
library(shinyIncubator)
shinyServer(function(input, output) {
values <- reactiveValues()
datasetInput <- reactive({
switch(input$dataset,
"Raw Data" = obatch,
"Normalised Data - Pre QC" = eset.spike)
})
sepInput <- reactive({
switch(input$sep,
"Yes" = TRUE,
"No" = FALSE)
})
rangeInput <- reactive({
df <- datasetInput()
values$range <- length(df[,1])
if(input$unit == "Percentile") {
values$first <- ceiling((values$range/100) * input$percentile[1])
values$last <- ceiling((values$range/100) * input$percentile[2])
} else {
values$first <- 1
values$last <- input$probes
}
})
plotInput <- reactive({
df <- datasetInput()
enable <- sepInput()
rangeInput()
p <- plot_profile(df[values$first:values$last,],
treatments=treatment,
sep=enable)
})
output$plot <- renderPlot({
print(plotInput())
})
output$downloadData <- downloadHandler(
filename = function() { paste(input$dataset, '_Data.csv', sep='') },
content = function(file) {
write.csv(datasetInput(), file)
}
)
output$downloadRangeData <- downloadHandler(
filename = function() { paste(input$dataset, '_', values$first, '_', values$last, '_Range.csv', sep='') },
content = function(file) {
write.csv(datasetInput()[values$first:values$last,], file)
}
)
output$downloadPlot <- downloadHandler(
filename = function() { paste(input$dataset, '_ProfilePlot.png', sep='') },
content = function(file) {
png(file)
print(plotInput())
dev.off()
}
)
})
ui.R
library(shiny)
library(shinyIncubator)
shinyUI(pageWithSidebar(
headerPanel('Profile Plot'),
sidebarPanel(
selectInput("dataset", "Choose a dataset:",
choices = c("Raw Data", "Normalised Data - Pre QC")),
selectInput("sep", "Separate by Treatment?:",
choices = c("Yes", "No")),
selectInput("unit", "Unit:",
choices = c("Percentile", "Absolute")),
wellPanel(
conditionalPanel(
condition = "input.unit == 'Percentile'",
sliderInput("percentile",
label = "Percentile Range:",
min = 1, max = 100, value = c(1, 5))
),
conditionalPanel(
condition = "input.unit == 'Absolute'",
conditionalPanel(
condition = "input.dataset == 'Normalised Data - Pre QC'",
sliderInput("probes",
"Probes:",
min = 1,
max = length(eset.spike[,1]),
value = 30)
),
conditionalPanel(
condition = "input.dataset == 'Raw Data'",
sliderInput("probes",
"Probes:",
min = 1,
max = length(obatch[,1]),
value = 30)
)
)
)
),
mainPanel(
plotOutput('plot'),
wellPanel(
downloadButton('downloadData', 'Download Data Set'),
downloadButton('downloadRangeData', 'Download Current Range'),
downloadButton('downloadPlot', 'Download Plot')
)
)
))
I think you're looking for the updateSliderInput function that allows you to programmatically update a shiny input:
http://shiny.rstudio.com/reference/shiny/latest/updateSliderInput.html. There are similar functions for other inputs as well.
observe({
x.dataset.selection = input$selection
if (x.dataset.selection == "raw") {
x.num.rows = nrow(obatch)
} else {
x.num.rows = nrow(eset.spike)
}
# Edit: Turns out updateSliderInput can't do this,
# but using a numericInput with
# updateNumericInput should do the trick.
updateSliderInput(session, "probes",
label = paste("Slider label", x.dataset.selection),
value = c(1,x.num.rows))
})
Another alternative can be applying a renderUI approach like it is described in one of the shiny gallery examples:
http://shiny.rstudio.com/gallery/dynamic-ui.html