简体   繁体   English

从 Shiny DT 中的单选按钮中提取用户输入值到 dataframe 或列表中

[英]Extracting user input values from radio buttons in Shiny DT into a dataframe or list

I am building a shiny app with a datatable that uses some javascript callback in which users can make a selection for every row (yes/no/maybe), in a later stage of the app I then need that user input in the form of a list or table.我正在构建一个 shiny 应用程序,该应用程序带有一个数据表,该数据表使用一些 javascript 回调,用户可以在其中为每一行进行选择(是/否/也许),然后在应用程序的后期阶段,我需要用户以列表或表格。 The exact number of rows is not predefined.未预定义确切的行数。 Ideally I would like to make the a summary on how many 'yes'/'no'/'maybe' were selected per user and how which rows were selected as no.理想情况下,我想总结一下每个用户选择了多少“是”/“否”/“可能”以及如何选择哪些行为否。 I can print the values into the R terminal, but that is not sufficient, the values, need to be saved as an object.我可以将这些值打印到 R 终端,但这还不够,这些值需要保存为 object。

Here is a short example of the code I have thusfar (based on Radio Buttons on Shiny Datatable, with data.frame / data.table and Extracting values of selected radio buttons in shiny DT )这是迄今为止我所拥有的代码的简短示例(基于Shiny 数据表上的单选按钮,带有 data.frame / data.table提取 Z531704A02607A1646Z DT 中所选单选按钮的值 DT EE1

library(shiny)
library(DT)
library(shinyWidgets)

my_table <- tibble(
  rowid = letters[1:7],
  val_1 = round(runif(7, 0, 10), 1),
  val_2 = round(rnorm(7), 2),
  Yes   = "Yes",
  No    = "No",
  Maybe = "Maybe"
) %>%
  mutate(
    Yes =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , Yes),
    No =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , No),
    Maybe =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , Maybe)
  )


shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    DT::dataTableOutput("datatable"),
    actionBttn(
      inputId = "btnProcess",
      label = "Process",
      style = "float",
      size = "sm",
      color = "success"
    ),
    actionBttn(
      inputId = "btnCancel",
      label = "Cancel",
      style = "float",
      size = "sm",
      color = "warning"
    )#,
    #verbatimTextOutput('sel')
    
    
    
  ),
  
  server = function(input, output, session) {
    dtWithRadioButton <- reactiveValues(dt = my_table)
    
    
    output$datatable <- renderDT(
      datatable(
        dtWithRadioButton$dt,
        selection = "none",
        escape = FALSE,
        options = list(
          dom = 't',
          paging = FALSE,
          ordering = FALSE
        ),
        callback = JS(
          "table.rows().every(function(i, tab, row) {
                  var $this = $(this.node());
                  $this.attr('id', this.data()[0]);
                  $this.addClass('shiny-input-radiogroup');
                });
                Shiny.unbindAll(table.table().node());
                Shiny.bindAll(table.table().node());"
        ),
        rownames = F
      ),
      server = FALSE
    )
    
    # this did not work
    #list_results <- eventReactive(input$btnProcess,{
    
    observeEvent(input$btnProcess, {
      dt <- dtWithRadioButton$dt # accessing the reactive value
      # do some processing based on the radio button selection
      
      list_values <- list()
      for (i in unique(my_table$rowid)) {
        list_values[[i]] <- paste0(i, ": ", input[[i]])
        
      }
      
      print(list_values)
      
    })
    
    # This did noy work
    # output$sel = renderPrint({
    #   list_results()
    # })
    #
    
    observeEvent(input$btnCancel, {
      removeModal(session)
    })
  }
)

For many bonus points, having some.css code to change the colours of the rows dependent on the radio button would be amazing (say red for no, green for yes and yellow for maybe).对于许多奖励积分,拥有一些.css 代码来更改依赖于单选按钮的行的颜色将是惊人的(例如红色表示否,绿色表示是,黄色表示可能)。

You could add a new variable in reactiveValues to store the result, get the data from input for each unique id using sapply and store it in dataframe.您可以在reactiveValues添加一个新变量来存储结果,使用sapply从每个唯一idinput中获取数据,并将其存储在 dataframe 中。

library(shiny)
library(DT)
library(shinyWidgets)

my_table <- tibble(
  rowid = letters[1:7],
  val_1 = round(runif(7, 0, 10), 1),
  val_2 = round(rnorm(7), 2),
  Yes   = "Yes",
  No    = "No",
  Maybe = "Maybe"
) %>%
  mutate(
    Yes =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , Yes),
    No =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , No),
    Maybe =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , Maybe)
  )


shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    DT::dataTableOutput("datatable"),
    actionBttn(
      inputId = "btnProcess",
      label = "Process",
      style = "float",
      size = "sm",
      color = "success"
    ),
    actionBttn(
      inputId = "btnCancel",
      label = "Cancel",
      style = "float",
      size = "sm",
      color = "warning"
    ),
    dataTableOutput('result')
  ),
  
  server = function(input, output, session) {
    dtWithRadioButton <- reactiveValues(dt = my_table, result = NULL)
    
    
    output$datatable <- renderDT(
      datatable(
        dtWithRadioButton$dt,
        selection = "none",
        escape = FALSE,
        options = list(
          dom = 't',
          paging = FALSE,
          ordering = FALSE
        ),
        callback = JS(
          "table.rows().every(function(i, tab, row) {
                  var $this = $(this.node());
                  $this.attr('id', this.data()[0]);
                  $this.addClass('shiny-input-radiogroup');
                });
                Shiny.unbindAll(table.table().node());
                Shiny.bindAll(table.table().node());"
        ),
        rownames = F
      ),
      server = FALSE
    )
    
    
    observeEvent(input$btnProcess, {
      dt <- dtWithRadioButton$dt 
      dt$result <- sapply(unique(my_table$rowid), function(x) input[[x]])
      dtWithRadioButton$result <- dt
    })
    
    
    observeEvent(input$btnCancel, {
      removeModal(session)
    })
    
    output$result <- renderDT({
      req(dtWithRadioButton$result)
      datatable(dtWithRadioButton$result[c('rowid', 'val_1', 'val_2', 'result')])
    })
  }
)

在此处输入图像描述

You can do the calculation in a reactive and then call that reactive inside an observeEvent and display it as a text or a DT table using any output method of your choice.您可以在reactive中进行计算,然后在observeEvent中调用该reactive式,并使用您选择的任何 output 方法将其显示为文本或 DT 表。

library(shiny)
library(DT)
library(shinyWidgets)

my_table <- tibble(
  rowid = letters[1:7],
  val_1 = round(runif(7, 0, 10), 1),
  val_2 = round(rnorm(7), 2),
  Yes   = "Yes",
  No    = "No",
  Maybe = "Maybe"
) %>%
  mutate(
    Yes =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , Yes),
    No =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , No),
    Maybe =  sprintf('<input type="radio" name="%s" value="%s"/>', rowid , Maybe)
  )


shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    DT::dataTableOutput("datatable"),
    actionBttn(
      inputId = "btnProcess",
      label = "Process",
      style = "float",
      size = "sm",
      color = "success"
    ),
    actionBttn(
      inputId = "btnCancel",
      label = "Cancel",
      style = "float",
      size = "sm",
      color = "warning"
    ),
    verbatimTextOutput('sel')
    
    
    
  ),
  
  server = function(input, output, session) {
    dtWithRadioButton <- reactiveValues(dt = my_table)
    
    
    output$datatable <- renderDT(
      datatable(
        dtWithRadioButton$dt,
        selection = "none",
        escape = FALSE,
        options = list(
          dom = 't',
          paging = FALSE,
          ordering = FALSE
        ),
        callback = JS(
          "table.rows().every(function(i, tab, row) {
                  var $this = $(this.node());
                  $this.attr('id', this.data()[0]);
                  $this.addClass('shiny-input-radiogroup');
                });
                Shiny.unbindAll(table.table().node());
                Shiny.bindAll(table.table().node());"
        ),
        rownames = F
      ),
      server = FALSE
    )
    

    
    list_results <- reactive({
      list_values <- list()
      for (i in unique(my_table$rowid)) {
        list_values[[i]] <- paste0(i, ": ", input[[i]])
        
      }
      list_values
    })
    
    observeEvent(input$btnProcess, {
      
      output$sel = renderPrint({
        list_results()
      })


      
    })
    

    
    observeEvent(input$btnCancel, {
      removeModal(session)
    })
  }
)

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM