R Shiny:如何创建以numericInput作为元素的矩阵

R shiny: how to create a matrix with numericInput as elements

我想创建一个可以在其中插入数值的矩阵。另外,我希望可见的行数取决于actionButton。只要我的矩阵中有NA,下面的以下代码就可以正常工作,但是如果我用某些numericInput代替NA,则下面的代码就可以正常工作。

这是ui.R:

1
2
3
4
5
6
7
8
9
shinyUI(
pageWithSidebar(
headerPanel("test"),
sidebarPanel(
actionButtonGreen("test","add a row")),
mainPanel(
uiOutput("value"))
)
)

这是服务器。R:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
shinyServer(function(input,output){

observe({
if (input$test == 0)
return()
isolate({
output$value <-renderTable(
mdat <- matrix(NA, nrow = input$test, ncol = 2, byrow = TRUE)
)
##If I change the NAs to a vector of numericInput, I obtain the following error
##Error: number of items to replace is not a multiple of replacement length
##That's when I replace the NA in the above matrix with
##c(numericInput(inputId="1",label="",value="2"),
##  numericInput(inputId="2",label="",value="2"),
##  numericInput(inputId="3",label="",value="2"),
##  numericInput(inputId="4",label="",value="2"))                    
})})

}
)

任何建议将不胜感激。

干杯


这是您要插入矩阵(numericInput(inputId="1",label="",value="2")的值)的内容:

1
2
3
4
[1]"<label for="1"></label>\
<input id="1" type="number" value="2"/>"
attr(,"html")
[1] TRUE

这是他的结构,它是包含3个元素的2个列表的列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List of 2
 $ :List of 3
  ..$ name    : chr"label"
  ..$ attribs :List of 1
  .. ..$ for: chr"1"
  ..$ children:List of 1
  .. ..$ : chr""
  ..- attr(*,"class")= chr"shiny.tag"
 $ :List of 3
  ..$ name    : chr"input"
  ..$ attribs :List of 3
  .. ..$ id   : chr"1"
  .. ..$ type : chr"number"
  .. ..$ value: chr"2"
  ..$ children: list()
  ..- attr(*,"class")= chr"shiny.tag"
 - attr(*,"class")= chr [1:2]"shiny.tag.list""list"

您的问题是函数numericInput返回的内容无法适合您的矩阵。

然后,我建议您直接在数据框中使用html标记,并使用sanitize.text.function函数按原样(而不是字符串)评估HTML标记。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
shiny::runApp(list(
  ui = pageWithSidebar(
      headerPanel("test"),
      sidebarPanel(
        actionButton("test","add a row")),
      mainPanel(
        tableOutput("value"))
  ),  
  server = function(input,output){
    observe({
      if (input$test == 0)
        return()
      isolate({
        output$value <-renderTable({
          num.inputs.col1 <- paste0("<input id='c1n", 1:input$test,"' class='shiny-bound-input' type='number' value='2'>")
          num.inputs.col2 <- paste0("<input id='c2n", 1:input$test,"' class='shiny-bound-input' type='number' value='2'>")
          data.frame(num.inputs.col1, num.inputs.col2)
        }, sanitize.text.function = function(x) x)
      })
    })
  }
))


我写了这些功能来做同样的事情。希望这会有所帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
 columm    <- function(x,checkval) { if (is.na(checkval)) {
                                                      return(paste('<td>',x,'</td>', sep=""))
                                                      } else {
                                                      return(paste('<td style="background-color:lightblue;">',x,'</td>', sep=""))
                                                      }
                            }
num_input <- function(id,checkval,default){  if (!is.na(checkval)) {
                                                      return(default)
                                                      } else {
                                                      return(paste("<input id='",id,"' type='number' value=",default,
                                                            " class='myInputstyle'>",sep=""))
                                                      }
  }