且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在数据表行中渲染numericInputs

更新时间:2023-12-01 20:05:40

您尝试采用的解决方案可能存在一些误解.

There might have been some misunderstandings with the solution you were trying to adapt.

起初,您遇到的错误是微不足道的,但是以某种方式被包装器函数掩盖了.标记 numericInput 需要一个参数 value ,这不是可选的.您没有在调用 shinyInput 的过程中提供它.(它是您引用的 ... 的一部分.)

At first, the error you got was kind of trivial, but somehow masked by the wrapper functions. The tag numericInput needs an argument value, which is not optional. You don't provide it in your call to shinyInput. (It is part of the ... you reference.)

更正此错误

Error : (list) object cannot be coerced to type 'double'

这是因为要在 shinyInput 内部将其转换为数字.您在这里误解了您链接的帖子. shinyInput 的作用是:它创建了许多特定于光泽的Web元素,您又希望将它们打包到表中.但是,由于这些网络元素不仅仅是HTML(包括依赖项),因此您希望将其转换为纯HTML.这就是为什么在链接的帖子中,作者使用 as.character .这与您希望小部件提供的输入类型无关.因此, as.numeric 在这里是错误的.

This is because, inside shinyInput you want to convert to numeric. Here you misinterpreted the post you linked. What shinyInput does is: it creates a number of shiny-specific web elements, which you in turn want to pack into your table. But, since those web elements are more than just HTML (including i.e. dependencies), you want to convert them down to just plain HTML. This is why in the linked post, the author used as.character. This has nothing to do with the kind of input you expect the widgets to deliver. So, as.numeric is wrong here.

由于我们要向 data.frame 中添加HTML,因此我们将要包含在 renderDataTable 中,因此我们必须指定 escape = FALSE ,这样我们的HTML实际上就被解释为HTML,而不会转换为无聊的文本.(还纠正了此调用中的某些语法.)

Since we are adding HTML to the data.frame, we are about to include in a renderDataTable, we have to specify escape = FALSE, so that our HTML is actually interpreted as HTML and not converted to boring text. (Corrected some syntax in this call as well.)

现在您至少可以正确显示输入字段.

Now you got at least your input fields showing correctly.

library(shiny)
library(DT)

data(mtcars)

if (interactive()) {
  ui <- fluidPage(
    sidebarLayout(
      sidebarPanel(
        fluidRow(
          column(6, checkboxGroupInput("dsnamesGrp", "Variable name")),
          column(6, uiOutput("dsordsGrp"), inline= FALSE)
        )
      ),
      mainPanel(
        tabsetPanel(
          tabPanel("contents", DT::dataTableOutput('contents')),
          tabPanel("binnedtable", DT::dataTableOutput('binnedtable'))
        ),
        DT::dataTableOutput('interface_table'),
        actionButton("do", "Apply")
      )
    )
  )

  server <- function(input, output, session) {
    output$contents <- DT::renderDataTable(mtcars, 
      rownames = FALSE,
      options = list(
        autoWidth = TRUE,
        scrollX = TRUE,
        dom = 't',
        ordering = FALSE
      )
    )

    # helper function for making input number values
    shinyInput <- function(FUN, len, id, ...) {
      inputs <- numeric(len)
      for (i in seq_len(len)) {
        # as.character to make a string of HTML
        inputs[i] <- as.character(FUN(paste0(id, i), label = NULL, ...))
      }
      inputs
    }

    # helper function for reading numeric inputs
    shinyValue <- function(id, len) {
      unlist(lapply(seq_len(len), function(i) {
        value <- input[[paste0(id, i)]]
        if (is.null(value)) NA else value
      }))
    }

    temp_m <- matrix(data = NA, nrow = 2, ncol = length(names(mtcars)))
    colnames(temp_m) <- names(mtcars)
    rownames(temp_m) <- c("Ordinality","Bins")
    temp_m[1,] <- lengths(lapply(mtcars, unique))
    bin_value <- list() #tags$input(bin_value)

    # Since numericInput needs a value parameter, add this here!
    temp_m[2,] <- shinyInput(numericInput, ncol(mtcars), "bin_values", value = NULL)

    output$interface_table <- DT::renderDataTable(temp_m,
      colnames = names(mtcars),
      rownames = FALSE,
      # Important, so this is not just text, but HTML elements.
      escape = FALSE,
      options = list(
        autoWidth = TRUE, scrollX = TRUE, dom = 't', 
        ordering = FALSE)
    )
  }
}

shinyApp(ui, server)