In running the below demo code, if the user selects to view two rows of data via the radio button, I would like to show the output of renderPrint({dat()})
in the 2nd panel "choices2" (whereby the Values in the above dataframe are multiplied by 2), otherwise show the output of renderText("Select view 2 rows for results")
in that same second panel "choices2". They both work fine when run on their own, but when I combine them into an conditional within an observeEvent()
(shown in commented-out lines below), the App crashes. What am I doing wrong here?
I'm trying to better understand reactivity and observers. Maybe an observer isn't even required here, I don't know.
Demo code:
library(shiny)
data <-
data.frame(
ID = c(1,1,1,2,2,2),
Period = c(1, 2, 3, 1, 2, 3),
Values = c(5, 10, 15, 0, 2, 4)
)
ui <- fluidPage(
h5(strong("Base data frame:")),
tableOutput("data"),
radioButtons(inputId = "viewData",
label = "View from original dataframe:",
choiceNames = c('All','First 2 rows'),
choiceValues = c('All','Two rows'),
selected = 'All',
inline = TRUE
),
h5(strong("Reactive results of radio button:")),
verbatimTextOutput("choices"),
h5(strong("Multiply above values by 2 when viewing 1st 2 rows:")),
verbatimTextOutput("choices2")
)
server <- function(input, output, session) {
output$data <- renderTable(data)
rv <- reactiveValues(choices=c())
observeEvent(input$viewData, {
if(input$viewData == 'Two rows'){rv$choices <- data[1:2,]}
else {rv$choices <- data}
})
output[["choices"]] <- renderPrint({ rv$choices })
dat <- reactive({
dat <- rv$choices
dat[, 3] <- 2 * dat[, 3]
dat
})
output[["choices2"]] <-
renderPrint({dat()}) # this runs fine on outs own
# renderText("Select view 2 rows for results") # this runs fine on outs own
# The below observer doesn't work:
# observeEvent(input$viewData, {
# if(input$viewData == 'Two rows'){renderPrint({dat()})}
# else {renderText("Select view 2 rows for results")}
# })
}
shinyApp(ui, server)
CodePudding user response:
Maybe you can do the check inside the renderPrint
:
output[["choices2"]] <- renderPrint({
if(input$viewData == 'Two rows'){
dat()
}
else{
cat("Select view 2 rows for results")
}
})
CodePudding user response:
Extending the answer from @PorkChop, use knitr::combine_words
to get rid of [1]
in output.
output[["choices2"]] <- renderPrint({
if(input$viewData == 'Two rows'){
dat()
}
else{
knitr::combine_words("Select view 2 rows for results")
}
})
CodePudding user response:
You can use uiOutput()
, which creates the UI based on a condition.
In pseudocode (e.g. you will need to adapt it a bit):
# ui
uiOutput("choices2")
# server
output$choices2 <- renderUI({
if( your_condition_to_test ){
h2("Select view 2 rows for results")
} else {
verbatimTextOutput(dat())
}
})