Shiny:如何在renderTable中控制rownames()的宽度?

时间:2016-12-22 12:52:52

标签: r shiny

下面的代码生成一个包含3行和3列的输入表(以简化情况 - 见下图)。根据输入,我需要在输入表下方生成9个直方图,重要的是直方图应与输入框垂直对齐。目前情况并非如此。

我正在考虑的一个选项是在包含图之前使用偏移量1。为了确保绘图是对齐的,输入的rownames(alt1,alt2,a3)应该以这样的方式出现,即它们恰好占据1列以匹配偏移量。默认情况下,renderTable似乎使用自动调整。我在网上搜索但找不到控制rownames宽度的方法。

有人可以帮忙吗?任何投入将不胜感激。非常感谢。

library(shiny)
library(grid)
library(gridBase)

u <- shinyUI(navbarPage(
"My Application",
tabPanel("Component 1",
       fluidPage(

         fluidRow(column(6,
          tableOutput('decision_Matrix'),offset=0)       
         ),
         fluidRow(column(5,
           plotOutput('decision_Matrix_plots')
           ,offset=1)       
         )
       )),
tabPanel("Component 2")
))

s <- shinyServer(

function(input,output) {

  output$decision_Matrix <- renderTable({

        matrix_input <- matrix(data = NA,nrow = 3,ncol = 3)
  for (j in 1:3) {
    for (i in 1:3) {
      matrix_input[i,j] <- paste0("<input id='C",j,"_A",i,"' type='number' class='form-control shiny-bound-input'  value='",input[[paste0("C",j,"_A",i)]],"'>")
    }
  }

  rownames(matrix_input) <- c("alt1","alt2","a3")

  colnames(matrix_input) <- c("crit1","crit2","t3")

  matrix_input
},include.rownames = TRUE,sanitize.text.function = function(x) x)

output$decision_Matrix_plots <- renderPlot({    

  layout(matrix(c(1,2,3,4,5,6,7,8,9),nrow = 3,ncol = 3))
  for (j in 1:3) {
    for (i in 1:3) {
      set.seed(123)
      n <- input[[paste0("C",j,"_A",i)]]
      if (is.null(n) || is.na(n) || n < 1) n <- 1
      hist(rnorm(n),breaks = 10,main=sprintf("histogram of rnorm( %d )",n))
    }
  }
  recordPlot()
})

})
shinyApp(ui = u,server = s)

enter image description here

2 个答案:

答案 0 :(得分:1)

就像你说的rownames搞乱了你的对齐。使用fluidRow和列Shiny正在使用Bootstrap。对于基本原则,fluidRow和column会查看http://www.w3schools.com/bootstrap/bootstrap_grid_basic.asp

垂直对齐的解决方案是将您的rownames放在单独的列中。以下更改可修复垂直对齐。

    ...
                     fluidRow(column(1,
                                     tableOutput('m_rownames'),offset=0, align="left"),
                             column(5,
                                tableOutput('decision_Matrix'),offset=0, align="right")
                     ),
                     fluidRow(column(5,
                                     plotOutput('decision_Matrix_plots')
                                     ,offset=1, align="right")
                     )
    ....

            },include.rownames = FALSE,sanitize.text.function = function(x) x)
            output$m_rownames <- renderTable({ c("alt1","alt2","a3") })

这会将您的rownames放在一个宽度为1的单独列中,并且您的矩阵和图每个都放在5个相应的列中。然而,这会弄乱你的rownames和矩阵的水平对齐。我稍后可能会有一点时间看这个,但是现在我会留给你调整它。

这是结果 enter image description here

答案 1 :(得分:1)

就对齐而言,最好的选择是制作3列。每个包含3个输入和3个相应的输出。第一列显示其他人没有的rownames。这需要进行一些重组,因为第一栏与其他栏不同,所以并不完美。这里有一些代码

    ...
    fluidRow(
           column(4,
                 tableOutput('decision_MatrixC1'),offset=0),
           column(4,
                 tableOutput('decision_MatrixC2'),offset=0),
           column(4,
                 tableOutput('decision_MatrixC3'),offset=0)
    ),
    fluidRow(
           column(3,
                 plotOutput('decision_Matrix_plotsC1')
                                     ,offset=1),
           column(4,
                 plotOutput('decision_Matrix_plotsC2')
                                    ,offset=0),
           column(4,
                 plotOutput('decision_Matrix_plotsC3')
                                   ,offset=0)
     )
     ....
     output$decision_MatrixC1 <- renderTable({                        
             matrix_input <- matrix(data = NA,nrow = 3,ncol = 1)
             for (j in 1:1) {
                    for (i in 1:3) {
                              matrix_input[i,j] <- paste0("<input id='C",j,"_A",i,"' type='number' class='form-control shiny-bound-input'  value='",input[[paste0("C",j,"_A",i)]],"'>")
                     }}                        
             rownames(matrix_input) <- c("alt1","alt2","a3")                        
             colnames(matrix_input) <- c("crit1")

             matrix_input
            },include.rownames = TRUE,sanitize.text.function = function(x) x)

            output$decision_MatrixC2 <- renderTable({
                    matrix_input <- matrix(data = NA,nrow = 3,ncol = 1)
                    for (j in 1:1) {
                            for (i in 1:3) {
                                    matrix_input[i,j] <- paste0("<input id='C",j+1,"_A",i,"' type='number' class='form-control shiny-bound-input'  value='",input[[paste0("C",j+1,"_A",i)]],"'>")
                            }}                        
                    rownames(matrix_input) <- c("alt1","alt2","a3")
                    colnames(matrix_input) <- c("crit2")
                    matrix_input
            },include.rownames = FALSE,sanitize.text.function = function(x) x)

第三列情节几乎相同。显然这段代码需要进行一些清理,但我希望尽可能保持代码尽可能接近。您可以以类似的方式按行组织它,而不是像这样在列中组织它。结果是

enter image description here