Search code examples
rshinyxtable

Shiny renderTable add.to.row


I have a dataframe that could look like this

> df
Product    noPat     Val  Tot TotVal
Product A  -318 -108.12 1356 461.04
Product C   403  544.05  462  623.7
Product D   -32  -39.68  529 655.96
Product B   N/A     N/A  N/A    N/A

I would like to add two multicolumns using the add.to.row argmument in the xtable function.

print(xtable(df, digits=2, caption=strCaption, label="Test_table"), 
      size="footnotesize", #Change size; useful for bigger tables
      include.rownames=FALSE, #Don't print rownames
      caption.placement="top", 
      hline.after=NULL, #We don't need hline; we use booktabs
      add.to.row = list(pos = list(-1, 
                                   nrow(df)),
                        command = c(paste("\\hline \n",
                                          "& \\multicolumn{2}{c}{Growth} & \\multicolumn{2}{c}{Total} \\\\ \n",
                                          "\\hline \n"),
                                    "\\hline \n")
      )
)

Which generates the desired latex output:

\begin{table}[ht]
\centering
\caption{test} 
\label{Test_table}
\begingroup\footnotesize
\begin{tabular}{lllll}
  \hline 
 & \multicolumn{2}{c}{Growth} & \multicolumn{2}{c}{Total} \\ 
 \hline 
Product & noPat & Val & Tot & TotVal \\ 
 Product A & -318 & -108.12 & 1356 & 461.04 \\ 
  Product C & 403 & 544.05 & 462 & 623.7 \\ 
  Product D & -32 & -39.68 & 529 & 655.96 \\ 
  Product B & N/A & N/A & N/A & N/A \\ 
   \hline 
\end{tabular}
\endgroup
\end{table}

Which is the format I want. I would like Shiny to output this, but Shiny just adds the add.to.row argument as text output just above the table.

My implementation in Shiny:

Server.R

output$tabletest <- renderTable({
        rows <<- nrow(df)
        xtable(df, digits=2)

      },

      caption = "Sample Data",
      caption.placement = getOption("xtable.caption.placement", "bottom"), 
      caption.width = getOption("xtable.caption.width", NULL),
      include.rownames=getOption("xtable.include.rownames", FALSE), #Don't print rownames
      add.to.row = getOption("xtable.add.to.row",list(pos = list(-1, 
                                   rows),
                        command = c(paste("\\hline \n",
                                          "& \\multicolumn{2}{c}{Growth} & \\multicolumn{2}{c}{Total} \\\\ \n",
                                          "\\hline \n"),
                                    "\\hline \n")))
      )

UI.R

tableOutput("tabletest")

Using MathJax

As suggested by NicE I tried to use MathJax in the following way

Server.R

output$tabletest<- renderUI({
        result <- withMathJax(HTML(
        "\\begin{table}[ht]
        \\centering
        \\caption{test}
        \\label{Test_table}
        \\begin{tabular}{lllll}
        \\hline
        & \\multicolumn{2}{c}{Growth} & \\multicolumn{2}{c}{Total} \\\\
        \\hline
        Product & noPat & Val & Tot & TotVal \\\\
        Product A & -318 & -108.12 & 1356 & 461.04 \\\\
        Product C & 403 & 544.05 & 462 & 623.7 \\\\
        Product D & -32 & -39.68 & 529 & 655.96 \\\\
        Product B & x & x & x & x \\\\
        \\hline
        \\end{tabular}
        \\end{table}"
        ))
 })

UI.R

              withMathJax(),
              uiOutput("KeyIndicatorsPatients")

But this results in

MathJax output


Solution

  • renderTable will use type="html" to print the xtable, but your add.to.row is Latex so they are not printed.

    You could try transforming your code to HTML, for example:

    output$tabletest <- renderTable({
        xtable(df,digits=2)
      },
      size="footnotesize", #Change size; useful for bigger tables
      include.rownames=FALSE, #Don't print rownames
      caption.placement="top",
      include.colnames=FALSE,
      add.to.row = list(pos = list(0),
                        command = "<tr><th></th><th colspan='2'>Growth</td><th colspan='2'>Total</th></tr>
    <tr> <th> Product </th> <th> noPat </th> <th> Val </th> <th> Tot </th> <th> TotVal </th>  </tr>"
      ))
    

    I added include.colnames=FALSE to your arguments and added them manually in the add.to.row to put them under your other header.

    The result looks like this:

    table example