cjerzak commited on
Commit
aee6cdd
·
verified ·
1 Parent(s): 3fdc35d

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +277 -54
app.R CHANGED
@@ -1,58 +1,281 @@
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
+ # setwd("~/Downloads")
2
+ {
3
+ # app.R
4
+ options(error = NULL)
5
+
6
+ # ------------------------------
7
+ # 1. Load Packages
8
+ # ------------------------------
9
+ library(shiny)
10
+ library(shinydashboard)
11
+ library(leaflet)
12
+ library(raster)
13
+ library(DT)
14
+ library(readr)
15
+ library(dplyr) # For data manipulation
16
+ library(ggplot2) # For histogram
17
+ library(RColorBrewer)
18
+
19
+ # ------------------------------
20
+ # 2. Data & Config
21
+ # ------------------------------
22
+
23
+ # Define time periods corresponding to each band in the GeoTIFF
24
+ time_periods <- c("1990–1992", "1993–1995", "1996–1998", "1999–2001", "2002–2004",
25
+ "2005–2007", "2008–2010", "2011–2013", "2014–2016", "2017–2019")
26
+
27
+ # Load GeoTIFF data
28
+ wealth_stack <- stack("wealth_map.tif")
29
+
30
+ # Clean up out-of-range values
31
+ wealth_stack[wealth_stack <= 0 | wealth_stack > 1] <- NA
32
+
33
+ # Load improvement data
34
+ improvement_data <- read_csv("poverty_improvement_by_state.csv")
35
+
36
+ # ------------------------------
37
+ # 3. UI
38
+ # ------------------------------
39
+
40
+ ui <- dashboardPage(
41
+
42
+ # -- Header
43
+ dashboardHeader(title = "Africa Living Conditions Explorer"),
44
+
45
+ # -- Sidebar
46
+ dashboardSidebar(
47
+ sidebarMenu(id = "tabs",
48
+ menuItem("Wealth Map", tabName = "mapTab", icon = icon("map")),
49
+ menuItem("Improvement Data", tabName = "improvementTab", icon = icon("table"))
50
+ ),
51
+ # Show inputs only for the map tab
52
+ conditionalPanel(
53
+ condition = "input.tabs == 'mapTab'",
54
+ br(),
55
+ selectInput("time_period", "Select Time Period:",
56
+ choices = time_periods,
57
+ selected = time_periods[1] # Load the first time period by default
58
+ ),
59
+ selectInput("color_palette", "Select Color Palette:",
60
+ choices = c("Viridis" = "viridis",
61
+ "Plasma" = "plasma",
62
+ "Magma" = "magma",
63
+ "Inferno"= "inferno",
64
+ "Spectral (Brewer)" = "Spectral"),
65
+ selected = "viridis"),
66
+ sliderInput("opacity", "Map Opacity:", min = 0.2, max = 1, value = 0.8, step = 0.1)
67
+ # Removed the 'Update Map' button
68
+ )
69
  ),
70
+
71
+ # -- Body
72
+ dashboardBody(
73
+ tabItems(
74
+
75
+ # ---------- MAP TAB ----------
76
+ tabItem(
77
+ tabName = "mapTab",
78
+ fluidRow(
79
+ # Value Boxes across the top for key stats
80
+ valueBoxOutput("highest_iwi_vb", width = 4),
81
+ valueBoxOutput("lowest_iwi_vb", width = 4),
82
+ valueBoxOutput("avg_iwi_vb", width = 4)
83
+ ),
84
+ fluidRow(
85
+ # Map
86
+ box(
87
+ title = "Wealth Map of Africa", width = 8, solidHeader = TRUE, status = "primary",
88
+ leafletOutput("map", height = "550px")
89
+ ),
90
+ # Histogram
91
+ box(
92
+ title = "IWI Distribution (Selected Period)", width = 4, solidHeader = TRUE, status = "info",
93
+ plotOutput("iwi_histogram", height = "250px"),
94
+ p("This histogram shows the distribution of the International Wealth Index (IWI) values for the selected time period across Africa.")
95
+ )
96
+ )
97
+ ),
98
+
99
+ # ---------- IMPROVEMENT DATA TAB ----------
100
+ tabItem(
101
+ tabName = "improvementTab",
102
+ fluidRow(
103
+ box(
104
+ width = 12, title = "Poverty Improvement by State", status = "primary", solidHeader = TRUE,
105
+ p("This table shows the estimated improvement in mean IWI between 1990–1992 and 2017–2019 for each province in Africa.
106
+ The 'Improvement' column indicates the change in IWI over this period. You can sort or filter the table,
107
+ and use the download button to export the data."),
108
+ downloadButton("download_data", "Download CSV", icon = icon("download")),
109
+ br(), br(),
110
+ DTOutput("improvement_table")
111
+ )
112
+ )
113
  )
114
+ )
115
+ )
116
+ )
117
+
118
+ # ------------------------------
119
+ # 4. Server
120
+ # ------------------------------
121
+
122
+ server <- function(input, output, session) {
123
+
124
+ # ----------------------------------
125
+ # Reactive expression for selected raster layer
126
+ # ----------------------------------
127
+ selected_raster <- reactive({
128
+ req(input$time_period)
129
+ band_index <- which(time_periods == input$time_period)
130
+ wealth_stack[[band_index]]
131
+ })
132
+
133
+ # ----------------------------------
134
+ # Custom color palette function
135
+ # (reactive to user-selected palette)
136
+ # ----------------------------------
137
+ color_pal <- reactive({
138
+ palette_choice <- switch(
139
+ input$color_palette,
140
+ "viridis" = "viridis",
141
+ "plasma" = "plasma",
142
+ "magma" = "magma",
143
+ "inferno" = "inferno",
144
+ # Fallback to a Brewer palette for "Spectral"
145
+ "Spectral" = "Spectral"
146
+ )
147
+ colorNumeric(
148
+ palette = palette_choice,
149
+ domain = c(0, 1),
150
+ na.color = "transparent"
151
+ )
152
+ })
153
+
154
+ # ----------------------------------
155
+ # 1. MAP OUTPUT
156
+ # ----------------------------------
157
+ output$map <- renderLeaflet({
158
+ leaflet() %>%
159
+ addProviderTiles(providers$OpenStreetMap) %>%
160
+ setView(lng = 20, lat = 0, zoom = 3) %>% # Center on Africa
161
+ addLegend(
162
+ pal = color_pal(),
163
+ values = c(1, 0),
164
+ bins = 2,
165
+ title = "IWI",
166
+ position = "bottomright",
167
+ labFormat = labelFormat(
168
+ prefix = "",
169
+ suffix = "",
170
+ between = " &ndash; ",
171
+ digits = 3,
172
+ big.mark = ","
173
+ )
174
+ )
175
+ })
176
+
177
+ # Any time one of the controls changes, redraw the raster
178
+ observe({
179
+ req(input$time_period, input$color_palette, input$opacity)
180
+
181
+ leafletProxy("map") %>%
182
+ clearImages() %>%
183
+ addRasterImage(
184
+ selected_raster(),
185
+ colors = color_pal(),
186
+ opacity = input$opacity,
187
+ project = TRUE
188
  )
189
+ })
190
+
191
+ # ----------------------------------
192
+ # 2. HISTOGRAM OUTPUT
193
+ # ----------------------------------
194
+ output$iwi_histogram <- renderPlot({
195
+ # Extract raster values for histogram
196
+ r_vals <- values(selected_raster())
197
+ r_vals <- r_vals[!is.na(r_vals)]
198
+
199
+ ggplot(data.frame(iwi = r_vals), aes(x = iwi)) +
200
+ geom_histogram(binwidth = 0.02, fill = "#2c7bb6", color = "white", alpha = 0.7) +
201
+ labs(x = "IWI (0 to 1)", y = "Frequency") +
202
+ theme_minimal(base_size = 14)
203
+ })
204
+
205
+ # ----------------------------------
206
+ # 3. VALUE BOXES FOR KEY STATS
207
+ # ----------------------------------
208
+ # Compute stats for current raster
209
+ raster_stats <- reactive({
210
+ r_vals <- values(selected_raster())
211
+ r_vals <- r_vals[!is.na(r_vals)]
212
+ list(
213
+ highest = max(r_vals, na.rm = TRUE),
214
+ lowest = min(r_vals, na.rm = TRUE),
215
+ average = mean(r_vals, na.rm = TRUE)
216
+ )
217
+ })
218
+
219
+ # Highest IWI
220
+ output$highest_iwi_vb <- renderValueBox({
221
+ valueBox(
222
+ value = round(raster_stats()$highest, 3),
223
+ subtitle = "Highest IWI",
224
+ icon = icon("arrow-up"),
225
+ color = "green"
226
+ )
227
+ })
228
+
229
+ # Lowest IWI
230
+ output$lowest_iwi_vb <- renderValueBox({
231
+ valueBox(
232
+ value = round(raster_stats()$lowest, 3),
233
+ subtitle = "Lowest IWI",
234
+ icon = icon("arrow-down"),
235
+ color = "red"
236
+ )
237
+ })
238
+
239
+ # Average IWI
240
+ output$avg_iwi_vb <- renderValueBox({
241
+ valueBox(
242
+ value = round(raster_stats()$average, 3),
243
+ subtitle = "Average IWI",
244
+ icon = icon("balance-scale"),
245
+ color = "blue"
246
+ )
247
+ })
248
+
249
+ # ----------------------------------
250
+ # 4. IMPROVEMENT DATA TABLE
251
+ # ----------------------------------
252
+ output$improvement_table <- renderDT({
253
+ datatable(
254
+ improvement_data,
255
+ filter = "top",
256
+ options = list(
257
+ scrollX = TRUE,
258
+ pageLength = 20,
259
+ autoWidth = TRUE
260
+ )
261
+ )
262
+ })
263
+
264
+ # Download CSV
265
+ output$download_data <- downloadHandler(
266
+ filename = function() {
267
+ paste0("poverty_improvement_", Sys.Date(), ".csv")
268
+ },
269
+ content = function(file) {
270
+ write.csv(improvement_data, file, row.names = FALSE)
271
  }
272
+ )
273
+
274
+ }
275
+
276
+ # ------------------------------
277
+ # 5. Run the App
278
+ # ------------------------------
279
+ shinyApp(ui = ui, server = server)
280
+
281
+ }