LTR
LTR

Reputation: 31

R Shiny output dynamic number of tables

I am writing a Shiny app to create a row containing a table for each variable in a dataset. The number of variables will change from use to use, and ideally the app will output as many rows and tables as there are variables. My current code is creating the correct number of rows and text, but is repeating the table data for the last table for all rows. I believe that the storing of table outputs in output[[tablename]] may not be in the right place to create separately stored tables. The next step will be to add a reactive input to filter the rows shown by vardata$category.

Code here includes data example:

library(shiny)    
variable <- c("Q17r01", "Q17r01", "Q17r01", "Q22r03", "Q22r03", "Q22r03", "Q15r01", "Q15r01", "Q15r01", "S03", "S03", "vAge", "vAge", "vAge", "vAge", "vAge", "vAge")
    responses <- c("A_T", "B_M", "C_B", "A_T", "B_M", "C_B", "A_T", "B_M", "C_B", "Female", "Male", "13 - 17", "18 - 24", "25 - 34", "35 - 44", "45 - 54", "55+")
    grp1 <- c(33, 39, 28, 27, 20, 53, 88, 7, 5, 51, 49, 27, 8, 33, 14, 16, 2)
    grp2 <- c(42, 46, 12,41, 45, 13, 64, 32, 4, 44, 56, 9, 22, 39, 13, 12, 4)
    xAgg <- c(32, 49, 19, 26, 48, 26, 51, 38, 11, 45, 55, 12, 16, 30, 17, 14, 11)
    chartdata <- data.frame(variable,responses,grp1,grp2,xAgg,row.names=NULL)

    profvars <- unique(variable)
    varlabel <- c("Q17r01_I_am_overwhelmed_by_the_number_of_apps_available_for_download", "Q22r03_I_feel_overwhelmed_by_the_number_of_digital_communications_I_receive",
                  "Q15r01_When_I_receive_a_message_online_I_tend_to_respond_right_away", "S03_Please_indicate_your_gender", "vAge_Age_breakdown")
    category <- c("a_Causes_of_Stress", "a_Causes_of_Stress", "a_Communication_Availability", "zz_Demo", "zz_Demo")
    vardata <- data.frame(profvars,varlabel,category,row.names=NULL)

    chartdatasplit <- split(chartdata, chartdata$variable)


    server <- function(input, output) {

    assigntables <- reactive({
      for (vars in profvars){
        local({
          var <- vars
          tablename <- paste0("table.",var)
          assign("tabledata",chartdatasplit[[var]],pos=1)  
          output[[tablename]] <- renderTable({tabledata}) ###appears this is only being done for last table
        })
      }
    })

      output$AllVars <- renderUI({
        ##for (i_var in 1:nrow(vardata)) {
        assigntables()
        return(apply(vardata,1,function(vars){
          fluidRow(column(12,offset=1,
            tableOutput(paste("table.",vars['profvars'],sep=''))),
            hr()
          )
        }))
      })
    }

    ui <- navbarPage("Seg Run",
                     tabPanel("Summary",
                              uiOutput("AllVars")
                     )
    )

    shinyApp(ui = ui, server = server)

Upvotes: 1

Views: 2106

Answers (1)

LTR
LTR

Reputation: 31

Here we go:

library(shiny)
library(xtable)

variable <- c("Q17r01", "Q17r01", "Q17r01", "Q22r03", "Q22r03", "Q22r03", "Q15r01", "Q15r01", "Q15r01", "S03", "S03", "vAge", "vAge", "vAge", "vAge", "vAge", "vAge")
responses <- c("A_T", "B_M", "C_B", "A_T", "B_M", "C_B", "A_T", "B_M", "C_B", "Female", "Male", "13 - 17", "18 - 24", "25 - 34", "35 - 44", "45 - 54", "55+")
grp1 <- c(33, 39, 28, 27, 20, 53, 88, 7, 5, 51, 49, 27, 8, 33, 14, 16, 2)
grp2 <- c(42, 46, 12,41, 45, 13, 64, 32, 4, 44, 56, 9, 22, 39, 13, 12, 4)
xAgg <- c(32, 49, 19, 26, 48, 26, 51, 38, 11, 45, 55, 12, 16, 30, 17, 14, 11)
chartdata <- data.frame(variable,responses,grp1,grp2,xAgg,row.names=NULL)

profvars <- unique(variable)
varlabel <- c("Q17r01_I_am_overwhelmed_by_the_number_of_apps_available_for_download", "Q22r03_I_feel_overwhelmed_by_the_number_of_digital_communications_I_receive",
              "Q15r01_When_I_receive_a_message_online_I_tend_to_respond_right_away", "S03_Please_indicate_your_gender", "vAge_Age_breakdown")
category <- c("a_Causes_of_Stress", "a_Causes_of_Stress", "a_Communication_Availability", "zz_Demo", "zz_Demo")
vardata <- data.frame(profvars,varlabel,category,row.names=NULL)

chartdatasplit <- split(chartdata, chartdata$variable)


server <- function(input, output) {

  tableize <- function(chartdatasplit){  ###can add additional arguments like dimension - add to where this is called also and how tabledata indexes
    tables <- list()
    for (x in names(chartdatasplit)){ ##go through all individually stored variable data frames in chartdatasplit list
      tabledata <- chartdatasplit[[x]]  ###function that returns a dataframe to use in table
      tables[[as.character(x)]] <- 
        print(xtable(tabledata, caption=paste("Variable:",x)),
           type="html", include.rownames = FALSE,
           html.table.attributes='class="data table table-bordered table-condensed"',
           caption.placement="top")
    }
    return(lapply(tables,paste))    
  }

  output$tables <- renderUI({
    out <- unlist(tableize(chartdatasplit))
      return(div(HTML(out),class="shiny-html-output"))
  })
} 

ui <- shinyUI(fluidPage(

  uiOutput("tables")
))


shinyApp(ui = ui, server = server)

Upvotes: 2

Related Questions