Dynamic update of a label withMathJax in Shiny UI - r

I'm using shiny::updateSliderInput to update the label of a slider. I would like the label for the slider to render with the Greek character xi (ξ) and a subscript. The subscript is target of the updateSliderInput call.
I've been successful generating the label without the updateSliderInput call, but correctly using the withMathJax() call for the label update has not worked as well as I would prefer.
A reproducible example of a shiny app for this issue is:
library(shiny)
shinyApp(ui = shinyUI(fluidPage(sliderInput("order", withMathJax("Order, \\(k\\)"), min = 3, max = 7, value = 4, step = 1),
sliderInput("iknots", "iKnots", min = 0, max = 10, value = 5, step = 1),
sliderInput("xi1", withMathJax(), min = 0, max = 10, value = 1, step = 0.1))),
server = shinyServer(function(input, output, clientData, session) {
observe({
k <- as.integer(input$order)
l <- as.integer(input$iknots)
updateSliderInput(session, "xi1", label = paste0("\\(\\xi_{", k + l, "}\\)"))
})
}))
Upon initial loading of the app in browser we have a the desirable label, the ξ9 is correct.
After adjusting either of the first two sliders, the label for the third slider does not render as expected.
I've tried using withMathJax in label argument of updateSliderInput but have had undesirable labels. Changing the updateSliderInput line in the above to
updateSliderInput(session, "xi1", label = withMathJax(paste0("\\(\\xi_{", k + l, "}\\)")))
and setting the sliderInput to have the either label = withMathJax() or label = "" results in the initial label of
and updated label of
How can the subscript on the ξ be correctly updated in the slider label?

You might need to use renderUI and uiOutput to create the last slider otherwise the javascript used to display the MathJax is not called when you update the label.
You could do:
library(shiny)
shinyApp(ui = shinyUI(fluidPage(sliderInput("order", withMathJax("Order, \\(k\\)"), min = 3, max = 7, value = 4, step = 1),
sliderInput("iknots", "iKnots", min = 0, max = 10, value = 5, step = 1),
uiOutput("lastSlider"))),
server = shinyServer(function(input, output, clientData, session) {
output$lastSlider<- renderUI({
k <- as.integer(input$order)
l <- as.integer(input$iknots)
sliderInput("xi1",label = withMathJax(paste0("\\(\\xi_{", k + l, "}\\)")), min = 0, max = 10, step = 0.1,value=input$xi1)
})
}))

Related

Is there a way that you can update noUiSliderInput for two values, when starting them as null?

Intro:
I have a list of 40 variables that each has 2000 entries, I am working in R Shiny in order to try automatically divide the data into 3 bins based the value at 1/3 of the data and 2/3 of the data.
Each variable has a range between -10 and 10.
UI code below:
selectInput("variable","Select your variable",choices = sort(colnames(train))),noUiSliderInput(inputId = "bins", label = "Choose bin width", min = -10, max = 10, value = c(NULL,NULL), orientation = "horizontal", margin = 1, width = 10000, color = "#68228B")
Server code:
ordered_data <- reactive({
sort_test <- c(joined_adw[,input$variable])
sort_test <- as.numeric(unlist(sort_test))
sort_test <- sort(sort_test)
})
eventReactive(
input$variable,{
updateNoUiSliderInput(session = session, inputId = "bins", value = c(ordered_data()[667], test()[1334]))
})
}
I know that there are other ways of doing this, but I need the slider in the report sheet.
Any help would be massively appreciated, as I have been trying to do this for a while, and each time I try it, the slider disappears when I use an update call.

How to feed a value from an output object as an input into another output object?

I'm working on a simulation-based app. I have 2 initial numeric input objects, "max imp count" and "population size". Based on what is fed into these numeric input objects, the app generates 2 more input objects (really as output objects)- "select_proportion" and "select_probability". If the "max imp count" is 3, the app should generate 8 new input objects- 4 which ask for proportion (proportion0, proportion1, proportion2, proportion3), and 4 of which ask for probability0, probability1, probability2 and probability3. I want to feed these proportion and probability values into sample functions that work in the following manner:
1) sample(c(0,input$max_imp, 1), size=input$population, replace=TRUE, prob= these take the proportion values
sample for binary values for all proportion brackets:
2) sample(c(0,1), length(proportion_i), replace=TRUE, prob=these take the probability values)
Ideally, I would like to have this all in a dataframe where I have columns for which proportion bracket a record belongs to and whether they have 0 or 1.
Code:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Simulation"),
dashboardSidebar(
sidebarMenu(
numericInput("max_imp", "max imp count", 0, min = 0, max = 15, step = 1),
numericInput("population", "population size", 1, min = 0, max = 100000, step = 1),
menuItemOutput("menuitem")
)
),
dashboardBody(
uiOutput("select_proportion"),
uiOutput("select_probability")
))
server <- function(input, output) {
output$select_proportion = renderUI(
lapply(0:(input$max_imp), function(i){
numericInput(inputId = "i1", label = paste0("proportion",i), 0, min = 0, max = 1, step = 0.05)}))
output$select_probability = renderUI(
lapply(0:(input$max_imp), function(i){
numericInput(inputId = "i2", label = paste0("probability",i), 0, min = 0, max = 1, step = 0.05)}))
}
# Run the application
shinyApp(ui = ui, server = server)
Your output elements are only UI container which are then filled with the input elements defined in the renderUI functions. You can easily access the values of these input elements as you do it with your other inputs.
The only thing here is that you have to set the IDs of the inputs in a dynamic way e.g. instead of id = "i2" for the second input use id = paste("input", i, "2", sep = "-"). This will create you input$max_imp + 1 different inputs. The values can then be accessed via input$input_1_2.
BR
Sebastian

Shiny save user input to google sheets

I am running a personality survey and am trying to save the data to google sheets.
I started by creating a sheet with a first row of zero and the headers I want. I have code to display the scores of participants in output$vaules. I tried to use that to save to the google sheet but that also did not work.
I am not getting any errors but the data is not being saved to the google sheet I initialized.
library(shiny)
library(googlesheets)
shiny_token <- gs_auth()
saveRDS(shiny_token, "shiny_app_token.rds")
initial_sheet <- data.frame(open1 = 0, open2 = 0, consc1 =
0, consc2 = 0, extra1 = 0, extra2 = 0, agree1 = 0, agree2 =
0, neur1 = 0, neur2 = 0)
gdoc_name <- "big5"
ss <- gs_new(gdoc_name, input=initial_sheet)
sheetkey <- ss$sheet_key
sheetkey <- "xxxx" #actual key would be here
ss <- gs_key(sheetkey)
set.seed(3000)
xseq<-seq(1,7,.01)
densities <-dnorm(xseq, 4,1)
ui
ui <- fluidPage(
table <- "responses",
titlePanel("Personality Traits"),
sidebarLayout(
sidebarPanel(
sliderInput("extra1", "I see myself as someone who is extraverted, enthusiastic.", min = 1, max = 7, value = 1),
sliderInput("agree1", "I see myself as someone who is critical, quarrelsome.",min = 1, max = 7,value = 1),
sliderInput("consc1", "I see myself as someone who is dependable, self-disciplined.",min = 1, max = 7, value = 1),
sliderInput("neur1", "I see myself as someone who is anxious, easily upset.",min = 1, max = 7, value = 1),
sliderInput("open1", "I see myself as someone who is open to new experiences, complex.", min = 1, max = 7, value = 1),
sliderInput("extra2", "I see myself as someone who is reserved, quiet.", min = 1, max = 7, value = 1),
sliderInput("agree2", "I see myself as someone who is sympathetic, warm.", min = 1, max = 7, value = 1),
sliderInput("consc2", "I see myself as someone who is disorganized, careless", min = 1, max = 7, value = 1),
sliderInput("neur2", "I see myself as someone who is calm, emotionally stable.", min = 1, max = 7, value = 1),
sliderInput("open2", "I see myself as someone who is conventional, uncreative.", min = 1, max = 7, value = 1),
actionButton("submit", "Submit")
),
mainPanel(
tableOutput("values")
))
)
server
server <- function(input, output) {
sliderValues <- reactive({
data.frame(Name = c("Openness","Conscientiousness","Extraversion", "Agreeableness", "Neuroticism"),
Value = as.character(c((input$open1 + (8-input$open2))/2 (input$consc1 + (8 - input$consc2))/2, (input$extra1 + (8 - input$extra2))/2,(input$agree2 + (8 - input$agree1))/2,(input$neur1 + (8 - input$neur2))/2)),stringsAsFactors = FALSE)
})
observeEvent(input$submit, {
output$values <- renderTable({
sliderValues()
})
observeEvent(input$save, {
open1 <- input$open1
open2 <- input$open2
consc1 <- input$consc1
consc2 <- input$consc2
extra1 <- input$extra1
extra2 <- input$extra2
agree1 <- input$agree1
agree2 <- input$agree2
neur1 <- input$neur1
neur2 <- input$neur1
gs_add_row(input = output$save)
})
}
run app
shinyApp(ui = ui, server = server)
After making my comment early today, I played with my code and got it to update my google sheet.
In my project, I want to click payment and send the payment date to the paid column (C5) in my datasheet. This needs to be performed as many times as empty cells (Not paid) are there (therefore the 'for' loop).
I count all the rows in my spreadsheet (total_rows) and the number of rows without a date in the paid column (n_rows). These values provided me with the range of empty cells the code needs to update after the action button is activated.
This is added to the UI portion of the app:
actionButton("payments", label = "EXECUTE PAYMENTS")
This to the server:
sheet = function() {gs_title("Title of the googlesheet")}
historic = function(){ sheet() %>% gs_read(ws = "spreadsheet name")}
observeEvent(input$payments, {
total_rows = nrow(historic())
ndata = historic() %>% filter(is.na(paid))
n_rows = nrow(ndata)
if (total_rows == n_rows){n_rows = n_rows+1}
for (i in (total_rows - n_rows + 2) : (total_rows+1)) {
anchor_range = paste("R", i, "C5", sep = "", collapse = NULL)
sheet() %>% gs_edit_cells(ws = "spreadsheet name", input = Sys.Date(), anchor = anchor_range)
}
Hope this works for you.
J

eventReactive, source() and plotting on R Shiny

I am having some trouble with creating plots on eventReactive. I have a source code for inside event reactive, and I am trying to make multiple plots. I am a little unsure how to make multiple plots, so I tried to make one into a plot. However, I am still having trouble with this.
My ui and server are
library(shiny)
library(lpSolve)
ui <- fluidPage(
mainPanel(
tabsetPanel(
tabPanel("Information required for the model",
sliderInput("Reservoirs", label = h3("Total Number of Reservoirs"),
min = 1, max = 25,
value = 10),
sliderInput("Municipalities", label = h3("Total Number of Municipalities Served by the Reservoirs"),
min = 1, max = 150,
value = 15),
sliderInput("Time", label = h3("Total Number of Months for Future Decision"),
min = 0, max = 60,
value = 0)
),
tabPanel("Summary of csv files",
actionButton("Run_Model", "Run Model")),
tabPanel("Results",
plotOutput("plot_ipsita"),
img(outfile)
)
)))
server <- function(input, output) {
running_code<-eventReactive(input$Run_Model, {
source("Source_code.R", local=TRUE)
outfile <- tempfile(fileext = '.png')
png(outfile,width=30,height=nR*3,units = "in",res=200)
par(mfrow=c(ceiling(nR)/2, 2))
for (i in 1:nR){
hist(abcd[i,1,1])
}
dev.off()
plot((colSums(abcd[1,,])),type="l",ylab="Withdrawal [mio m3]",xlab = "months",col=1,lwd=3,lty=1)
abline(h=130, col = 2,lwd=3,lty=3)
abline(h=205, col=3, lwd=3,lty=4)
legend("topleft", c("","All Reservoirs","Import","Failure"), col = c(0,1,2,3),pt.cex=0.5,lty=1:4,lwd=3, cex=0.75,bty="n")
title(paste0("Withdrawals from reservoirs and imports and failure for % initial storage" ), cex.main=1)
})
output$plot_ipsita <- renderPlot({
running_code()
})
}
shinyApp(ui = ui, server = server)
And my source code is
nR<-input$Reservoirs
nM<-input$Municipalities
nT<-input$Time
abcd<-array(data=0, c(nR,nM,nT))
for (i in 1:nR){
abcd[i,,]<-(1+i)*55
}
My actual code is a lot more complicated, so I tried to simplify it to test with this one, and it does not seem happy. Nothing is running. However, if I try to run it as a regular R code, I am able to get all the results.
Please help!!!
The mistake in your code is in your ui where your sliderInput Time has a default value 0. This causes the following loop to fail not assigning any value to array abcd:
for (i in 1:nR){
abcd[i,,]<-(1+i)*55
}
Hence, colSums(abcd[1,,]) dos not have the value due to which it fails.
If you change the sliderInput("Time", label = h3("Total Number of Months for Future Decision"), min = 0, max = 60, value = 0) to sliderInput("Time", label = h3("Total Number of Months for Future Decision"), min = 0, max = 60, value = 2) your code creates a graph as follows:
Hope it helps!

Radio buttons with numerical inputs in conditional panels

I am trying to make a Shiny app to do calculations as in [this pape
There are 3 sorts of calculation,called "calcprior", "calcpval" and "calcFPR".
Which calculation is to be done is chosen by radioButton. Each calculation requires different inputs. The inputs are placed in conditionalPanels. The correct names appear in thec onditionalPanel, but the numerical values aren't passed to the server, e.g. input$pval does not have the value entered in the numericInput in the conditional panel.
In contrast the value of nsamp, needed for all 3 calculations, is passed correctly to the server.
I'm a beginner at Shiny, so I hope that someone can explain what's going wrong. Not being able to see the values of variables makes debugging a million times harder than in regular R.
sidebarLayout(
sidebarPanel(
radioButtons("calctype", "Choose calculation:",selected = "calcFPR",
choices = c(
"prior (for given FPR and P val)" = "calcprior",
"P value (for given FPR and prior)" = "calcpval",
"FPR (for given P value and prior)" = "calcFPR")),
conditionalPanel(
condition = "input.calctype == 'calcprior'",
numericInput("pval", label = h5("observed P value"), value = 0.05, min
= 0, max = 1),
numericInput("FPR", label = h5("false positive risk"), value = 0.05,
min = 0, max = 1)
),
conditionalPanel(
condition = "input.calctype == 'calcpval'",
numericInput("FPR", label = h5("false positive risk"), value = 0.05,
min = 0, max = 1),
numericInput("prior", label = h5("prior probability of real effect"),
value = 0.5, min = 0, max = 1)
),
conditionalPanel(
condition = "input.calctype == 'calcFPR'",
numericInput("pval",label = h5("observed P value"),value = 0.05, min =
0, max = 1),
numericInput("prior", label = h5("prior probability of real effect"),
value = 0.5, min = 0., max = 1.)
),
inputPanel(
numericInput("nsamp",label = h5("Number in each sample"), step = 1,
value = 16, min = 2)
),
mainPanel(
(I also need to work out how to use the calctype to direct the server to the appropriate block of R code.)
Here is a working example for you:
library(shiny)
ui <- fluidPage(
titlePanel("|Species Table"),
sidebarLayout(
sidebarPanel(
radioButtons("calctype", "Choose calculation:",selected = "calcFPR",
choices = c(
"prior (for given FPR and P val)" = "calcprior",
"P value (for given FPR and prior)" = "calcpval",
"FPR (for given P value and prior)" = "calcFPR")),
uiOutput("test1"),
uiOutput("test2"),
inputPanel(
numericInput("nsamp",label = h5("Number in each sample"), step = 1,
value = 16, min = 2)
)),
mainPanel(textOutput("text1"),
textOutput("text2"))
))
server <- function(input, output) {
test <- reactive({
if(input$calctype == 'calcprior'){
label1 <- paste("observed P value")
label2 <- paste("false positive risk")
}else if(input$calctype == 'calcpval'){
label1 <- paste("false positive risk")
label2 <- paste("prior probability of real effect")
}else{
label1 <- paste("observed P value")
label2 <- paste("prior probability of real effect")
}
list(label1 = label1, label2 = label2)
})
output$test1 <- renderUI({
numericInput("test1", label = h5(test()$label1), value = 0.05, min = 0, max = 1)
})
output$test2 <- renderUI({
numericInput("test2", label = h5(test()$label2), value = 0.05, min = 0, max = 1)
})
output$text1 <- renderText({
input$test1
})
output$text2 <- renderText({
input$test2
})
}
shinyApp(ui = ui, server = server)
you do not need so many conditionalPanels, i have noticed in your code that the only thing that changes is the label of numericInput according to choosen calculation type. Therefore in this case i have used if...else... statement in the server to change the label of two `numericInputs (test1 and test2) with choosen calculation type.
Furthermore i have printed out the output of the numericInput `s (text1 and text2) to show you that the user input is acctually passed to server and can be further used in the calculations.

Resources