Class Error When Trying To Pass Radio Button Values to Server - html

I have simplified my example below from the code I am currently working with. I am trying to pass values that a user chooses from a set of radio buttons, to a total score that is conducted. My code was working fine, but now I am getting the following error:
Warning: Error in as.character: cannot coerce type 'closure' to vector of type 'character'
Stack trace (innermost first):
1: runApp
Error : cannot coerce type 'closure' to vector of type 'character'
It sounds like this is a syntax issue, but I am drawing a blank trying to figure this out.
UI.R
ui <- fluidPage(
#title header
titlePanel("This is My Form"),
fluidRow(
column(6,
h3("BUTTON"),
radioButtons("Button1","My First Button", choices = c("Yes" = "y","No" = "n","N/a" = "na"), selected = "na", inline = T),
br(),
h3("BUTTON 2 AND 3"),
radioButtons("Button2","My Second Button", choices = c("Yes" = "y","No" = "n","N/a" = "na"), selected = "na", inline = T),
br(),
radioButtons("Button3","My Third Button",
choices = c("Yes" = "y","No" = "n","N/a" = "na"), selected = "na", inline = T),
br(),
br()
),
column(6,
h3("BUTTON 4"),
radioButtons("Button4","My Fourth Button",
choices = c("Yes" = "y","No" = "n","N/a" = "na"), selected = "na", inline = T)
)
),
actionButton(inputId = "Submit", label = "Calculate"),
(br),
mainPanel(
h1(textOutput('totals'), align = "center")
)
)
SERVER.R
server <- function(input,output,session){
button1 <- reactive({ ifelse(input$Button1 == "y", 50, ifelse(input$Button1 == "n", 25, 0)) })
button2 <- reactive({ ifelse(input$Button2 == "y", 50, ifelse(input$Button2 == "n", 25, 0)) })
button3 <- reactive({ ifelse(input$Button3 == "y", 50, ifelse(input$Button3 == "n", 25, 0)) })
button4 <- reactive({ ifelse(input$Button4 == "y", 50, ifelse(input$Button4 == "n", 25, 0)) })
output$totals <- renderText({
if (input$Submit == 0)
return(NULL)
isolate({
total <- as.numeric(Button1())+as.numeric(Button2())+as.numeric(Button3())+as.numeric(Button4())
if (is.na(total)){
print("Make Selections and Click Submit")
} else
print(total)
})
})
}
GLOBAL.R
library(shiny)
library(rsconnect)

You indeed have a typo in your UI, (br) -> br()
actionButton(inputId = "Submit", label = "Calculate"),
(br),
mainPanel(
h1(textOutput('totals'), align = "center")
)
Should be
actionButton(inputId = "Submit", label = "Calculate"),
br(),
mainPanel(
h1(textOutput('totals'), align = "center")
)

Related

Render vector as comma separated text in shiny app using htmlOutput

I want to use htmlOutput to render text in shiny app.
App works if I have just one object selected in the select input !
As soon as input$var has more than one object the result is not as I expected
require(shiny)
runApp(list(ui = pageWithSidebar(
headerPanel("Test"),
sidebarPanel(
selectInput("var",
label = "Choose a variable to display",
choices = c("Text01", "Text02",
"Text03", "Text04"),multiple = TRUE,
selected = "Text01"),
sliderInput("range",
label = "Range of interest:",
min = 0, max = 100, value = c(0, 100))
),
mainPanel(htmlOutput("text"))
),
server = function(input, output) {
output$text <- renderUI({
str1 <- paste("You have selected", input$var)
str2 <- paste("You have chosen a range that goes from",
input$range[1], "to", input$range[2])
HTML(paste(str1, str2, sep = '<br/>'))
})
}
)
)
How do I modify the code to hav output like :
You have selected Text01,Text02
You have chosen a range that goes from 0 to 100.
I'd recommend using the base R function toString() instead of a second paste:
library(shiny)
runApp(list(
ui = pageWithSidebar(
headerPanel("Test"),
sidebarPanel(
selectInput(
"var",
label = "Choose a variable to display",
choices = c("Text01", "Text02",
"Text03", "Text04"),
multiple = TRUE,
selected = "Text01"
),
sliderInput(
"range",
label = "Range of interest:",
min = 0,
max = 100,
value = c(0, 100)
)
),
mainPanel(htmlOutput("text"))
),
server = function(input, output) {
output$text <- renderUI({
str1 <- paste("You have selected", toString(input$var))
str2 <- sprintf("You have chosen a range that goes from %s to %s", input$range[1], input$range[2])
HTML(paste(str1, str2, sep = '<br/>'))
})
}
))
Just replace the line
str1 <- paste("You have selected", input$var)
with
str1 <- paste("You have selected", paste(input$var, collapse = ", "))
The problem is that paste() returns a vector of strings when input$var has more than 1 element. With collapse you reduce a string vector input$var to a single value.
library(shiny)
runApp(list(ui = pageWithSidebar(
headerPanel("Test"),
sidebarPanel(
selectInput("var",
label = "Choose a variable to display",
choices = c("Text01", "Text02",
"Text03", "Text04"), multiple = TRUE,
selected = "Text01"),
sliderInput("range",
label = "Range of interest:",
min = 0, max = 100, value = c(0, 100))
),
mainPanel(htmlOutput("text"))
),
server = function(input, output) {
output$text <- renderUI({
str1 <- paste(input$var, collapse = " ")
str2 <- paste("You have chosen a range that goes from",
input$range[1], "to", input$range[2])
tagList(
div("You have selected", str1),
div(str2))
})
}
)
)

Multiplue HTML in R Shiny

I have multiple HTML files, and I would like to create a reactive function that changes according to the user input selections as follow:
library(shiny)
library(shinydashboard)
ui <-
dashboardPage(
dashboardSidebar( sliderTextInput(
inputId = "mySliderText",
label = "Story line",
grid = TRUE,
force_edges = TRUE,
choices = c('1','2')
)
),
dashboardBody(
fluidRow(
column(9,
box(
title = "Operations ",
closable = FALSE,
width = 9,
status = "primary",
solidHeader = FALSE,
collapsible = TRUE,
uiOutput("operations")
)
)
)
)
)
server <- function(input, output,session) {
operations_reactive <- reactive({
if (input$mySliderText ==1)
{
return(includeHTML("trial1.html"))
}
else
{
return(includeHTML("trial2.html"))
}
})
output$operations<-renderUI({operations_reactive()})
}
shinyApp(ui = ui, server = server)
it works but not in a proper way, the operations_reactive does not change when input$mySliderText changes

Result in a separate page in R shiny

I want when I click on the search button show the result on a separate page, not on the same page.
I have tried two codes the first one:
UI:
ui = fluidPage(
theme = shinytheme("cerulean"),
mainPanel(
div(align = "center", style="margin-left:500px",
radioButtons("typeInput", "Extract tweets by: ",list("Hashtag" = "hashtag", "Twitter Username"= "username"),inline=T),
textInput("hashtagInput", "Enter search string","", placeholder = "input search string"),
conditionalPanel(
condition = "input.typeInput == 'username'",
textInput("usernameInput", "Username", placeholder = "input username")),
sliderInput("numberInput", "Select number of tweets",min = 0, max = 3000, value = 100),
br(),
actionButton("goButton", "Search", icon("twitter"),
style="color: #fff; background-color: #337ab7"),
uiOutput("pageStub")
)))
server:
server = function(input, output){
data = eventReactive(input$goButton, {
if (input$typeInput == "hashtag") {
tweetOutput = searchThis(search_string = input$hashtagInput,
number.of.tweets = input$numberInput)}
else if (input$typeInput == "username") {
tweetOutput = userTL(user.name = input$usernameInput,number.of.tweets = input$numberInput)}
else {}
library(twitteR)
df.tweets = data.frame(tweetOutput)
tweetOutput = df.tweets})
uiOutput(
output$pageStub <- renderUI(
fluidPage(
fluidRow(
renderDataTable({data()}, options = list(lengthMenu = c(10, 30, 50), pageLength = 5))))))}
but it shows the result on the same page as shown here
the second code I tried shinyBS library but I think the window is too small
UI:
ui = fluidPage(
theme = shinytheme("cerulean"),
mainPanel(
div(align = "center", style="margin-left:500px",
radioButtons("typeInput", "Extract tweets by: ",list("Hashtag" = "hashtag", "Twitter Username"= "username"),inline=T),
textInput("hashtagInput", "Enter search string","", placeholder = "input search string"),
conditionalPanel(
condition = "input.typeInput == 'username'",
textInput("usernameInput", "Username", placeholder = "input username")),
sliderInput("numberInput", "Select number of tweets",min = 0, max = 3000, value = 100),
br(),
actionButton("goButton", "Search", icon("twitter"),
style="color: #fff; background-color: #337ab7"),
bsModal("modalExample", "Your result", "goButton", size = "large",dataTableOutput("tweetTable"))
)))
server:
server = function(input, output)
{
data = eventReactive(input$goButton, {
if (input$typeInput == "hashtag")
{
tweetOutput = searchThis(search_string = input$hashtagInput,
number.of.tweets = input$numberInput)
}
else if (input$typeInput == "username")
{
tweetOutput = userTL(user.name = input$usernameInput,number.of.tweets = input$numberInput)
}
else {}
library(twitteR)
df.tweets = data.frame(tweetOutput)
tweetOutput = df.tweets
})
output$tweetTable =renderDataTable({data()}, options = list(lengthMenu = c(10, 30, 50), pageLength = 5))
}
as shown here:
and here is the search function that I called:
searchThis = function(search_string,number.of.tweets = 100)
{
search_tweets(search_string,n = number.of.tweets, lang = "en")
}
userTL = function(user.name,number.of.tweets = 100)
{
userTimeline(user.name,n = number.of.tweets)
}
is there any other way to do this?
thank you
If you want to use modals, you can modify the width so it's full-screen with the following line in the UI :
tags$head(tags$style(".modal-dialog{ width:100%; overflow-x: scroll;}"))
# width :100% enables you to choose the width of the modal, it could be 95%,50% ...
# overflow-x:scroll displays a horizontal scrollbar if the content is too large for the modal
You UI would be
ui = fluidPage(
theme = shinytheme("cerulean"),
mainPanel(
tags$head(tags$style(".modal-dialog{ width:100%; overflow-x: scroll;}")),
div(align = "center", style="margin-left:500px",
radioButtons("typeInput", "Extract tweets by: ",list("Hashtag" = "hashtag", "Twitter Username"= "username"),inline=T),
textInput("hashtagInput", "Enter search string","", placeholder = "input search string"),
conditionalPanel(
condition = "input.typeInput == 'username'",
textInput("usernameInput", "Username", placeholder = "input username")),
sliderInput("numberInput", "Select number of tweets",min = 0, max = 3000, value = 100),
br(),
actionButton("goButton", "Search", icon("twitter"),
style="color: #fff; background-color: #337ab7"),
bsModal("modalExample", "Your result", "goButton", size = "large",dataTableOutput("tweetTable"))
)))

R/Shiny : RenderUI in a loop to generate multiple objects

After the success of the dynamic box in shiny here : R/Shiny : Color of boxes depend on select I need you to use these boxes but in a loop.
Example :
I have an input file which give this :
BoxA
BoxB
BoxC
I want in the renderUI loop these values as a variable to generate dynamically a Box A, B and C. (if I have 4 value, i will have 4 boxes etC.)
Here is my actually code:
for (i in 1:nrow(QRSList))
{
get(QRSOutputS[i]) <- renderUI({
column(4,
box(title = h3(QRSList[1], style = "display:inline; font-weight:bold"),
selectInput("s010102i", label = NULL,
choices = list("Non commencé" = "danger", "En cours" = "warning", "Terminé" = "success"),
selected = 1) ,width = 12, background = "blue", status = get(QRSIntputS[i])))
})
column(4,
observeEvent(input$s010102i,{
get(QRSOutputS[i]) <- renderUI({
box(title = h3(QRSList[1], style = "display:inline; font-weight:bold"),
selectInput("s010102i", label = NULL,
choices = list("Not good" = "danger", "average" = "warning", "good" = "success"),
selected = get(QRSIntputS[i])) ,width = 12, background = "blue",status = get(QRSIntputS[i]))
})
The aim is to replace these box names to a variable like input$s010102 for example. But get and assign function does not exist.
Any idea ?
Thanks a lot
Here is an example how to generate boxes dynamically
library(shinydashboard)
library(shiny)
QRSList <- c("Box1","Box2","Box3","Box4","Box5")
ui <- dashboardPage(
dashboardHeader(title = "render Boxes"),
dashboardSidebar(
sidebarMenu(
menuItem("Test", tabName = "Test")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "Test",
fluidRow(
tabPanel("Boxes",uiOutput("myboxes"))
)
)
)
)
)
server <- function(input, output) {
v <- list()
for (i in 1:length(QRSList)){
v[[i]] <- box(width = 3, background = "blue",
title = h3(QRSList[i], style = "display:inline; font-weight:bold"),
selectInput(paste0("slider",i), label = NULL,choices = list("Not good" = "danger", "average" = "warning", "good" = "success"))
)
}
output$myboxes <- renderUI(v)
}
shinyApp(ui = ui, server = server)

Coloring the checkboxGroupInput choices

In my Shiny UI I have
ui <- checkboxGroupInput("my_cbgi", "Choose Something", c("A", "B", "C", "D"))
And I would like it so that the choices (the text) A and B are colored red, but C and D are not. I tried HTML but then in the UI weird boxes like "attribs" and "children" showed up.
Thanks in advance
Since shiny_1.0.1, checkboxGroupInput have a choiceNames and choiceValues arguments for passing arbitrary UI to display to the user, check this example :
library("shiny")
ui <- fluidPage(
checkboxGroupInput(
inputId = "my_cbgi",
label = "Choose Something",
choiceNames = list(
tags$span("A", style = "color: red;"),
tags$span("B", style = "color: red;"),
tags$span("C", style = "color: blue;"),
tags$span("D", style = "font-weight: bold;")
),
choiceValues = c("A", "B", "C", "D")
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
Great Victorp, I improved your answer adding a varying behaviour to it.
library("shiny")
my.options <- c('A', 'B', 'C')
my.colors <- c('red', 'green', 'blue')
my.fun <- function() {
res <- list()
for (o in my.options) {
res[[length(res)+1]] <- tags$span(o,
style = paste0('color: ', my.colors[which(my.options == o)],';'))
}
res
}
ui <- fluidPage(
checkboxGroupInput(inputId = "myId", label = "Options",
choiceNames = my.fun(),
choiceValues = my.colors
)
)
server <- function(input, output) {}
shinyApp(ui = ui, server = server)