簡體   English   中英

有沒有辦法在 shiny 中將選擇器/選擇輸入與可編輯的反應式 DT 結合使用?

[英]Is there a way to use picker/selectInput in conjunction with an editable, reactive DT in shiny?

我一直在努力解決以下問題,並且在 SO 上找不到合適的解決方案。

這是我對 DataTable 的要求

  1. 我想編輯我的數據表(已實現)
  2. 在我的編輯完好無損的情況下過濾 DataTable 中的數據。 目前,我的編輯在我更改過濾器后消失
  3. 將整個 DataTable 保存為 RDS,而不僅僅是基於過濾器的當前顯示數據。 目前,我只是根據過濾器保存當前顯示的 DataTable

提前謝謝你的幫助!

df <- iris

species <- unique(as.character(df$Species))
width <- unique(df$Petal.Width)
#==========================================UI=======================================================#
ui = navbarPage("CSAT & SA", theme = shinytheme("flatly"),
                tabPanel("Sentiment Analysis",
                         sidebarLayout(
                           sidebarPanel(
                             pickerInput(inputId = "species",
                                         label = "Species", selected = species,
                                         choices = species, multiple = T, 
                                         options = list(`actions-box` = TRUE, `deselect-all-text` = "None...",
                                                        `select-all-text` = "Select All", `none-selected-text` = "None Selected")),
                             pickerInput(inputId = "width",
                                         label = "Petal Width", selected = width,
                                         choices = width, multiple = T, 
                                         options = list(`actions-box` = TRUE, `deselect-all-text` = "None...",
                                                        `select-all-text` = "Select All", `none-selected-text` = "None Selected")),
                             width = 2, 
                             actionButton(inputId = "save", label = "Save"), 
                             actionButton(inputId = "update", label = "Update")
                           ),
                           mainPanel(
                             h2("Iris"), fluidRow(
                               tabPanel("Iris", DT::dataTableOutput("x1"),
                                        width = 12)
                             )))))
#==========================================SERVER=======================================================#

server <- function(input, output, session) {
  
  SA <- reactive({
    df<-df %>%
      filter(Species %in% input$species) %>%
      filter(Petal.Width %in% input$width)
  }) 
  
  
  rec_val = reactiveValues(df = NULL)
  
  
  observe({
    rec_val$SA <- SA()
  })
  
  output$x1 = renderDT(SA(),  selection = 'none', editable = list(target = 'cell', disable = list(columns=c(0,1,2))))
  
  proxy = dataTableProxy('x1')
  
  observeEvent(input$x1_cell_edit, {
    info = input$x1_cell_edit
    str(info)
    i = info$row
    j = info$col   
    v = info$value
    rec_val$SA[i, j] <<- DT::coerceValue(v, rec_val$SA[i, j])
    replaceData(proxy, rec_val$SA, resetPaging = FALSE)
  })
  
  observeEvent(input$save, {
    saveRDS(rec_val$SA, "somewhere.rds") # write new data out
    
  })

  
  
}

shinyApp(ui = ui, server = server) 

編輯:

看這里

您需要使用updatePickerInput()根據編輯更新可用的選項。 此外,定義行 id 以保留修改后的數據。 使用重置您可以返回到原始數據表。 嘗試這個

library(shinythemes)
dat <- iris

species <- unique(as.character(dat$Species))
width <- unique(dat$Petal.Width)
#==========================================UI=======================================================#
ui = navbarPage("CSAT & SA", theme = shinytheme("flatly"),
                tabPanel("Sentiment Analysis",
                         sidebarLayout(
                           sidebarPanel(
                             pickerInput(inputId = "species",
                                         label = "Species", selected = species,
                                         choices = as.list(species), multiple = T, 
                                         options = list(`actions-box` = TRUE, `deselect-all-text` = "None...",
                                                        `select-all-text` = "Select All", `none-selected-text` = "None Selected")),
                             pickerInput(inputId = "width",
                                         label = "Petal Width", selected = width,
                                         choices = as.list(width), multiple = T, 
                                         options = list(`actions-box` = TRUE, `deselect-all-text` = "None...",
                                                        `select-all-text` = "Select All", `none-selected-text` = "None Selected")),
                             width = 2, 
                             actionButton(inputId = "save", label = "Save"), 
                             actionButton(inputId = "reset", label = "Reset")
                           ),
                           mainPanel(
                             h2("Iris"), fluidRow(
                               tabPanel("Iris", DT::dataTableOutput("x1"), DTOutput("x2"),
                                        width = 12)
                             )))))
#==========================================SERVER=======================================================#

server <- function(input, output, session) {
  
  SA <- reactive({
    row_id <- c(1:nrow(dat))
    data <- data.frame(dat,row_id)
    data
  })
  
  rv = reactiveValues(df = NULL)
  
  observe({
    rv$df <- SA() %>%
      filter(Species %in% isolate(input$species)) %>%
      filter(Petal.Width %in% isolate(input$width))
  })
  
  observeEvent(input$species, {
                  df1 <- SA()         ### orig data
                  df2 <- rv$df        ### modified data
                  if (is.null(df2)){
                    rvdf <- SA()
                  }else{
                    vn <- colnames(df1)
                    vnx <- paste0(vn,".x")
                    vny <- paste0(vn,".y")

                    rvdf <- left_join(df1, df2, by="row_id") %>% transmute(var1 = get(!!vnx[1]), var2 = get(!!vnx[2]), var3 = get(!!vnx[3]),
                                                                            var4 = ifelse(is.na(get(!!vny[4])), get(!!vnx[4]), get(!!vny[4])),
                                                                            var5 = get(!!vnx[5]),  # ifelse(is.na(get(!!vny[5])), get(!!vnx[5]), get(!!vny[5])),
                                                                            row_id)

                    colnames(rvdf) <- vn
                  }
                  rv$df <- rvdf  %>%
                    filter(Species %in% input$species) %>% 
                    filter(Petal.Width %in% input$width)

  })
  
  observeEvent(input$width, {
    df1 <- SA()         ### orig data
    df2 <- rv$df        ### modified data
    if (is.null(df2)){
      rvdf <- SA()
    }else{
      
      vn <- colnames(df1)
      vnx <- paste0(vn,".x")
      vny <- paste0(vn,".y")
      ###    keep modified data, if present; if not, keep original data
      rvdf <- left_join(df1, df2, by="row_id") %>% transmute(var1 = get(!!vnx[1]), var2 = get(!!vnx[2]), var3 = get(!!vnx[3]),
                                                              var4 = ifelse(is.na(get(!!vny[4])), get(!!vnx[4]), get(!!vny[4])),  ##  keep modified data
                                                              var5 = get(!!vnx[5]),  # ifelse(is.na(get(!!vny[5])), get(!!vnx[5]), get(!!vny[5])),
                                                              row_id)
      
      colnames(rvdf) <- vn
      
    }
    rv$df <- rvdf  %>%
      filter(Species %in% input$species) %>% 
      filter(Petal.Width %in% input$width)
    
  })
  
  output$x1 <- renderDT(rv$df,  selection = 'none',
                       editable = list(target = 'cell', disable = list(columns=c(0,1,2))),
                       options = list(
                         columnDefs = list(
                           list(
                             visible = FALSE,
                             targets = 6
                           )
                         )
                       )
                       )
  
  proxy <- dataTableProxy('x1')
  
  observeEvent(input$x1_cell_edit, {
    info = input$x1_cell_edit
    str(info)
    i = info$row
    j = info$col   
    v = info$value
    
    rv$df[i, j] <<- DT::coerceValue(v, rv$df[i, j])
    
    #replaceData(proxy, rv$df, resetPaging = FALSE)
    
  })
  
  observeEvent(input$save, {
    #choicess <- as.list(unique(c(as.character(rv$df[,5]), as.character(SA()[,5]))))
    choicesp <- as.list(unique(c(rv$df[,4], SA()[,4])))
    # updatePickerInput(session, inputId = "species", choices = choicess, selected=choicess)
    updatePickerInput(session, inputId = "width", choices = choicesp, selected=choicesp)
    saveRDS(rv$df, "somewhere.rds") # write new data out
    
    df3 <- readRDS("C:/My Disk Space/_My Work/RStuff/GWS/somewhere.rds")
    output$x2 <- renderDT({
      df3
    })
    
  })
  observeEvent(input$reset, {
    rv$df <- SA()
    # choicess <- unique(as.character(rv$df[,5]))
    choicesp <- unique(SA()[,4])
    # updatePickerInput(session, inputId = "species", choices = choicess, selected=choicess)
    updatePickerInput(session, inputId = "width", choices = choicesp, selected=choicesp)
  })
  
}

shinyApp(ui = ui, server = server) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM