闪亮:如何根据计数器条件显示结果

时间:2017-06-27 12:21:52

标签: r shiny

我想根据计数器值显示不同的输出。例如,如果计数器等于3显示输出A.如果计数器小于3,则不显示任何内容,如果计数器大于3则显示输出A和C. 要显示的输出(在我的示例中是第三列的总和)来自observe()函数。

这是一个最小的例子

 library(shiny)

 ui <- fluidPage(
  sidebarPanel(numericInput("c1","Example", NA),
           actionButton("update", "Update"),
           br(),  br(),
           actionButton("reset", "Clear"),
           br(), br(),
           uiOutput("displayCounter"),
           br(),br(),
           textOutput("displaysum"),
           br(),br(),
           textOutput("total_sum")
  ),

  mainPanel( tableOutput("example")

            )
)

server <- function(input, output, session) {

 values <- reactiveVal(data.frame(A=1, B=2, C=3))

  # update values table on button click
  observeEvent(input$update,{

    old_values <- values()

    A_new <- input$c1
    B_new <- A_new + 2
    C_new <- A_new + B_new

  new_values <- data.frame(A=A_new, B=B_new, C=C_new)

    # attach the new line to the old data frame here:
    new_df <- rbind(old_values, new_values)

    #store the result in values variable
    values(new_df)

    #reset the numeric input to NA  
    updateNumericInput(session, "c1", "Example", NA)

  })

#Delete last row 
     deleteEntry <- observeEvent(input$reset,{
           values( values()[-nrow(values()),])
   })

##reactive counter
   updateCounter <- reactive({
     if (is.na(input$update)) {k <- 0}  
     else {k <- (input$update - input$reset)}
     return(k)
     })

##After 3 interactions stop counter 
   Counterlimit <- reactive({ 
     if(updateCounter() > 3){ return(3)
     }else{ updateCounter() }
   })

   output$displayCounter <- renderText({ c("Iteractions:", 
Counterlimit())   })       

       # reactive

       Total <- reactive({ colSums(values()[3]) })

#After 3 interactions display sum of column 3

  observe({

    c3_sum <-Total()
    if (updateCounter()==3) {
     output$displaysum  <- renderText({paste("Partial sum", c3_sum )})
     }
    if (updateCounter()<3){
     output$displaysum  <- renderText({paste("Partial sum", NULL)})
    }
    if (updateCounter()>3) {
      output$total_sum  <- renderText({paste("Total sum", Total() )})

    }

  })
# Print table

  output$example <- renderTable({  return(values())  })
}

shinyApp(ui = ui, server = server)

如果我使用清除按钮使计数器小于3,则仍会显示总和。由于我的问题是显示条件的结果,我想知道我是否可以在我的ui中使用条件面板来显示我想要的内容。

是否可以使用observe()函数的输出作为条件面板中的输入来显示结果?或基于反制条件显示这些产出的任何其他建议。

2 个答案:

答案 0 :(得分:1)

您需要为条件分配ouput个插槽

ui <- fluidPage(
  selectInput("choose", "choose", letters[1:2]),
  conditionalPanel(
    condition = "output.myCondition == true",
    actionButton("button", "this button is only visible when a is selected"))
)

server <- function(input, output){
  output$myCondition <- reactive({input$choose == 'a'})
  outputOptions(output, "myCondition", suspendWhenHidden = FALSE)
}

shinyApp(ui, server)

suspendWhenHidden部分至关重要。它强制评估output$myCondition,即使它没有(直接)显示在UI中。

请注意,true参数使用TRUE而不是condition。这是因为它遵循javascript语法。

但是,对于您的问题,无需使用conditionalPanel。您可以根据输入返回不同的文本。

shinyApp(
  fluidPage(
    textOutput("display"),
    actionButton("rerun","rerun")
  ),
  function(input, output, session){
    updateCounter = reactive({
      input$rerun
      sample(4:6,1)
    })

    Total = function(){isolate(updateCounter())}

    output$display  <- renderText({
      partialsum <-Total()
      ctr = updateCounter()
      if(ctr==5) {
        return(paste("Result", partialsum))
      } 
      if(ctr<5){
        return(paste("Result", NULL))
      }
      if(ctr>5) {
        return(paste("Result", partialsum))
      } 
    })
  }
)

答案 1 :(得分:0)

按照格雷戈尔的想法,我找到了解决方案。两个主要变化:

首先,我意识到我需要隔离计数器值,所以我改变了我定义计数器的形式。

其次,我将条件放在渲染文本函数中。现在直接显示预期结果。

我已将原始问题修改为更精确。这是最终的代码:

library(shiny)

ui <- fluidPage(
  sidebarPanel(numericInput("c1","Example", NA),
           tags$p(actionButton("update", "Update")),
           tags$p(actionButton("reset", "Clear")),
           textOutput("count"),
           textOutput("display")
 ),

  mainPanel( tableOutput("example")
            )
) 

server <- function(input, output, session) {

  values <- reactiveVal(data.frame(A=1, B=2, C=3))

  # update values table on button click
  observeEvent(input$update,{

    old_values <- values()

    A_new <- input$c1
    B_new <- A_new + 2
    C_new <- A_new + B_new

  new_values <- data.frame(A=A_new, B=B_new, C=C_new)

    # attach the new line to the old data frame here:
    new_df <- rbind(old_values, new_values)

    #store the result in values variable
    values(new_df)

    #reset the numeric input to NA  
    updateNumericInput(session, "c1", "Example", NA)

  })

 #Delete last row 
       deleteEntry <- observeEvent(input$reset,{
               values( values()[-nrow(values()),])
   })

##reactive counter modified
    updateCounter <- reactiveValues(i = 0)

   output$count <- renderText({
     paste0("Iteractions: ", updateCounter$i)
   })

   observe({
     input$update

     isolate({
       updateCounter$i <- updateCounter$i + 1
     })
   })

   observe({
     input$reset
     isolate(updateCounter$i <- updateCounter$i - 1)
   })

Total <- reactive({ colSums(values()[3]) })

      output$display  <- renderText({
        partialsum <-Total()
        if(updateCounter$i==3) {
          value3 <<- partialsum
          return(paste("Partial result", value3))
        } 
        if(updateCounter$i<3){
           return()
        }
        if(updateCounter$i>3) {
        display1 <- paste("Partial result", value3)
        display2 <- paste("Total result", partialsum)  
        paste(display1, display2)  
        } 
      })

  output$example <- renderTable({  return(values())  })
}

 shinyApp(ui = ui, server = server)