pbriss7 commited on
Commit
f27e965
·
verified ·
1 Parent(s): 735bd62

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +288 -49
app.R CHANGED
@@ -1,58 +1,297 @@
1
  library(shiny)
2
- library(bslib)
3
- library(dplyr)
4
- library(ggplot2)
5
-
6
- df <- readr::read_csv("penguins.csv")
7
- # Find subset of columns that are suitable for scatter plot
8
- df_num <- df |> select(where(is.numeric), -Year)
9
-
10
- ui <- page_sidebar(
11
- theme = bs_theme(bootswatch = "minty"),
12
- title = "Penguins explorer",
13
- sidebar = sidebar(
14
- varSelectInput("xvar", "X variable", df_num, selected = "Bill Length (mm)"),
15
- varSelectInput("yvar", "Y variable", df_num, selected = "Bill Depth (mm)"),
16
- checkboxGroupInput("species", "Filter by species",
17
- choices = unique(df$Species), selected = unique(df$Species)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  ),
19
- hr(), # Add a horizontal rule
20
- checkboxInput("by_species", "Show species", TRUE),
21
- checkboxInput("show_margins", "Show marginal plots", TRUE),
22
- checkboxInput("smooth", "Add smoother"),
23
- ),
24
- plotOutput("scatter")
 
25
  )
26
 
27
- server <- function(input, output, session) {
28
- subsetted <- reactive({
29
- req(input$species)
30
- df |> filter(Species %in% input$species)
31
- })
32
-
33
- output$scatter <- renderPlot(
34
- {
35
- p <- ggplot(subsetted(), aes(!!input$xvar, !!input$yvar)) +
36
- theme_light() +
37
- list(
38
- theme(legend.position = "bottom"),
39
- if (input$by_species) aes(color = Species),
40
- geom_point(),
41
- if (input$smooth) geom_smooth()
42
- )
43
-
44
- if (input$show_margins) {
45
- margin_type <- if (input$by_species) "density" else "histogram"
46
- p <- p |> ggExtra::ggMarginal(
47
- type = margin_type, margins = "both",
48
- size = 8, groupColour = input$by_species, groupFill = input$by_species
49
- )
50
- }
51
 
52
- p
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  },
54
- res = 100
 
 
55
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  }
57
 
58
- shinyApp(ui, server)
 
 
1
  library(shiny)
2
+ library(DT)
3
+ library(shinyWidgets)
4
+ library(data.table)
5
+ library(stringr)
6
+ library(markdown)
7
+
8
+ data <- readRDS("donnees_nettes/dolq_min.RDS") |> setDT()
9
+
10
+ readme_content <- readLines("README.md", warn = FALSE)
11
+
12
+ source("Fonctions.R")
13
+
14
+ ui <- fluidPage(
15
+ titlePanel("Dictionnaire des oeuvres littéraires du Québec, t. 1-6"),
16
+ tabsetPanel(
17
+ tabPanel("Recherche plein texte",
18
+ sidebarLayout(
19
+ sidebarPanel(
20
+ noUiSliderInput(inputId = "date_range",
21
+ label = "Sélectionner une période:",
22
+ min = 1830,
23
+ max = 1980,
24
+ value = c(1830, 1980),
25
+ format = wNumbFormat(decimals = 0),
26
+ tooltips = TRUE),
27
+ br(),
28
+
29
+ pickerInput(
30
+ inputId = "column",
31
+ label = h5("Choisissez les colonnes où effectuer la recherche:"),
32
+ choices = c("Auteur_oeuvre", "Titre", "Auteur_notice", "Article",
33
+ "Depouillement", "Details_bibliographiques"),
34
+ selected = "Article",
35
+ options = list(`actions-box` = TRUE),
36
+ multiple = TRUE
37
+ ),
38
+ pickerInput(
39
+ inputId = "additional_columns",
40
+ label = h5("Choisissez les colonnes à afficher:"),
41
+ choices = c("Id", "Auteur_oeuvre", "Titre", "Annee_parution", "Auteur_notice", "Article", "Volume", "Depouillement", "Details_bibliographiques"),
42
+ selected = c("Auteur_oeuvre", "Titre", "Article"),
43
+ options = list(`actions-box` = TRUE),
44
+ multiple = TRUE
45
+ ),
46
+ textInput(
47
+ inputId = "motcle",
48
+ label = h5("Chaine de caractères à rechercher"),
49
+ value = "Montréal"
50
+ ),
51
+ prettySwitch(
52
+ inputId = "regex",
53
+ label = "Utiliser une expression régulière?",
54
+ fill = FALSE,
55
+ status = "primary"
56
+ ),
57
+ downloadButton("downloadData", "Exporter le résultat de la table (csv)"),
58
+ width = 4,
59
+ hr(),
60
+
61
+ tags$head(tags$link(rel = "stylesheet", href = "https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css")),
62
+
63
+
64
+ h5("Antisèche - expressions régulières"),
65
+ tags$a(href = "regex.pdf", target = "_blank",
66
+ tags$img(src = "regex.jpg", alt = "Thumbnail", width = "100%")),
67
+
68
+ hr(),
69
+ h5("Accéder aux volumes (pdf)"),
70
+ # Add clickable images for each volume
71
+ tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-1-des-origines-a-1900/", target = "_blank",
72
+ tags$img(src = "DOLQ_01.jpg", alt = "Volume 1", width = "50%")),
73
+ tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-2-1900-a-1939/", target = "_blank",
74
+ tags$img(src = "DOLQ_02.jpg", alt = "Volume 2", width = "50%")),
75
+ tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-3-1940-a-1959/", target = "_blank",
76
+ tags$img(src = "DOLQ_03.jpg", alt = "Volume 3", width = "50%")),
77
+ tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-4-1960-1969/", target = "_blank",
78
+ tags$img(src = "DOLQ_04.jpg", alt = "Volume 4", width = "50%")),
79
+ tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-5-1970-1975/", target = "_blank",
80
+ tags$img(src = "DOLQ_05.jpg", alt = "Volume 5", width = "50%")),
81
+ tags$a(href = "https://crilcq.org/dictionnaire-des-oeuvres-litteraires-du-quebec-tome-5-1970-1975/", target = "_blank",
82
+ tags$img(src = "DOLQ_06.jpg", alt = "Volume 6", width = "50%")),
83
+ ),
84
+
85
+ mainPanel(h3("Distribution chronologique des notices"),
86
+
87
+ radioButtons(inputId = "dist_type",
88
+ label = "Type de distribution:",
89
+ choices = list("Distribution brute" = "raw",
90
+ "Distribution relative" = "relative"),
91
+ selected = "raw"),
92
+
93
+ numericInput("num_breaks", label = "Nombre d'intervalles:", value = 65, min = 1),
94
+
95
+ plotOutput("histogram"),
96
+
97
+ downloadButton("download_graph", "Exporter le graphique"),
98
+ downloadButton("download_table", "Exporter les données du graphique"),
99
+
100
+ h3("Table"),
101
+ textOutput("filtered_count"),
102
+ DT::dataTableOutput('table'))
103
+ )
104
  ),
105
+
106
+ # Second tab: Documentation
107
+
108
+ tabPanel("Documentation",
109
+ uiOutput("readme")
110
+ )
111
+ )
112
  )
113
 
114
+ server <- function(input, output) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
+ reactive_data <- reactive({
117
+ filter_data(data, input, input$additional_columns)
118
+ })
119
+
120
+ reactive_data1 <- reactive({
121
+ filter_data(data, input)
122
+ })
123
+
124
+ filtered_count <- reactive({
125
+ nrow(reactive_data())
126
+ })
127
+
128
+ hist_data <- reactive({
129
+ if ("Annee_unique" %in% names(reactive_data1()) && nrow(reactive_data1()) > 0) {
130
+ # Ensure the data is numeric
131
+ data_numeric <- as.numeric(reactive_data1()[, Annee_unique])
132
+
133
+ # Remove NA values
134
+ data_numeric <- na.omit(data_numeric)
135
+
136
+ if (length(data_numeric) > 0) {
137
+ min_year <- min(data_numeric)
138
+ max_year <- max(data_numeric)
139
+ breaks_hist <- seq(min_year, max_year, length.out = input$num_breaks + 1)
140
+
141
+ # Raw counts
142
+ raw_counts <- hist(data_numeric, plot=FALSE, breaks=breaks_hist)$counts
143
+
144
+ # Relative counts
145
+ total_counts <- hist(data[data$Annee_unique %in% reactive_data1()[, Annee_unique], Annee_unique], plot=FALSE, breaks=breaks_hist)$counts
146
+
147
+ relative_counts <- ifelse(total_counts == 0, 0, raw_counts / total_counts)
148
+
149
+ breaks <- round(seq(min_year, max_year, length.out = length(raw_counts)))
150
+
151
+ # Return data based on user's selection
152
+ if (input$dist_type == "raw") {
153
+ return(data.frame(Breaks = breaks, Counts = raw_counts))
154
+ } else {
155
+ return(data.frame(Breaks = breaks, RelativeCounts = relative_counts))
156
+ }
157
+ }
158
+ }
159
+ # Ensure a dataframe is always returned
160
+ return(data.frame(Breaks = numeric(0), Counts = numeric(0)))
161
+ })
162
+
163
+
164
+ output$filtered_count <- renderText({
165
+ paste("Nombre de notices filtrées:", filtered_count())
166
+ })
167
+
168
+ output$table <- DT::renderDataTable({
169
+ datatable(reactive_data(), options = list(searching = FALSE),
170
+ callback = JS(paste0("
171
+ table.on('draw.dt', function() {
172
+ var keyword = '", input$motcle, "';
173
+ $('td').each(function() {
174
+ var content = $(this).html();
175
+ var highlighted = content.replace(new RegExp(keyword, 'gi'), function(match) {
176
+ return '<span style=\"background-color: yellow;\">' + match + '</span>';
177
+ });
178
+ $(this).html(highlighted);
179
+ });
180
+ });
181
+ ")))
182
+ })
183
+
184
+ output$downloadData <- downloadHandler(
185
+ filename = function() {
186
+ paste("filtered_data-", Sys.Date(), ".csv", sep="")
187
  },
188
+ content = function(file) {
189
+ fwrite(reactive_data(), file)
190
+ }
191
  )
192
+
193
+ output$histogram <- renderPlot({
194
+ # Check if 'Annee_unique' column exists and has data
195
+ if ("Annee_unique" %in% names(reactive_data1()) && nrow(reactive_data1()) > 0) {
196
+ min_year <- min(na.omit(reactive_data1()[, Annee_unique]))
197
+ max_year <- max(na.omit(reactive_data1()[, Annee_unique]))
198
+ breaks_hist <- seq(min_year, max_year, length.out = input$num_breaks + 1)
199
+
200
+ if (input$dist_type == "raw") {
201
+ hist(reactive_data1()[, Annee_unique],
202
+ main = "Distribution brute des notices",
203
+ xlab = "Année",
204
+ ylab = "Nombre",
205
+ border = "blue",
206
+ col = "lightblue",
207
+ breaks = breaks_hist)
208
+ } else {
209
+ # Compute relative distribution
210
+ filtered_counts <- hist(reactive_data1()[, Annee_unique], plot=FALSE, breaks=breaks_hist)$counts
211
+ total_counts <- hist(data[data$Annee_unique %in% reactive_data1()[, Annee_unique], Annee_unique], plot=FALSE, breaks=breaks_hist)$counts
212
+ relative_counts <- ifelse(total_counts == 0, 0, filtered_counts / total_counts)
213
+
214
+ # Ensure names.arg matches the length of relative_counts
215
+ names_for_bars <- round(seq(min_year, max_year, length.out = length(relative_counts)))
216
+
217
+ barplot(relative_counts,
218
+ main = "Distribution relative des notices",
219
+ xlab = "Année",
220
+ ylab = "Fréquence relative",
221
+ border = "blue",
222
+ col = "lightblue",
223
+ space = 0,
224
+ names.arg = names_for_bars)
225
+ }
226
+ } else {
227
+ plot.new()
228
+ title(main = "No data available for the selected criteria")
229
+ }
230
+ })
231
+
232
+ output$download_graph <- downloadHandler(
233
+ filename = function() {
234
+ paste("histogram_graph", Sys.Date(), ".png", sep = "_")
235
+ },
236
+ content = function(file) {
237
+ png(file)
238
+ # Check if 'Annee_unique' column exists and has data
239
+ if ("Annee_unique" %in% names(reactive_data1()) && nrow(reactive_data1()) > 0) {
240
+ min_year <- min(na.omit(reactive_data1()[, Annee_unique]))
241
+ max_year <- max(na.omit(reactive_data1()[, Annee_unique]))
242
+ breaks_hist <- seq(min_year, max_year, length.out = input$num_breaks + 1)
243
+
244
+ if (input$dist_type == "raw") {
245
+ hist(reactive_data1()[, Annee_unique],
246
+ main = "Distribution brute des notices",
247
+ xlab = "Année",
248
+ ylab = "Nombre",
249
+ border = "blue",
250
+ col = "lightblue",
251
+ breaks = breaks_hist)
252
+ } else {
253
+ # Compute relative distribution
254
+ filtered_counts <- hist(reactive_data1()[, Annee_unique], plot=FALSE, breaks=breaks_hist)$counts
255
+ total_counts <- hist(data[data$Annee_unique %in% reactive_data1()[, Annee_unique], Annee_unique], plot=FALSE, breaks=breaks_hist)$counts
256
+ relative_counts <- ifelse(total_counts == 0, 0, filtered_counts / total_counts)
257
+
258
+ # Ensure names.arg matches the length of relative_counts
259
+ names_for_bars <- round(seq(min_year, max_year, length.out = length(relative_counts)))
260
+
261
+ barplot(relative_counts,
262
+ main = "Distribution relative des notices",
263
+ xlab = "Année",
264
+ ylab = "Fréquence relative",
265
+ border = "blue",
266
+ col = "lightblue",
267
+ space = 0,
268
+ names.arg = names_for_bars)
269
+ }
270
+ } else {
271
+ plot.new()
272
+ title(main = "No data available for the selected criteria")
273
+ }
274
+ dev.off()
275
+ }
276
+ )
277
+
278
+ output$download_table <- downloadHandler(
279
+ filename = function() {
280
+ paste("histogram_data", Sys.Date(), ".csv", sep = "_")
281
+ },
282
+ content = function(file) {
283
+ write.csv(hist_data(), file, row.names = FALSE)
284
+ }
285
+ )
286
+ output$readme <- renderUI({
287
+ # Read the content of the README.md file
288
+ readme_content <- readLines("README.md", warn = FALSE)
289
+
290
+ # Convert the markdown content to HTML for rendering in the Shiny app
291
+ HTML(markdown::markdownToHTML(text = readme_content, fragment.only = TRUE))
292
+ })
293
+
294
  }
295
 
296
+
297
+ shinyApp(ui = ui, server = server)