如何使用用户输入更新R Shiny中的 Dataframe

rggaifut  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(179)

我想在R Shiny应用程序中使用用户输入更新 Dataframe 。用户选择一行数据,然后选择使用selectInput更新物种列的值。每次更新都需要累积,即新更新更新以前更新的数据。我尝试按照answer使用reactiveValues,但无法使其工作。

library(shiny)
library(reactable)
library(tidyverse)

iris_df = iris %>% 
  mutate(
    id = row_number(),
    Species = as.character(Species)
    )

ui <- fluidPage(
  
  navbarPage(
    "HELP!", 
    tabPanel(
      "Iris",
      sidebarLayout(
        sidebarPanel(
          selectInput("update_species", "Update species", choices = c("Rose", "Daffodil"))
        ),
        mainPanel(fluidRow(reactableOutput("iris")))
      )
    )
  )
)

server <- function(input, output) {
  
  observeEvent(input$update_species, {
      iris_df = iris_df %>% 
        mutate(Species = case_when(id == selected_row() ~ input$update_species, TRUE ~ Species))
  })
  
  selected_row = reactive(getReactableState("iris", "selected"))
  
  output$iris = renderReactable({
    reactable(
      iris_df,
      selection = "single",
    )
  })
}

shinyApp(ui = ui, server = server)
tzdcorbm

tzdcorbm1#

您的代码的第一个问题是observeEventinput$update_species触发,如果没有选择行,selected_row()将是NULL,则会导致错误。为了防止出现这种情况,您可以添加req(selected_row())或使用selected_row()来触发observeEvent,就像我在下面的代码中所做的那样。
接下来,正如您已经意识到的,您需要reactiveValreactiveValues来根据用户选择实际更新observeEvent内的 Dataframe 。

library(shiny)
library(reactable)
library(tidyverse)

iris_df <- iris %>%
  mutate(
    id = row_number(),
    Species = as.character(Species)
  )

ui <- fluidPage(
  navbarPage(
    "HELP!",
    tabPanel(
      "Iris",
      sidebarLayout(
        sidebarPanel(
          selectInput("update_species", "Update species", choices = unique(iris_df$Species))
        ),
        mainPanel(fluidRow(reactableOutput("iris")))
      )
    )
  )
)

server <- function(input, output) {
  iris_df <- reactiveVal(iris_df)

  observeEvent(selected_row(), {
    iris_df(iris_df() %>%
      mutate(Species = case_when(id == selected_row() ~ input$update_species, TRUE ~ Species)))
  })

  selected_row <- reactive(getReactableState("iris", "selected"))

  output$iris <- renderReactable({
    reactable(
      iris_df(),
      selection = "single",
    )
  })
}

shinyApp(ui = ui, server = server)

这是更新第1、4和7行后的输出示例:

相关问题