R_CrossTab / app.R
PichMixT's picture
Update app.R
385c544 verified
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)