【问题标题】:Radiobuttons in Shiny DataTable for "subselection" of rows/ grouping in one columnShiny DataTable 中的单选按钮,用于在一列中对行/分组进行“子选择”
【发布时间】:2018-06-01 19:57:03
【问题描述】:

我想要完成的与this thread 类似,但稍微复杂一些。

我想将单选按钮分成不同的组,但在一列中,因此可以“子选择”行。

目前只有 ID 为“C”的单选按钮组有效,因为 div 元素是为整个表格定义的。我试图通过javascript回调插入闪亮的标签,但我只能为每一行或每一列插入一个单选按钮,但不能为一列中多行的子集插入。

对 javascript 或闪亮的解决方案开放。

shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    tags$div(id="C",class='shiny-input-radiogroup',DT::dataTableOutput('foo')),
    verbatimTextOutput("test")
  ),
  server = function(input, output, session) {
    m = matrix(
      c(round(rnorm(24),1), rep(3,12)), nrow = 12, ncol = 3, byrow = F,
      dimnames = list(month.abb, LETTERS[1:3])
    )
    m[, 2] <- rep(c("A","B","C", "D"), each= 3)
    m[, 3] <- paste0('<input type="radio" name="', rep(c("A","B","C", "D"), each= 3),'" value="', month.abb,'"/>')
    m[c(1,4,7,10), 3] <- gsub('/>', 'checked="checked"/>', m[c(1,4,7,10), 3], fixed = T)
    m
    output$foo = DT::renderDataTable(
      m, escape = FALSE, selection = 'none', server = FALSE,
      options = list(dom = 't', paging = FALSE, ordering = FALSE)
      # callback = JS("table.rows().every(function() {
      #           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());")
    )
    output$test <- renderPrint(str(input$C))
  }
)

更新:

我的最终解决方案的粗略结构,带有反应式按钮选择。重新渲染表格时输入和视觉效果保持不变(只是第一次输入渲染为NULL,这对我来说没有什么特别的问题)。

library(shiny)
library(DT)

shinyApp(
  ui = fluidPage(
    title = "Radio buttons in a table",
    sliderInput("slider_num_rows", "Num Rows", min = 2, max = 12, value = 5),
    tags$div(id = 'placeholder'),
    verbatimTextOutput("test")
  ),
  server = function(input, output, session) {
    rea <- reactive({
      m = matrix(
        c(round(rnorm(24),1), rep(3,12)), nrow = 12, ncol = 3, byrow = F,
        dimnames = list(month.abb, LETTERS[1:3])
      )

      m[, 2] <- rep(c("A","B","C", "D"), each= 3)
      m[, 3] <- paste0('<input type="radio" name="', rep(c("A","B","C", "D"), each= 3),'" value="', month.abb,'"/>')
      save_sel <- c()
      mon_tes <- c("Jan", "Apr", "Jul", "Oct")
      ab <- c("A", "B", "C", "D")
      for (i in 1:4){
        if (is.null(input[[ab[i]]])){
          save_sel[i] <-  mon_tes[i]
        } else {
          save_sel[i] <- input[[ab[i]]]
        }
      }
      sel <- rownames(m) %in% save_sel
      m[sel, 3] <- gsub('/>', 'checked="checked"/>', m[sel, 3], fixed = T)
      m <- m[1:input$slider_num_rows,]
      m
    })

    output$foo = DT::renderDataTable(
      rea(), escape = FALSE, selection = 'none', server = FALSE,
      options = list(dom = 't', paging = FALSE, ordering = FALSE,
                     columnDefs = list(list(className = 'no_select', targets = 3)))
    )

     observe({
      l <- unique(m[, 2])

      for(i in 1:length(l)) {
        if (i == 1) {
          radio_grp <- div(id = l[i], class = "shiny-input-radiogroup", DT::dataTableOutput("foo"))
        } else {
          radio_grp <- div(id = l[i], class = "shiny-input-radiogroup", radio_grp)
        }
      }
      insertUI(selector = '#placeholder',
               ui = radio_grp)
    })
    output$test <- renderPrint( {
      str(input$A)
      str(input$B)
      str(input$C)
      str(input$D)
    })
  }
)

【问题讨论】:

    标签: javascript r shiny dt


    【解决方案1】:

    您可以像这样将div 元素相互嵌套:

      ui = fluidPage(
        title = "Radio buttons in a table",
        div(id = "A", class = "shiny-input-radiogroup",
          div(id = "B", class = "shiny-input-radiogroup",
            div(id = "C", class = "shiny-input-radiogroup",
              div(id = "D", class = "shiny-input-radiogroup", DT::dataTableOutput("foo"))    
            )
          )
        ),
    

    我还修改了renderText 以打印所有值。

    output$test <- renderPrint( {
      str(input$A)
      str(input$B)
      str(input$C)
      str(input$D)
    })
    

    这是与dataTableOutput交互后的结果(选中Feb单选按钮):

    请注意,在交互之前,元素仍将具有 NULL 值。不过,您可以通过 if 语句解决此问题,当输入元素为 NULL 时,使用单选按钮的默认值。

    编辑:您可以使用这样的循环创建divs

    l <- unique(m[, 2])
    
    for(i in 1:length(l)) {
      if (i == 1) {
        radio_grp <- div(id = l[i], class = "shiny-input-radiogroup", DT::dataTableOutput("foo"))
      } else {
        radio_grp <- div(id = l[i], class = "shiny-input-radiogroup", radio_grp) 
      }
    }
    

    【讨论】:

    • 谢谢,这就像一个魅力。但是如果我有 100 个组,嵌套这么多 div 元素是否明智?是否可以动态嵌套这些?
    • 我不认为嵌套一些divs 应该是个问题。至于“动态嵌套”,您可以为此编写一个循环。查看我的编辑。
    • 再次感谢!关于在交互之前具有NULL 值的单选按钮的另一个问题。当它们是NULL 时,我在observe() 中更改了它们的值。但是,如果我进行选择或更改任何内容,导致重新渲染表格的原因,任何按钮中都不会显示任何内容。它们的输入值仍然相同。您知道如何使用默认值以这种方式渲染表格,或者在每次渲染到当前值后相应地更改其视觉输出吗?
    猜你喜欢
    • 2017-09-30
    • 1970-01-01
    • 2013-01-25
    • 2013-06-02
    • 1970-01-01
    • 2011-11-01
    • 2013-06-14
    • 2018-06-25
    • 1970-01-01
    相关资源
    最近更新 更多