glow518
glow518

Reputation: 21

Display Crosstab Correctly in Shiny

I want to display a simple crosstab in my Shiny app, but the renderTable function seems to reformat the table. How do I construct the table in renderTable, or is there another way to display my original table?

purchase_by_sex = table(sales$purch_freq, sales$sex)

This gets me the desired output in the console;

                     Female Male
  Once a Week           3    9
  Once a Month          7   11
  Every 2-3 Months      6    8
  < Every 3 Months      5    2
  Never                20   15
  Don't Know            6    8

but gets reformatted in Shiny;

Var1                Var2     Freq
Once a Week         Female    3
Once a Month        Female    7
Every 2-3 Months    Female    6
< Every 3 Months    Female    5
Never               Female    20

ui <- fluidPage( tableOutput("table2") )

server <- function(input, output) {
    output$table2 <- renderTable(purchase_by_sex, striped=TRUE, bordered = TRUE)}

Upvotes: 2

Views: 1682

Answers (1)

Florian
Florian

Reputation: 25405

renderTable() expects as input a data.frame, which the result of table(sales$purch_freq, sales$sex) is not. Try:

class(table(sales$purch_freq, sales$sex))

that returns:

[1] "table".

I think renderTable thus parses the table to a data.frame itself, and indeed we can see that as.data.frame(purchase_by_sex) creates your undesired output:

       Var1   Var2 Freq
1     often female    2
2    rarely female    5
3 sometimes female    1
4     often   male    6
5    rarely   male    4
6 sometimes   male    2

You can use the as.data.frame.matrix(purchase_by_sex) function to convert the table into a data.frame object with the right layout:

          female male
often          2    6
rarely         5    4
sometimes      1    2

and then all we have to do is set rownames=True in renderTable. Hope this helps!


Working example:

library(shiny)

sales = data.frame(sex=sample(c('male','female'),20,TRUE),purch_freq=sample(c('sometimes','often','rarely'),20,TRUE))

purchase_by_sex = table(sales$purch_freq, sales$sex)

ui <- fluidPage(
  tableOutput("table2"),
  tableOutput("table3")

)

# create the server
server <- function( input, output, session ){
  output$table2 <- renderTable( purchase_by_sex, striped=TRUE, bordered = TRUE)
  output$table3 <- renderTable( as.data.frame.matrix(purchase_by_sex), striped=TRUE, bordered = TRUE,rownames = T)

  }


shiny::shinyApp( ui = ui, server = server)

enter image description here

Upvotes: 4

Related Questions