首页 > 解决方案 > 如何在 R Shiny 中更改反应小标题中的值

问题描述

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

以下是我遇到的问题的代表。运行第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

以编程方式更改反应小标题中的值的语法是什么?

标签: rshinyreactive

解决方案


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

  • 第一个是renderTable在对数据进行子集化后使用,然后在里面修改表observeEvent
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()(因为它是反应性的)。它可能会让您和代码的执行感到困惑。


推荐阅读