R Shiny Pass a vector as radioButtons choices argument - r

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.

Related

Use information about selectInput within a renderUI

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))
})
})

call R script from Shiny App

I developed a shiny app which displays some dynamic charts. These charts are generated at execution time according to the value of some buttons. This shiny app gets the data from a raw csv which is previously treated and transformed. I got a Rscript apart from the shiny app to do all those "transformations" of the raw data. What I would like to do is to call this Rscript from the shiny app in order to be executed when the shiny app is launched.
I have already checked these links but it didn't help at all: How can I connect R Script with Shiny app in R? and this one using Source() in Shiny. I checked the Rstudio documentation too: http://shiny.rstudio.com/tutorial/lesson5/.
I think it should be something like this, being procesadoDatos.R the RScript. i just want the source command to be executed at the beginning in order to load the data as the shiny app is starting:
source("procesadoDatos.R",local = TRUE)
shinyServer(function(input, output,session) {
(renderplots, reactives elements and so on)}
The Rscript is the shiny project path as the server.R and UI.R files. I also tried including the path but it didn't work either.
Another thing I tried was to create a function which makes all the transformations and then call it from server.R file after sourcing it:
source("procesadoDatos.R",local = TRUE)
generate_data(ticketsByService_report10.csv)
Being generate_data this function defined in the RScript:
generate_data <- function(csv_file) {
(all those transformation, data frame an so on)}
In all cases I got the same error saying that the data frames which are generated in the RScript aren't found.
Does anyone know what is wrong? Thanks in adavance
Scoping in Shiny
All this largely depends on where exactly you call source(). If you need the data to be found from within both the UI and the server function, you put source() outside the app.
If you place source() inside the server function, the UI won't be able to find any object created by the script. If you put this inside a render function, the objects are only visible inside that render function. See also Scoping rules for Shiny
Note that if you have separate server.R and ui.R files and you want the UI to find the objects created by the script, you should add a global.R file to your app directory. The source() command then goes in the global.R file.
A small example:
source('testScript.R')
shinyApp(
fluidPage(
selectInput("cols", "pick columns",
choices = names(x)),
dataTableOutput("what")),
function(input, output, session){
output$what <- renderDataTable(x)
}
)
and testScript.R contains one line:
x <- iris
The key here is:
the script actually has to create these objects
the script should be sourced in the correct spot.
So if you can do the following:
shinyApp(
fluidPage(
selectInput("cols", "pick columns",
choices = names(x)),
dataTableOutput("what")),
function(input, output, session){
source('testScript.R', local = TRUE)
output$what <- renderDataTable(x)
}
)
you get an error about not being able to find x. That's normal, because x is now only defined inside the environment of the server function.
You still can do this though:
shinyApp(
fluidPage(
dataTableOutput("what")),
function(input, output, session){
source('R/testScript.R', local = TRUE)
output$what <- renderDataTable(x)
}
)
Note how x is only needed inside the server function, not inside the UI.
Using functions
For functions, the same thing applies. You put the function definition in a script and source it like before. A function is nothing else but an object, so the script essentially creates a function object that then can be found using the exact same scoping rules.
Keep in mind though that this function should return something if you want to use the result of the function. So put this trivial example in testScript.R:
myfun <- function(x){
tmp <- iris[x]
return(tmp)
}
And now you can do the following:
source('testScript.R', local = TRUE)
shinyApp(
fluidPage(
selectInput("cols", "pick columns",
choices = names(myfun())),
dataTableOutput("what")),
function(input, output, session){
output$what <- renderDataTable(myfun(input$cols))
}
)
This doesn't work any longer if you put the source() inside the server function. The UI side won't be able to see myfun() any more.
rm(list = ls())
shinyApp(
fluidPage(
selectInput("cols", "pick columns",
choices = names(myfun())),
dataTableOutput("what")),
function(input, output, session){
source('R/testScript.R', local = TRUE)
output$what <- renderDataTable(myfun(input$cols))
}
)
# Error in myfun() : could not find function "myfun"

Is it possible to have a Shiny ConditionalPanel whose condition is a global variable?

My goal is to have a tabsetPanel wrapped in a conditionalPanel whose condition is a global variable being false.
ui.R
mainPanel(
conditionalPanel("searchPage == \"false\"",
tabsetPanel(
tabPanel("Summary",htmlOutput("summary")),
tabPanel("Description", htmlOutput("description"))
))),
global.R
searchPage <- "true"
then in server.R I assign new values to it a few different times, but all like this:
observeEvent(input$openButton,
output$results <- renderUI({
textOutput("")
searchPage <- "false"
}))
No matter what I do, I always get "Uncaught ReferenceError: searchPage is not defined". I've tried changing the global.R to multiple different combinations of using quotes, not using quotes, using <- or <<-, making it this.searchPage, my.searchPage and numerous other things (of course always making server.R and ui.R match too), but haven't had much luck at all.
As mentioned in a comment on the question's post, this is a perfect usecase for the shinyjs toggle()/show()/hide() functions. Whenever you need to conditionally show something where the condition is not a simple javascript expression of an input, it's easy to use these functions instead of a conditionalPanel().
In order to use these functions, you need to have some way to specify the element you want to hide/show (in this case, the mainPanel()). The easist way to do this is to just wrap the entire panel in a div with an id. So define the panel like mainPanel(div(id = "mainpanel", ...)) and voila, there's an id to your panel, and now you can call shinyjs::show("mainpanel") or hide() whenever you want in the server code.
What you are trying to do is not really possible the way you are trying to do it (the server and client are in different environments and don't share variables). You will need to explicitly pass the value from server to client, and there are different approaches to doing that. One way:
library(shiny)
runApp(list(ui = fluidPage(
conditionalPanel(condition='output.bool',
HTML("Hello world")),
actionButton("btn","Press me to toggle")
),
server = function(input, output, session) {
value=TRUE
output$bool <- eventReactive(input$btn,{
value
})
outputOptions(output,"bool",suspendWhenHidden=FALSE)
observeEvent(input$btn,
value <<- !value
)
}))
There are probably better approaches. Hope this helps

obtain another UI element value in ui.R in R shiny

It may be a very simple issue, but I can't seem to get it work.
In my ui.R I have a dropdown whose ID is "product", how do I use the selected value for product in another place in ui.R itself.
I tried input.product, input.product.value etc...none worked
Any help?
To give more information: I have tried the following to get a hyperlink on my web page :
server.R
output$sppath <- renderText({
link1<-paste("http://server2/projects/", input$product, "/collaboration/forms/collaborative%20documents.aspx?&SortField=Modified&SortDir=Desc",sep="")
return(link1) })
ui.R
fluidRow(h6("Sharepoint:", a("Collaboration", href=textOutput("sppath")))),
With above code, the link under "collaboration" is created as
http://shiny-server:8787/p/5620/%3Cdiv%20id=%22sppath%22%20class=%22shiny-text-output%22%3E%3C/div%3E
What am I doing wrong? Why is the sppath not resolving properly?
When I try just textOutput outside of a tag, it shows the full path.
the syntax is input$product, not input.product, and what you want is
renderUI in your server.r which uses input$product, then call uiOutput in ui.r
I'm able find the solution, here it is :
server.R
output$sppath <- renderUI({
link1<- paste("http://server2/projects/",input$product,"/collaboration/forms/collaborative%20documents.aspx?&SortField=Modified&SortDir=Desc",sep="")
h6("Sharepoint:",tags$a( href=link1,"Collaboration"))
})
ui.R
fluidRow(htmlOutput("sppath)),

Shiny - Taking Text input into auxiliary function

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')

Resources