Как изменить значение в реактивном тибле в R Shiny - PullRequest
0 голосов
/ 25 февраля 2020

Я хотел бы обновить содержимое реактивного объекта, который держит тиббл в ответ на кнопку pu sh, и я не могу понять синтаксис. Решение, которое было размещено здесь , содержит решение, которое раньше работало, но теперь оно выдает ошибку.

Ниже приведено описание проблемы, с которой я столкнулся. Сначала запустите 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

Какой синтаксис для программно изменить значение в реактивном тибле?

1 Ответ

0 голосов
/ 25 февраля 2020

Вы не можете напрямую изменять значение реактивного объекта. Сначала необходимо определить объект stati c, который будет принимать значение реактивного объекта, а затем вы можете изменить значение объекта stati c. Два варианта для вас (без изменений в 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() (потому что он реактивный). Это может сбивать с толку как вас, так и выполнение кода.

...