library(shiny) library(DT) library(readxl) library(haven) library(openxlsx) library(expss) library(dplyr) ui <- fluidPage( titlePanel("Shiny App: Cross Tabulation"), sidebarLayout( sidebarPanel( fileInput("file", "Upload File (CSV, XLSX, SAV)", accept = c(".csv", ".xlsx", ".sav")), # Input for R script textAreaInput( "r_script", label = "Write R Script to Modify Data:", #value = "data$New_Column <- data$Score * 2", # Example default script rows = 10, placeholder = "Write R code here to modify the dataframe, example: data$New_Column <- data$Score * 2" ), actionButton("apply_script", "Apply Script"), br(), # Select the data source for the crosstab selectInput("data_source", "Select Data Source for Crosstab", choices = c("Original Data" = "original", "Modified Data" = "modified")), # Crosstab selections selectInput("col_vars", "Select Column Variables", choices = NULL, multiple = TRUE), selectInput("row_vars", "Select Row Variables", choices = NULL, multiple = TRUE), selectInput("crosstab_type", "Crosstab Type", choices = c("Absolute Values", "Percentage", "Mean Score")), actionButton("generate_crosstab", "Generate Crosstab"), # Download Crosstab downloadButton("download_crosstab", "Download Crosstab") ), mainPanel( tabsetPanel( tabPanel("Original Data", DTOutput("original_data_table")), tabPanel("Modified Data", DTOutput("modified_data_table")), tabPanel("Crosstab Output", DTOutput("crosstab_table")) ) ) ) ) server <- function(input, output, session) { # Reactive values for data original_data <- reactiveVal(NULL) modified_data <- reactiveVal(NULL) # Load original data observeEvent(input$file, { req(input$file) file_ext <- tools::file_ext(input$file$name) if (file_ext == "csv") { df <- read.csv(input$file$datapath) } else if (file_ext == "xlsx") { df <- read_excel(input$file$datapath) } else if (file_ext == "sav") { df <- haven::read_sav(input$file$datapath) for (var in names(df)) { var_lab(df[[var]]) <- var_lab(df[[var]]) # Keep variable labels } } else { showNotification("Unsupported file format!", type = "error") return() } original_data(df) # Display the original data in the Original Data tab output$original_data_table <- renderDT({ datatable(original_data(), options = list(pageLength = 10, scrollX = TRUE)) }) # Update dropdown variabel updateSelectInput(session, "col_vars", choices = names(df)) updateSelectInput(session, "row_vars", choices = names(df)) showNotification("Original data loaded successfully!", type = "message") }) # Apply R script to modify data observeEvent(input$apply_script, { req(input$r_script) req(original_data()) # Ensure that the original data has been loaded tryCatch({ # Take the original data df <- original_data() # Evaluate the script in a specific environment env <- new.env() env$data <- df # The original data is stored in the evaluation environment eval(parse(text = input$r_script), envir = env) # Evaluate the script # Take the modification results from the environment modified_data(env$data) # Display the modified data in the Modified Data tab output$modified_data_table <- renderDT({ datatable(modified_data(), options = list(pageLength = 10, scrollX = TRUE)) }) showNotification("Script applied successfully!", type = "message") }, error = function(e) { showNotification(paste("Error in script:", e$message), type = "error") }) }) # Generate Crosstab crosstab <- eventReactive(input$generate_crosstab, { req(input$col_vars, input$row_vars) # Select data based on the selected source df <- if (input$data_source == "original") { original_data() } else { modified_data() } # Prepare row and column variables row_result <- df %>% select(all_of(input$row_vars)) column_result <- df %>% select(all_of(input$col_vars)) # Crosstab calculation based on type if (input$crosstab_type == "Absolute Values") { cro_cases(row_result, list(total(), column_result)) } else if (input$crosstab_type == "Percentage") { cro_cpct(row_result, list(total(), column_result)) } else { cro_mean_sd_n(row_result, list(total(), column_result)) } }) # Render Crosstab output$crosstab_table <- renderDT({ req(crosstab()) datatable(crosstab(), options = list(pageLength = 10, scrollX = TRUE)) }) # Download Crosstab output$download_crosstab <- downloadHandler( filename = function() { paste("crosstab-", Sys.Date(), ".xlsx", sep = "") }, content = function(file) { wb <- createWorkbook() sh1 <- addWorksheet(wb, "Crosstab") xl_write(crosstab(), wb, sh1) saveWorkbook(wb, file, overwrite = TRUE) } ) } shinyApp(ui, server)