I want to use some information of a selectInput in a renderUi, e.g. the length of selected items (renderUi depends on this number).
Unfortunately I haven't find a solution yet. Below a short simplified example, which should display the length of selected items. I guess there is a problem either with the return type of input or with the encoding of I/O.
Please note: I tried already renderPrint, which is working! But I need the information about the length of selectInput within a renderUi, since I want to create further ui elements based on the selected number.
Ui.R:
library(shiny)
shinyUI(fluidPage(
selectInput("first","first",choices=c("a","b"),multiple=TRUE),
uiOutput("hallo")
))
Server.R:
library(shiny)
shinyServer(function(input, output) {
output$hallo <- renderUI({
print(length(input$first))
})
})
Related
I would like to define a radio button in Shiny which normally I could do for example as:
radioButtons("choose_country", h3("Country"),
choices=c('uganda'='UG','tanzania'='TZ','kenya'='KE'))
Which gives the desired output:
However, I would like the choices part of radioButtons to be read from an
externally defined vector. i.e.
country_assg <- c('uganda'='UG','tanzania'='TZ','kenya'='KE')
I would then like to paste this vector as follows:
radioButtons("choose_country", h3("Country"),
choices=country_assg)
This does not seem to work as it seems not to break up the elements in the country_assg vector as required.
My question is how I can make country_assg to be evaluated as the choice argument inside the
radioButtons command so that I get the desired output.
I would appreciate ideas to tackle the issue.
For me, compiling the following three files does the job (all files in the same folder as always):
ui.R:
source('helpers.R')
shinyUI(fluidPage(
titlePanel("censusVis"),
radioButtons("choose_country", h3("Country"),
choices=c('uganda'='UG','tanzania'='TZ','kenya'='KE')),
radioButtons("choose_country", h3("Country"),
choices=country_assg)
)
)
server.R
library(shiny)
source("helpers.R")
shinyServer(
function(input, output) {
}
)
and helpers.R
country_assg <- c('uganda'='UG','tanzania'='TZ','kenya'='KE')
Hope this helps.
PS: Strictly speaking, you do not need to source the helpers.R in the server portion of this little app, because server.R does not require any of the definitions made in helpers.R.
I am new to shiny, I have been stuck on this for quite a while and the things I tried and read so far held no fruits. I have a dropdown, where the user will choose a Question, then depending on the question, a drop down will be populated with the response numbers. After the user chooses the response number a map will be plotted. I have gone through the dynamic drop down list, that is done. But I cannot get access to the second user input, the response number, so I can select my data for the map accordingly. I feel like this is really simple I don't know why this does not work. I am getting this error:
Error in .getReactiveEnvironment()$currentContext() : Operation not
allowed without an active reactive context. (You tried to do something
that can only be done from inside a reactive expression or observer.)
My code is as follows, I have tentatively put in special cases and later I will expand to a general case with lists.
library(shiny)
runApp(list(
ui = shinyUI(pageWithSidebar(
headerPanel('Dialect Comparison'),
sidebarPanel(
selectInput('Question', 'Choose The Question', c('100. Do you cut or mow the lawn or grass?'='Q100',
'101. Do you pass in homework or hand in homework?'='Q101')),
uiOutput('C')
),
mainPanel(
plotOutput('plot')
)
)
),
server = function(input, output){
output$C = renderUI({
ques = input$Question
selectInput('Choice', 'Choose The Response', seq(0,max(ling_data[,ques])))
})
##########
#The Data#
##########
#text = renderPrint({'uhu'})
#print(text()) #THIS WORKS
choice_number = renderPrint({input$Choice}) #http://shiny.rstudio.com/gallery/dynamic-ui.html
print(choice_number()) #it fails here
...
})
}
))
Reactive variables, including inputs, can be accessed only in a reactive scope created using one of the following:
shiny::reactive, shiny::eventReactive
shiny::observe, shiny::observeEvent
shiny::render*
or inside shiny::isolate block.
For actions like logging you probably want observe block:
observe({print(choice_number())})
I am trying to display from 1 to 5 tabPanels in a navbarPage in Shiny.
I have 5 plots my code generates, but I'd like a user to be able to select how many they want to have access to -- to be displayed one plot in each tabPanel, naturally.
I've got an external configuration file (config.txt) that via source('config.txt'), I have access to a number_of_pages variable.
For example, number_of_tabPages <- 3
How would I set this up in UI.R?
The number of tabPanels can't be hardcoded at all in the UI file, since it depends on a value that is specified by a user, not using a control.
I've searched around and found that most of the approaches to this kind of thing
involve using uiOutput and renderUI functions, such as this similar problem, but I don't want any special control in the UI to do any selecting.
This is where things get tricky, when we are building the UI depending on values that may change. My brain is trying to wrap itself around the best method for doing this type of thing -- I feel like it isn't exactly in line with how Shiny wants to communicate with itself using a UI <--> server environment.
Any advice is greatly appreciated.
My UI.R is easy to create when it isn't dynamic:
fluidRow(
column(12,
"",
navbarPage("",tabPanel("First Tab",
plotOutput("plot1")),
tabPanel("Second Tab",
plotOutput("plot2")),
tabPanel("Third Tab",
plotOutput("plot3")),
tabPanel("Fourth Tab",
plotOutput("plot4")),
tabPanel("Fifth Tab",
plotOutput("plot5"))
)
)
)
)
Thanks!
If you don't need the user to change the number of tabPanel interactively, but just load varying numbers of them when the app is started you can use the do.call function in the navBarPage:
library(dplyr)
library(shiny)
library(ggvis)
#number of tabs needed
number_of_tabPages <- 10
#make a list of all the arguments you want to pass to the navbarPage function
tabs<-list()
#first element will be the title, empty in your example
tabs[[1]]=""
#add all the tabPanels to the list
for (i in 2:(number_of_tabPages+1)){
tabs[[i]]=tabPanel(paste0("Tab",i-1),plotOutput(paste0("plot",i-1)))
}
#do.call will call the navbarPage function with the arguments in the tabs list
shinyUI(fluidRow(
column(12,
"",
do.call(navbarPage,tabs)
)
)
)
Note: After coming up with the answer I reworded the question to make if clearer.
Sometimes in a shiny app. I want to make use of a value selected by the user for a widget, as well as the previous value selected for that same widget. This could apply to reactive values derived from user input, where I want the old and the new value.
The problem is that if I try to save the value of a widget, then the variable containing that value has to be reactive or it will not update every time the widget changes. But, if I save the the value in a reactive context it will always give me the current value, not the previous one.
How can I save the previous value of a widget, but still have it update every time the user changes the widget?
Is there a way that does not require the use of an actionButton every time the user changes things? Avoiding an actionButton can be desirable with adding one is otherwise unnecessary and creates excess clicking for the user.
Seeing as the session flush event method seems to be broken for this purpose, here is an alternative way to do it using an observeEvent construct and a reactive variable.
library(shiny)
ui <- fluidPage(
h1("Memory"),
sidebarLayout(
sidebarPanel(
numericInput("val", "Next Value", 10)
),
mainPanel(
verbatimTextOutput("curval"),
verbatimTextOutput("lstval")
)
)
)
server <- function(input,output,session) {
rv <- reactiveValues(lstval=0,curval=0)
observeEvent(input$val, {rv$lstval <- rv$curval; rv$curval <- input$val})
curre <- reactive({req(input$val); input$val; rv$curval})
lstre <- reactive({req(input$val); input$val; rv$lstval})
output$curval <- renderPrint({sprintf("cur:%d",curre())})
output$lstval <- renderPrint({sprintf("lst:%d",lstre())})
}
options(shiny.reactlog = TRUE)
shinyApp(ui, server)
Yielding:
Update This answer was posted before the advent of the reactiveValues/observeEvent model in shiny. I think that #MikeWise 's answer is the better way to do this.
After some playing around this is what I came up with. The ui.r is nothing special
ui.r
library(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectizeInput(inputId="XX", label="Choose a letter",choices=letters[1:5])
),
mainPanel(
textOutput("Current"),
textOutput("old")
)
)
))
"Current" will display the current selection and "old" displays the previous selection.
In the server.r I made use of three key functions: reactiveValues, isolate and session$onFlush.
server.r
library(shiny)
server <- function(input, output,session) {
Values<-reactiveValues(old="Start")
session$onFlush(once=FALSE, function(){
isolate({ Values$old<-input$XX })
})
output$Current <- renderText({paste("Current:",input$XX)})
output$old <- renderText({ paste("Old:",Values$old) })
}
The server.r works like this.
First, Values$old is created using the reactiveValues function. I gave it the value "Start" to make it clear what was happening on load up.
Then I added a session$onFlush function. Note that I have session as an argument in my server function. This will run every time that shiny flushes the reactive system - such as when the selectizeInput is changed by the user. What is important is that it will run before input$XX gets a new value - so the value has changed at the selectizeInput but not at XX.
Inside the session$onFlush I then assign the outgoing value of XX to Values$old. This is done inside an isolate() as this will prevent any problems with input$XX gets updated with the new values. I can then use input$XX and Values$old in the renderText() functions.
I am new to Shiny and trying to build a more accessible input and output for a function I built. I am giving this to people that don't run R so trying to build something that runs my functions in the background and then spits out the answer.
I am having some trouble getting everything in the way that I want it unfortunately and dealing with a bunch of errors. However, here is my more pointed question:
The actual function that I want to run takes a name (in quotations as "Last,First") and a number.
PredH("Last,First",650)
So I want a shiny application that takes a name input and a number input that then runs this program and then spits back out a data table with my answer. So a couple of questions.
How do I get it in the right form to input into my equation on the server side script, do I need to return it in the function so it can be accessed using a function$table type access? (Right now I am just printing using cat() function in the console for the function but know that may not be usable for this type of application.
I want to return a dataframe that can be gotten at PredH14$table. How do I go about building that shiny?
Here is my code so far:
UI:
library(shiny)
shinyUI(pageWithSidebar(
# Application title
headerPanel("Miles Per Gallon"),
# Sidebar with controls to select the variable to plot against mpg
# and to specify whether outliers should be included
sidebarPanel(
textInput("playername", "Player Name (Last,First):", "Patch,Trevor"),
radioButtons("type", "Type:",
list("Pitcher" = "P",
"Hitter" = "H"
)),
numericInput("PAIP", "PA/IP:", 550),
submitButton("Run Comparables")
),
mainPanel(
textOutput("name")
)
Server:
library(shiny)
shinyServer(function(input, output) {
sliderValues <- reactive({
data.frame(
Name = c("name", "PA"),
Value = c(as.character(playername),
PAIP),
stringsAsFactors=FALSE)
})
name=input[1,2]
PAIP=input[2,2]
testing <- function(name,PAIP){
a=paste(name,PAIP)
return(a) }
output$name=renderText(testing$a)
})
I am not quite sure I understood your question 100% but I clearly see you are wondering how to pass the input of the UI into the server and maybe, the other way back.
In your server code, clearly you are not getting any input from the UI. Basically you have created three input variables in your ui.R:
1. input$playername
2. input$type
3. input$PAIP
And one output:
1. output$name
Just let you know, the function sliderValues <- reactive(..) is called every time there is any input from the input... like people click the dropdown list or people modifies words in the text box.
You can even get started without the submit button just to get started. But the existence of the submit button actually makes everything easier. Create a submit button for an input form. Forms that include a submit button do not automatically update their outputs when inputs change, rather they wait until the user explicitly clicks the submit button.
So you can put your code in a way similar like this:
# server.R
library(shiny)
shinyServer(function(input, output) {
sliderValues <- reactive({
result <- ... input$playername ... input$type ... input$PAIP
return(result)
})
output$name <- renderPlot/renderText (... sliderValues...)
})
# ui.R
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Miles Per Gallon"),
sidebarPanel(
textInput("playername" ... ),
radioButtons("type" ... ),
numericInput("PAIP" ... ),
submitButton("...")
),
mainPanel(
textOutput/plotOutput...("name")
)
))
In the end, check out the shiny example that might be what you want.
library(shiny)
runExample('07_widgets')