Reputation: 303
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 tableOutput
s I will need?
Upvotes: 3
Views: 3032
Reputation: 303
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.
Upvotes: 4