如何在 R Shiny 中更改反应式 tibble 中的值

How to change a value in a reactive tibble in R Shiny

我想更新反应式 object 的内容,该反应式 object 持有小标题以响应按钮按下,但我无法弄清楚语法。发布的解决方案 包含一个曾经有效但现在抛出错误的解决方案。

以下是我遇到的问题的代表。 运行 write.csv(iris, "text.csv") 第一。

library(shiny)
library(tidyverse)

# create the test data first
# write.csv(iris, "text.csv")

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

    in_data <- reactive({
        inFile <- input$raw
        x <- read.csv(inFile$datapath, header=TRUE)
    })

    subset <- reactive({
        subset <- in_data() %>%
            filter(Species == "setosa")
    })

    observeEvent(input$pushme, {
            subset()$Sepal.Length[2] <- 2
    })

    output$theOutput <- renderTable({
        subset()
    })
})


ui <- shinyUI(
    fluidPage(
        fileInput('raw', 'Load test.csv'),
        actionButton("pushme","Push Me"),
        tableOutput('theOutput')     
    )
)
shinyApp(ui,server)

我更改值的代码:

subset()$Sepal.Length[2] <- 2

引发此错误:

Error in <-: invalid (NULL) left side of assignment

以编程方式更改响应式 tibble 中的值的语法是什么?

您不能直接修改反应对象的值。您必须首先定义一个静态对象,它将采用反应对象的值,然后您可以修改静态对象的值。两个选项供您选择(ui 中没有修改):

  • 第一个是在对数据进行子集化之后使用 renderTable,然后在 observeEvent:
  • 中修改 table
server <- shinyServer(function(input, output) {

  in_data <- reactive({
    inFile <- input$raw
    x <- read.csv(inFile$datapath, header=TRUE)
  })

  test1 <- reactive({
    data <- in_data() %>%
      filter(Species == "setosa")
    data
  })

  output$theOutput <- renderTable({
    req(input$raw)
    test1()
  })

  observeEvent(input$pushme, {
    output$theOutput <- renderTable({
      req(input$raw)
      test1 <- test1()
      test1$Sepal.Length[2] <- 2
      test1
    })
  })

})
  • 第二个是定义另一个数据集(此处为test2),仅当按下按钮时才会用eventReactive计算。然后,您必须使用存在条件来定义要在 renderTable 中使用的两个数据集中的哪一个:
server <- shinyServer(function(input, output) {

  in_data <- reactive({
    inFile <- input$raw
    x <- read.csv(inFile$datapath, header=TRUE)
  })

  test1 <- reactive({
    data <- in_data() %>%
      filter(Species == "setosa")
    data
  })

  test2 <- eventReactive(input$pushme, {
      test1 <- test1()
      test1$Sepal.Length[2] <- 2
      test1
    }
  )

  output$theOutput <- renderTable({
    if (input$pushme) {
      test2()
    }
    else {
      req(input$raw)
      test1()
    }
  })

})

顺便说一句,你不应该像函数名一样调用数据集(反应性或非反应性)。在您的示例中,您调用了 subset 您修改的反应性数据集。这不好,因为这个数据集将用作 subset()(因为它是反应性的)。这可能会让您和代码的执行感到困惑。