Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
367 views
in Technique[技术] by (71.8m points)

r - Outputing N tables in shiny, where N depends on the data

I have a shiny app in which I would like to print multiple tables. The catch is, I do not know how many tables I will have in advance - it depends on the data. E.g. if the variable "X" has 5 levels, I want to output 5 tables - one for each level of the variable.

To generate a table, I call a function inside renderTable() in server.R and assign it to an output slot like this:

output$tablePyramid <- renderTable ({
          tableGeneratingFunction(argument1, argument2, ...)
})

If I put more than one "tableGeneratingFunction" inside the renderTable(), it only returns the last table generated. So it seems it's only one table per output slot. I guess I could handle this in the server.R file, assigning dynamically as many output slots as needed.

But I also have to list all outputs in the ui.R file. Example excerpt for two tables:

mainPanel(
tabsetPanel(
... some code

  tabPanel(title="Proportions",
           tableOutput("tablePyramid"),
           tableOutput("tablePyramid2")
           ),
  ... some more code

Do I have to list each table in its own tableOutput function or is there a more elegant way to proceed, since I do not know in advance how many tableOutputs I will need?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I started from the comment with link Dieter made to my question (R Shiny - add tabPanel to tabsetPanel dynamically (with the use of renderUI)). The principle is the same - generate HTML with all the tables in Server.R and then display it with uiOutput() in Ui.R. The difference is, that I could not find a function in shiny package, that would be analogous to the tabPanel(), that generates the HTML in the given example.

But I was able to use xtable() to generate the HTML and passed it some extra arguments for the tables to look like expected in shiny framework when rendered.

Example of a function, that generates HTML for an arbitrary number of tables:

tabelize <- function(variables, arg2, ...) {

  tables <- list() # create a list to hold all tables

  for (variable in variables) { # go through all possible values of variables
    table <- function_that_returns_a_data_frame(variable, arg2, ...)
    tables[[as.character(variable)]] <- 
      # save table into slot in created list
      # print table as HTML with additional formatting options
      print(xtable(table, caption=paste("Variable:", variable)),
            type="html",
            html.table.attributes='class="data table table-bordered table-condensed"',
            caption.placement="top")
  }
  return(lapply(tables, paste)) # return HTML tables pasted together
}

Call this function in Server.R (with some additional options) and assign to an output$ slot:

output$tables <- renderUI({
  out <- tabelize(variables, arg2, ...) 
  # additional options to make rendering possible
  return(div(HTML(out),class="shiny-html-output"))
 })

Do an uiOutput() of it in Ui.R:

    ... code        
    uiOutput("tables")
    ... code

If there's a better way, please comment.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...