R shiny: how to create a matrix with numericInput

2020-06-23 08:55发布

I would like to create a matrix in which one could insert numeric values. Also, I would like that the number of rows visible depend on an actionButton. The following code herebelow works fine as long as I've got NAs in my matrix, but not if I replace the NA by some numericInput.

Here is the ui.R:

shinyUI(
pageWithSidebar(
headerPanel("test"),
sidebarPanel(
actionButtonGreen("test","add a row")),
mainPanel(
uiOutput("value"))
)
) 

And here is the server.R:

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"))                    
})})

} )

Any advice would be greatly appreciated.

Cheers

标签: r shiny
2条回答
家丑人穷心不美
2楼-- · 2020-06-23 09:26

I wrote these functions to do the same thing. Hope this helps.

 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="")) 
                                                      }
  }
查看更多
ゆ 、 Hurt°
3楼-- · 2020-06-23 09:33

This is what you are trying to insert into your matrix (the value of numericInput(inputId="1",label="",value="2")) :

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

and this is his structure, it's a list of 2 lists with 3 elements :

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"

Your problem is that the function numericInput returns something that cant fit into you matrix.

Then I suggest you to use directly the html tag in a data frame, and with the sanitize.text.function function to evaluate the HTML tags as is (and not as strings).

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)
      })
    })
  }
))
查看更多
登录 后发表回答