'Why does Rshiny tableOutput create an additional column?

Hi all I'm relatively new to Rshiny and got some unexpected behavior in a simple example of tableOutput.

I'm trying to display a simple table in an Rshiny application but notice there is an additional column created that I did not specify. I'm a little baffled as reproducing the code in 'normal' R does not show this additional column.

My RShiny code:

library(shiny)


ui <- fluidPage(


titlePanel("Test"),
tableOutput("Table1")

)


server <- function(input, output) {

output$Table1 <- renderTable({
matrix1 = matrix(c(2, 3, 5, 8, 13), ncol =1, nrow = 5)
rownames(matrix1) = c('Min', 'value1', 'Max', 'value2', 'Standard deviation')
colnames(matrix1) = c('values')
as.table(matrix1)
})
}


shinyApp(ui = ui, server = server)

This results in the following app where the 'Var2' column is the one I did not expect: RShiny view

I expected the output to be similar of the 'normal' R one: R table Created by this R code:

matrix1 = matrix(c(2, 3, 5, 8, 13), ncol =1, nrow = 5)
rownames(matrix1) = c('Min', 'value1', 'Max', 'value2', 'Standard deviation')
colnames(matrix1) = c('values')
table1 = as.table(matrix1)

Can someone help me understand from where the additional column comes from in the RShiny view and how to get rid of it?

(Ps: I'm new to posting, so please let me know in case I'm unclear/missed something)



Solution 1:[1]

It is a table object, instead wrapped around the matrix, which is really not needed, instead it can be just the matrix object or converted to data.frame

server <- function(input, output) {
  
  output$Table1 <- renderTable({
    matrix1 = matrix(c(2, 3, 5, 8, 13), ncol =1, nrow = 5)
    rownames(matrix1) = c('Min', 'value1', 'Max', 'value2', 'Standard deviation')
    colnames(matrix1) = c('values')
    matrix1
  }, rownames = TRUE)
}
shinyApp(ui = ui, server = server)

-output

enter image description here


When we add as.table, it converts to table class and it gets converted to data.frame during the process and this results in the change of format

> as.table(matrix1)
                   values
Min                     2
value1                  3
Max                     5
value2                  8
Standard deviation     13
> as.data.frame(as.table(matrix1))
                Var1   Var2 Freq
1                Min values    2
2             value1 values    3
3                Max values    5
4             value2 values    8
5 Standard deviation values   13

> str(as.table(matrix1))
 'table' num [1:5, 1] 2 3 5 8 13
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:5] "Min" "value1" "Max" "value2" ...
  ..$ : chr "values"

If we check the source code of renderTable, there is a line which does the as.data.frame and thus it changes the format to three column because there are different methods for as.data.frame depending on the class of the object

> shiny::renderTable
...
classNames <- paste0("table shiny-table", paste0(" table-", 
            names(format)[format], collapse = ""), paste0(" spacing-", 
            spacing))
data <- as.data.frame(data)
...

Also, check methods for as.data.frame

> methods(as.data.frame)
 [1] as.data.frame.aovproj*            as.data.frame.array               as.data.frame.AsIs                as.data.frame.character          
 [5] as.data.frame.complex             as.data.frame.data.frame          as.data.frame.data.table*         as.data.frame.Date               
 [9] as.data.frame.default             as.data.frame.descr*              as.data.frame.difftime            as.data.frame.EventHistory.frame*
[13] as.data.frame.factor              as.data.frame.ftable*             as.data.frame.function*           as.data.frame.grouped_df*        
[17] as.data.frame.groupedData*        as.data.frame.idf*                as.data.frame.integer             as.data.frame.ITime*             
[21] as.data.frame.list                as.data.frame.logical             as.data.frame.logLik*             as.data.frame.mapped_discrete*   
[25] as.data.frame.matrix              as.data.frame.model.matrix        as.data.frame.noquote             as.data.frame.numeric            
[29] as.data.frame.numeric_version     as.data.frame.ordered             as.data.frame.POSIXct             as.data.frame.POSIXlt            
[33] as.data.frame.raw                 as.data.frame.resamples*          as.data.frame.shingle*            as.data.frame.Surv*              
[37] as.data.frame.Surv2*              as.data.frame.table    #####           as.data.frame.tbl_df*             as.data.frame.timeDate*          
[41] as.data.frame.ts                  as.data.frame.vctrs_sclr*         as.data.frame.vctrs_vctr*         as.data.frame.vector             
[45] as.data.frame.xyVector*          
see '?methods' for accessing help and source code

The source code of as.data.frame.table does create three columns

> as.data.frame.table
function (x, row.names = NULL, ..., responseName = "Freq", stringsAsFactors = TRUE, 
    sep = "", base = list(LETTERS)) 
{
    ex <- quote(data.frame(do.call("expand.grid", c(dimnames(provideDimnames(x, 
        sep = sep, base = base)), KEEP.OUT.ATTRS = FALSE, stringsAsFactors = stringsAsFactors)), 
        Freq = c(x), row.names = row.names))
    names(ex)[3L] <- responseName
    eval(ex)
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1