在数据表行中渲染numericInputs [英] Render numericInputs in a datatable row

查看:39
本文介绍了在数据表行中渲染numericInputs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想有一个数据表显示基于另一个表的信息,该表的下面是一排numericInputs.我正在尝试使表格中出现numericInput框,以便用户可以输入值,然后在准备好值时按Submit.

I'd like to have a datatable display information based on another table with a single row of numericInputs below it. I'm trying to get the numericInput boxes appear in the table so that a user can type in values, then press submit when they are ready.

在我从 R Shiny selectedInput里面添加numericInput代码之前,这是可行的renderDataTable单元格.但是我收到一条错误消息:

This worked before I added the numericInput code from R Shiny selectedInput inside renderDataTable cells. However I am getting an error message:

Warning: Error in force: argument "value" is missing, with no default
Stack trace (innermost first):
    49: force
    48: restoreInput
    47: FUN
    46: shinyInput [#34]
    45: server [#53]
     4: <Anonymous>
     3: do.call
     2: print.shiny.appobj
     1: <Promise>
Error in force(default) : argument "value" is missing, with no default

ShinyApp可复制的代码:

ShinyApp reproducible code:

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}, options = list(autoWidth = TRUE, 
      scrollX = TRUE, dom = 't', ordering = FALSE),
      rownames = FALSE)

    # helper function for making input number values
    shinyInput <- function(FUN, len, id, ...) {
      inputs <- numeric(len)
      for (i in seq_len(len)) {
        inputs[i] <- as.numeric(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)
    temp_m[2,] <- shinyInput(numericInput, ncol(mtcars),
                             "bin_values")

    output$interface_table <- DT::renderDataTable({
      temp_m
      colnames = names(mtcars)
      rownames = FALSE
      options = list(
        autoWidth = TRUE, scrollX = TRUE, dom = 't', 
        ordering = FALSE)
    })
  }
}

shinyApp(ui, server)    

推荐答案

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

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)

这篇关于在数据表行中渲染numericInputs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆