File size: 5,187 Bytes
c6a0031
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385c544
c6a0031
 
385c544
c6a0031
 
385c544
c6a0031
385c544
c6a0031
385c544
c6a0031
385c544
c6a0031
 
385c544
c6a0031
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385c544
c6a0031
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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)