如何使用reactiveValues保存以前的交互

时间:2017-06-10 20:58:40

标签: shiny

我正在开发一个表,每次使用操作按钮时都会进行一些计算。我的表中的一列取决于其先前的值,

C_new <- C_old + B_new - A_new

例如,如果A = 4,B = A + 2且C = C(-1)+ B - A我的预期结果是

A   B  C
1   2  3
4   6  5

我试图使用reactiveValue保存列C的先前值,如How to “remember” information from the previous iteration when using reactiveTimer in Shiny?中所述,但它不起作用。我不知道我哪里出错了。

这是我的代码

library(shiny)
ui <- fluidPage(
  sidebarPanel(textInput("c1","Example"),
           actionButton("update", "Update Table")),
  mainPanel(tableOutput("example"))
)

server <- function(input, output) {

  C_old <- reactive(x=3)

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

  newEntry <- observeEvent(input$update,{

    A_new <- as.numeric(input$c1)
    B_new <- A_new + 2
    C_new <- isolate (C_old$x + B_new - A_new) 
    C_old$x <<- C_new

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

   # attach the new line to the old data frame here:
   values$df <- rbind(values$df, new)

  })

  # Print the content of values$df
  output$example <- renderTable({
   return(values$df)
  })

}

shinyApp(ui = ui, server = server)

1 个答案:

答案 0 :(得分:4)

重要的是要知道,observeEvent s(类似于observe s)没有输出。你只是观察一个变化,并在他们的身体中做一些事情,但不应该返回任何东西(这与reactive({ })不同,后者也会观察到变化但有返回值),有用link

Isolate中不需要

observeEvent,因为除了input$update之外没有任何内容触发更新(这与observereactive不同,其中所有内容都可更改正文中的项目会触发更新)。

以下是您的问题的解决方案。我使用了reactiveVal来存储一个可更新的值(请参阅?reactiveVal获取帮助)。单击操作按钮后,我通过调用values()检索旧表,计算所有新值(注意,我需要使用tail仅获取最后C值)并附加在通过调用values

将扩展表存储到values(new_df)之前得到旧值
library(shiny)
ui <- fluidPage(
  sidebarPanel(numericInput("c1","Example", 0),
               actionButton("update", "Update Table")),
  mainPanel(tableOutput("example"))
)

server <- function(input, output) {

  # stores the current data frame, called by values() and set by values(new_data_table)
  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 <- tail(old_values$C, 1) + B_new - A_new  # tail to get the last C value

    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)

  })

  # Print the content of values$df
  output$example <- renderTable({
    return(values())
  })

}

shinyApp(ui = ui, server = server)

enter image description here