aephiday commited on
Commit
614aa54
·
verified ·
1 Parent(s): caac760

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +1155 -48
app.R CHANGED
@@ -1,58 +1,1165 @@
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(shinyWidgets)
3
+ library(echarts4r)
4
  library(bslib)
5
+ library(tidyverse)
6
+ library(leaflet)
7
+
8
+ library(readxl)
9
+ library(vetiver)
10
+ library(janitor)
11
+
12
+ telco_customer <- readr::read_csv("data/telco_customer_churn_dashboard.csv")
13
+ locations <- readxl::read_xlsx("data/telco_customer_churn_location.xlsx") %>%
14
+ clean_names() %>%
15
+ select(customer_id, city, latitude, longitude)
16
+
17
+ ui <- fluidPage(
18
+ tags$head(
19
+ tags$style("
20
+ body {
21
+ background-color: #8ec2ed;
22
+ }")
23
+ ),
24
+ title = "Customer Churn Prevention Dashboard",
25
+ tabsetPanel(
26
+ tabPanel(h5("Dashboard", style="font-weight:bold;margin-top:5px;margin-bottom:5px;"),
27
+ h1("Customer Churn Prevention Dashboard", style="font-weight:bold;text-align:center;color:#000;"),
28
+ fluidRow(
29
+ column(12,
30
+ column(2,
31
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
32
+ h5("Customer", style="font-weight:bold;margin:0;padding:0;"),
33
+ hr(style="margin:0.5em;padding:0;"),
34
+ h2(scales::number(nrow(telco_customer), big.mark = ","), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
35
+ )
36
+ ),
37
+ column(2,
38
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
39
+ h5("Potential Churn Customer", style="font-weight:bold;margin:0;padding:0;"),
40
+ hr(style="margin:0.5em;padding:0;"),
41
+ h2(paste0(scales::number(sum(telco_customer$churn_label == "Yes"), accuracy = 1, big.mark = ","), " (", scales::percent(sum(telco_customer$churn_label == "Yes")/nrow(telco_customer), accuracy = 0.01), ")"), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
42
+ )
43
+ ),
44
+ column(2,
45
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
46
+ h5("Avg Monthly Charges", style="font-weight:bold;margin:0;padding:0;"),
47
+ hr(style="margin:0.5em;padding:0;"),
48
+ h2(scales::number(mean(telco_customer$monthly_charge), accuracy = 0.01, big.mark = ",", prefix = "$"), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
49
+ )
50
+ ),
51
+ column(2,
52
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
53
+ h5("Total Charges", style="font-weight:bold;margin:0;padding:0;"),
54
+ hr(style="margin:0.5em;padding:0;"),
55
+ h2(scales::number(sum(telco_customer$total_charges), big.mark = ",", prefix = "$"), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
56
+ )
57
+ ),
58
+ column(2,
59
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
60
+ h5("Avg Monthly Long Dist. Chrg", style="font-weight:bold;margin:0;padding:0;"),
61
+ hr(style="margin:0.5em;padding:0;"),
62
+ h2(scales::number(mean(telco_customer$avg_monthly_long_distance_charges), accuracy = 0.01, big.mark = ",", prefix = "$"), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
63
+ )
64
+ ),
65
+ column(2,
66
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
67
+ h5("Avg CLTV", style="font-weight:bold;margin:0;padding:0;"),
68
+ hr(style="margin:0.5em;padding:0;"),
69
+ h2(scales::number(mean(telco_customer$cltv), accuracy = 0.01, big.mark = ","), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
70
+ )
71
+ )
72
+ )
73
+ ),
74
+ fluidRow(
75
+ column(4,
76
+ h3("Customer Demographics", style="font-weight:bold;text-align:center;color:#fff;"),
77
+ column(6,
78
+ wellPanel(style="background-color:transparent;text-align:center;margin:0 0 0.5em 0;padding:1em;height:200px;border-width:medium;box-shadow: 2px 2px #888888;",
79
+ # h5("% by Gender", style="margin:0;padding:0;"),
80
+ # hr(style="margin:0.5em;padding:0;"),
81
+ telco_customer |>
82
+ count(gender) |>
83
+ mutate(pct = round(n/sum(n)*100, 2)) |>
84
+ e_charts(gender) |>
85
+ e_pie(pct,
86
+ startAngle = 90) |>
87
+ e_title("% by Gender") |>
88
+ e_legend(show = TRUE, type = "plain", orient = "vertical", left = "right") |>
89
+ e_dims(height = 200) |>
90
+ e_tooltip(
91
+ formatter = htmlwidgets::JS("function(params){
92
+ return(params.name + ': ' + params.value + '%')
93
+ }")
94
+ )
95
+ )
96
+ ),
97
+ column(6,
98
+ div(style="display:flex;",
99
+ wellPanel(style="background-color:transparent;text-align:center;margin:0 0.5em 0.5em 0;padding:1em;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
100
+ h5("Sr. Citizen", style="font-weight:bold;margin:0;padding:0;"),
101
+ hr(style="margin:0.5em;padding:0;"),
102
+ h3(telco_customer %>%
103
+ mutate(senior_citizen = age > 65) %>%
104
+ pull(senior_citizen) %>%
105
+ mean() %>%
106
+ scales::percent(accuracy = 0.01), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
107
+ ),
108
+ wellPanel(style="background-color:transparent;text-align:center;margin:0 0 0.5em 0.5em;padding:1em;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
109
+ h5("Married", style="font-weight:bold;margin:0;padding:0;"),
110
+ hr(style="margin:0.5em;padding:0;"),
111
+ h3(telco_customer %>%
112
+ mutate(married = married == "Yes") %>%
113
+ pull(married) %>%
114
+ mean() %>%
115
+ scales::percent(accuracy = 0.01), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
116
+ )
117
+ ),
118
+ div(style="display:flex;",
119
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0.5em 0 0;padding:1em;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
120
+ h5("Dependents", style="font-weight:bold;margin:0;padding:0;"),
121
+ hr(style="margin:0.5em;padding:0;"),
122
+ h3(telco_customer %>%
123
+ mutate(dependents = number_of_dependents > 0) %>%
124
+ pull(dependents) %>%
125
+ mean() %>%
126
+ scales::percent(accuracy = 0.01), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
127
+ ),
128
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0 0 0.5em;padding:1em;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
129
+ h5("Ref Friend", style="font-weight:bold;margin:0;padding:0;"),
130
+ hr(style="margin:0.5em;padding:0;"),
131
+ h3(telco_customer %>%
132
+ mutate(referred_a_friend = referred_a_friend == "Yes") %>%
133
+ pull(referred_a_friend) %>%
134
+ mean() %>%
135
+ scales::percent(accuracy = 0.01), style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
136
+ )
137
+ )
138
+ ),
139
+ column(12,
140
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0 0 0;padding:0;border-width:medium;box-shadow: 2px 2px #888888;",
141
+ uiOutput("map")
142
+ )
143
+ )
144
+
145
+ ),
146
+ column(4,
147
+ h3("Customer Account Information", style="font-weight:bold;text-align:center;color:#fff;"),
148
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:1em;height:200px;border-width:medium;box-shadow: 2px 2px #888888;",
149
+ # telco_customer |>
150
+ # count(payment_method) |>
151
+ # mutate(pct = round(n/sum(n)*100, 2)) |>
152
+ # e_charts(payment_method) |>
153
+ # e_pie(pct,
154
+ # startAngle = 120) |>
155
+ # e_title("Payment Method") |>
156
+ # e_legend(show = TRUE, type = "plain", orient = "vertical", left = "right") |>
157
+ # e_dims(height = 200) |>
158
+ # e_tooltip(
159
+ # formatter = htmlwidgets::JS("function(params){
160
+ # return(params.name + ': ' + params.value + '%')
161
+ # }")
162
+ # )
163
+ telco_customer |>
164
+ count(payment_method) |>
165
+ # top_n(3, n) %>%
166
+ mutate(pct = round(n/sum(n), 4)) |>
167
+ arrange(pct) %>%
168
+ e_charts(payment_method, reorder = TRUE) |>
169
+ e_bar(pct, legend = FALSE) |>
170
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
171
+ e_flip_coords() %>%
172
+ e_title("Payment Method") |>
173
+ e_dims(width = 600, height = 200) |>
174
+ e_grid(left = "20%", top = "12.5%", bottom = "25%") %>%
175
+ e_tooltip(
176
+ formatter = htmlwidgets::JS("function(params){
177
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
178
+ }")
179
+ )
180
+ ),
181
+ div(style="display: flex;",
182
+ wellPanel(style="background-color:transparent;text-align:center;margin:1em 0.5em 0.5em 0;padding:1em;height:190px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
183
+ telco_customer %>%
184
+ count(paperless_billing) |>
185
+ mutate(pct = round(n/sum(n)*100, 2)) |>
186
+ e_charts(paperless_billing) %>%
187
+ e_pie(pct) |>
188
+ e_title("Paperless Billing") |>
189
+ e_legend(show = TRUE, type = "plain", orient = "vertical", left = "right") |>
190
+ e_dims(height = 190) |>
191
+ e_tooltip(
192
+ formatter = htmlwidgets::JS("function(params){
193
+ return(params.name + ': ' + params.value + '%')
194
+ }")
195
+ )
196
+ ),
197
+ wellPanel(style="background-color:transparent;text-align:center;margin:1em 0 0.5em 0.5em;padding:1em;height:190px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
198
+ telco_customer |>
199
+ count(offer) |>
200
+ mutate(offer = str_remove(offer, "Offer "),
201
+ pct = round(n/sum(n), 4)) |>
202
+ arrange(n) %>%
203
+ e_charts(offer) |>
204
+ e_bar(pct, legend = FALSE) |>
205
+ e_title("Offer") |>
206
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
207
+ e_flip_coords() %>%
208
+ e_dims(height = 200) |>
209
+ e_grid(left = "15%", top = "12.5%", bottom = "25%", right = "10%") %>%
210
+ e_tooltip(
211
+ formatter = htmlwidgets::JS("function(params){
212
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
213
+ }")
214
+ )
215
+ )
216
+ ),
217
+ div(style="display: flex;",
218
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0.5em 0 0;padding:1em;height:200px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
219
+ telco_customer %>%
220
+ mutate(tenure_grp = case_when(tenure_in_months < 12 ~ " < 1 year",
221
+ tenure_in_months < 24 ~ " < 2 year",
222
+ tenure_in_months < 36 ~ " < 3 year",
223
+ tenure_in_months < 48 ~ " < 4 year",
224
+ TRUE ~ "4+ year")) %>%
225
+ count(tenure_grp) %>%
226
+ mutate(pct = round(n/sum(n), 4)) |>
227
+ arrange(n) %>%
228
+ e_charts(tenure_grp) |>
229
+ e_bar(pct, legend = FALSE) |>
230
+ e_title("Tenure") |>
231
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
232
+ e_flip_coords() %>%
233
+ e_dims(height = 200) |>
234
+ e_grid(left = "25%", top = "12.5%", bottom = "25%", right = "10%") %>%
235
+ e_tooltip(
236
+ formatter = htmlwidgets::JS("function(params){
237
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
238
+ }")
239
+ )
240
+ ),
241
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0 0 0.5em;padding:1em;height:200px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
242
+ telco_customer %>%
243
+ count(contract) %>%
244
+ mutate(pct = round(n/sum(n), 4)) |>
245
+ arrange(n) %>%
246
+ e_charts(contract) |>
247
+ e_bar(pct, legend = FALSE) |>
248
+ e_title("Contract Type") |>
249
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
250
+ e_flip_coords() %>%
251
+ e_dims(height = 200) |>
252
+ e_grid(left = "45%", top = "12.5%", bottom = "25%", right = "10%") %>%
253
+ e_tooltip(
254
+ formatter = htmlwidgets::JS("function(params){
255
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
256
+ }")
257
+ )
258
+ )
259
+ )
260
+ ),
261
+ column(4,
262
+ h3("Services Signed", style="font-weight:bold;text-align:center;color:#fff;"),
263
+ column(12,
264
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:1em;height:285px;border-width:medium;box-shadow: 2px 2px #888888;",
265
+ telco_customer |>
266
+ count(internet_type) |>
267
+ mutate(pct = round(n/sum(n), 4)) |>
268
+ arrange(n) %>%
269
+ e_charts(internet_type) |>
270
+ e_bar(pct, legend = FALSE) |>
271
+ e_title("Internet Service Type") |>
272
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
273
+ e_flip_coords() %>%
274
+ e_dims(width = 600, height = 285) |>
275
+ e_grid(left = "15%", top = "12.5%", bottom = "20%", right = "15%") %>%
276
+ e_tooltip(
277
+ formatter = htmlwidgets::JS("function(params){
278
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
279
+ }")
280
+ )
281
+ ),
282
+ div(style="display:flex;",
283
+ wellPanel(style="background-color:transparent;text-align:center;margin:1em 0.5em 1em 0;padding:1em;height:320px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
284
+ # br(),
285
+ progressBar(id = "pb1", value = 0, display_pct = TRUE, striped = TRUE),
286
+ progressBar(id = "pb2", value = 0, display_pct = TRUE, striped = TRUE),
287
+ progressBar(id = "pb3", value = 0, display_pct = TRUE, striped = TRUE),
288
+ progressBar(id = "pb4", value = 0, display_pct = TRUE, striped = TRUE),
289
+ progressBar(id = "pb5", value = 0, display_pct = TRUE, striped = TRUE)
290
+ ),
291
+ wellPanel(style="background-color:transparent;text-align:center;margin:1em 0 1em 0.5em;padding:1em;height:320px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
292
+ # br(),
293
+ progressBar(id = "pb6", value = 0, display_pct = TRUE, striped = TRUE),
294
+ progressBar(id = "pb7", value = 0, display_pct = TRUE, striped = TRUE),
295
+ progressBar(id = "pb8", value = 0, display_pct = TRUE, striped = TRUE),
296
+ progressBar(id = "pb9", value = 0, display_pct = TRUE, striped = TRUE),
297
+ progressBar(id = "pb10", value = 0, display_pct = TRUE, striped = TRUE)
298
+ )
299
+ )
300
+ )
301
+ )
302
+ )
303
+ ),
304
+ tabPanel(
305
+ h5("Customer Churn Prediction", style="font-weight:bold;margin-top:5px;margin-bottom:5px;"),
306
+ fluidRow(
307
+ column(12,
308
+ # h1("Customer Churn Prediction", style="font-weight:bold;text-align:center;color:#000;margin-bottom:0;"),
309
+ div(style="display:flex;flex-wrap:nowrap;margin-left:1.5rem;margin-bottom:-30px !important;margin-top:1.5em;",
310
+ fileInput("file_data", "Upload File", width = "20%",),
311
+ div(style="height:30px;margin-top:1.75em;margin-bottom:0;",
312
+ actionButton("process", "Process", icon = icon("cogs"))
313
+ ),
314
+ div(style="margin-left:0.5em;",
315
+ selectInput("customer", "Select Customer", choices = c("---All Customers---"))
316
+ )
317
+ )
318
+ )
319
+ ),
320
+ fluidRow(
321
+ column(12,
322
+ column(2,
323
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
324
+ uiOutput("pred_total_cust")
325
+ )
326
+ ),
327
+ column(2,
328
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
329
+ uiOutput("pred_potential_churn")
330
+ )
331
+ ),
332
+ column(2,
333
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
334
+ uiOutput("pred_monthly_charge")
335
+ )
336
+ ),
337
+ column(2,
338
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
339
+ uiOutput("pred_total_charge")
340
+ )
341
+ ),
342
+ column(2,
343
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
344
+ uiOutput("pred_avg_long_dist")
345
+ )
346
+ ),
347
+ column(2,
348
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:0.5em;border-width:medium;box-shadow: 2px 2px #888888;",
349
+ uiOutput("pred_avg_cltv")
350
+ )
351
+ )
352
+ )
353
+ ),
354
+ fluidRow(
355
+ column(4,
356
+ h3("Customer Demographics", style="font-weight:bold;text-align:center;color:#fff;"),
357
+ column(6,
358
+ wellPanel(style="background-color:transparent;text-align:center;margin:0 0 0.5em 0;padding:1em;height:200px;border-width:medium;box-shadow: 2px 2px #888888;",
359
+ echarts4rOutput("pred_pie_gender")
360
+ )
361
+ ),
362
+ column(6,
363
+ div(style="display:flex;",
364
+ wellPanel(style="background-color:transparent;text-align:center;margin:0 0.5em 0.5em 0;padding:1em;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
365
+ uiOutput("pred_sr_citizen")
366
+ ),
367
+ wellPanel(style="background-color:transparent;text-align:center;margin:0 0 0.5em 0.5em;padding:1em;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
368
+ uiOutput("pred_married")
369
+ )
370
+ ),
371
+ div(style="display:flex;",
372
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0.5em 0 0;padding:1em;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
373
+ uiOutput("pred_dependents")
374
+ ),
375
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0 0 0.5em;padding:1em;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
376
+ uiOutput("pred_referred")
377
+ )
378
+ )
379
+ ),
380
+ column(12,
381
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0 0 0;padding:0;border-width:medium;box-shadow: 2px 2px #888888;",
382
+ uiOutput("pred_map")
383
+ )
384
+ )
385
+
386
+ ),
387
+ column(4,
388
+ h3("Customer Account Information", style="font-weight:bold;text-align:center;color:#fff;"),
389
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:1em;height:200px;border-width:medium;box-shadow: 2px 2px #888888;",
390
+ echarts4rOutput("pred_payment")
391
+ ),
392
+ div(style="display: flex;",
393
+ wellPanel(style="background-color:transparent;text-align:center;margin:1em 0.5em 0.5em 0;padding:1em;height:190px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
394
+ echarts4rOutput("pred_paperless")
395
+ ),
396
+ wellPanel(style="background-color:transparent;text-align:center;margin:1em 0 0.5em 0.5em;padding:1em;height:190px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
397
+ echarts4rOutput("pred_offer")
398
+ )
399
+ ),
400
+ div(style="display: flex;",
401
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0.5em 0 0;padding:1em;height:200px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
402
+ echarts4rOutput("pred_tenure")
403
+ ),
404
+ wellPanel(style="background-color:transparent;text-align:center;margin:0.5em 0 0 0.5em;padding:1em;height:200px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
405
+ echarts4rOutput("pred_contract")
406
+ )
407
+ )
408
+ ),
409
+ column(4,
410
+ h3("Services Signed", style="font-weight:bold;text-align:center;color:#fff;"),
411
+ column(12,
412
+ wellPanel(style="background-color:transparent;text-align:center;margin:0;padding:1em;height:285px;border-width:medium;box-shadow: 2px 2px #888888;",
413
+ echarts4rOutput("pred_internet_type")
414
+ ),
415
+ div(style="display:flex;",
416
+ wellPanel(style="background-color:transparent;text-align:center;margin:1em 0.5em 1em 0;padding:1em;height:320px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
417
+ # br(),
418
+ progressBar(id = "pred_pb1", value = 0, display_pct = TRUE, striped = TRUE),
419
+ progressBar(id = "pred_pb2", value = 0, display_pct = TRUE, striped = TRUE),
420
+ progressBar(id = "pred_pb3", value = 0, display_pct = TRUE, striped = TRUE),
421
+ progressBar(id = "pred_pb4", value = 0, display_pct = TRUE, striped = TRUE),
422
+ progressBar(id = "pred_pb5", value = 0, display_pct = TRUE, striped = TRUE)
423
+ ),
424
+ wellPanel(style="background-color:transparent;text-align:center;margin:1em 0 1em 0.5em;padding:1em;height:320px;width:50%;border-width:medium;box-shadow: 2px 2px #888888;",
425
+ # br(),
426
+ progressBar(id = "pred_pb6", value = 0, display_pct = TRUE, striped = TRUE),
427
+ progressBar(id = "pred_pb7", value = 0, display_pct = TRUE, striped = TRUE),
428
+ progressBar(id = "pred_pb8", value = 0, display_pct = TRUE, striped = TRUE),
429
+ progressBar(id = "pred_pb9", value = 0, display_pct = TRUE, striped = TRUE),
430
+ progressBar(id = "pred_pb10", value = 0, display_pct = TRUE, striped = TRUE)
431
+ )
432
+ )
433
+ )
434
+ )
435
+ )
436
+ )
437
+ )
438
  )
439
 
440
+ server <- function(input, output, session){
441
+ output$location <- renderLeaflet({
442
+ tag.map.title <- tags$style(HTML("
443
+ .leaflet-control.map-title {
444
+ transform: translate(-50%,20%);
445
+ position: float !important;
446
+ left: 80%;
447
+ margin-top: -50%;
448
+ text-align: left;
449
+ padding-left: 10px;
450
+ padding-right: 10px;
451
+ background: transparent;
452
+ font-weight: bold;
453
+ font-size: 20px;
454
+ }"))
455
+
456
+ title <- tags$div(
457
+ tag.map.title, HTML("Location")
458
+ )
459
+
460
+ telco_customer %>%
461
+ count(city, longitude, latitude) %>%
462
+ leaflet() %>%
463
+ addTiles() %>%
464
+ # addMarkers(lng = ~longitude, lat = ~latitude,
465
+ # clusterOptions = markerClusterOptions()
466
+ # ) %>%
467
+ addCircles(lng = ~longitude, lat = ~latitude) %>%
468
+ addControl(title, position = "topleft", className="map-title")
469
+ })
470
+ output$map <- renderUI({
471
+ leafletOutput("location")
472
+ })
473
+
474
+ mypb_status <- function(value){
475
+ if (value < 33) {
476
+ status <- "danger"
477
+ } else if (value >= 33 & value < 67) {
478
+ status <- "warning"
479
+ } else {
480
+ status <- "success"
481
+ }
482
+ return(status)
483
+ }
484
+
485
+ # observe({
486
+ # shinyWidgets::updateProgressBar(session = session, id = "pb1", value = 80, title = "Premium Tech Support")
487
+ # shinyWidgets::updateProgressBar(session = session, id = "pb2", value = 80, title = "Phone Service")
488
+ # shinyWidgets::updateProgressBar(session = session, id = "pb3", value = 50, title = "Multiple Lines")
489
+ # shinyWidgets::updateProgressBar(session = session, id = "pb4", value = 50, title = "Online Security")
490
+ # shinyWidgets::updateProgressBar(session = session, id = "pb5", value = 50, title = "Online Backup")
491
+ # shinyWidgets::updateProgressBar(session = session, id = "pb6", value = 50, title = "Device Protection Plan")
492
+ # shinyWidgets::updateProgressBar(session = session, id = "pb7", value = 50, title = "Streaming TV")
493
+ # shinyWidgets::updateProgressBar(session = session, id = "pb8", value = 50, title = "Streaming Music")
494
+ # shinyWidgets::updateProgressBar(session = session, id = "pb9", value = 50, title = "Streaming Movies")
495
+ # shinyWidgets::updateProgressBar(session = session, id = "pb10", value = 50, title = "Unlimited Data")
496
+ # })
497
+ #
498
+ observe({
499
+ shinyWidgets::updateProgressBar(session = session, id = "pb1", value = round(sum(telco_customer$premium_tech_support == "Yes")/nrow(telco_customer)*100, 2), title = "Premium Tech Support")
500
+ shinyWidgets::updateProgressBar(session = session, id = "pb2", value = round(sum(telco_customer$phone_service == "Yes")/nrow(telco_customer)*100, 2), title = "Phone Service")
501
+ shinyWidgets::updateProgressBar(session = session, id = "pb3", value = round(sum(telco_customer$multiple_lines == "Yes")/nrow(telco_customer)*100, 2), title = "Multiple Lines")
502
+ shinyWidgets::updateProgressBar(session = session, id = "pb4", value = round(sum(telco_customer$online_security == "Yes")/nrow(telco_customer)*100, 2), title = "Online Security")
503
+ shinyWidgets::updateProgressBar(session = session, id = "pb5", value = round(sum(telco_customer$online_backup == "Yes")/nrow(telco_customer)*100, 2), title = "Online Backup")
504
+ shinyWidgets::updateProgressBar(session = session, id = "pb6", value = round(sum(telco_customer$device_protection_plan == "Yes")/nrow(telco_customer)*100, 2), title = "Device Protection Plan")
505
+ shinyWidgets::updateProgressBar(session = session, id = "pb7", value = round(sum(telco_customer$streaming_tv == "Yes")/nrow(telco_customer)*100, 2), title = "Streaming TV")
506
+ shinyWidgets::updateProgressBar(session = session, id = "pb8", value = round(sum(telco_customer$streaming_music == "Yes")/nrow(telco_customer)*100, 2), title = "Streaming Music")
507
+ shinyWidgets::updateProgressBar(session = session, id = "pb9", value = round(sum(telco_customer$streaming_movies == "Yes")/nrow(telco_customer)*100, 2), title = "Streaming Movies")
508
+ shinyWidgets::updateProgressBar(session = session, id = "pb10", value = round(sum(telco_customer$unlimited_data == "Yes")/nrow(telco_customer)*100, 2), title = "Unlimited Data")
509
+ })
510
+
511
+ # to_pred_df <- eventReactive(input$process, read_csv(input$file_data$datapath))
512
+
513
+ vep <- vetiver_endpoint("https://aephiday-test.hf.space/predict")
514
+
515
+ outpred <- eventReactive(input$process, {
516
+ ext <- tools::file_ext(input$file_data$datapath)
517
+ req(input$file_data)
518
+ validate(need(ext == "csv", "Please upload a csv file"))
519
+ if(is.null(input$file_data)){
520
+ return(NULL)
521
+ } else {
522
+ to_pred_df <- read_csv(input$file_data$datapath)
523
+ vep %>%
524
+ augment(new_data = to_pred_df) %>%
525
+ mutate(.pred_class = factor(if_else(.pred_Yes > 0.5, "Yes", "No"), levels = c("Yes", "No")))
526
+ }
527
+ })
528
+
529
+ observeEvent(input$process, {
530
+ updateSelectInput(session = session, inputId = "customer", label = "Select Customer", choices = c("---All Customers---", outpred()$customer_id))
531
+ })
532
+
533
+ output$pred_total_cust <- renderUI({
534
+ if(input$customer == "---All Customers---"){
535
+ tagList(
536
+ h5("Total Customer", style="font-weight:bold;margin:0;padding:0;"),
537
+ hr(style="margin:0.5em;padding:0;"),
538
+ scales::number(nrow(outpred()), big.mark = ",") %>%
539
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
540
+ )
541
+ } else {
542
+ tagList(
543
+ h5("Customer ID", style="font-weight:bold;margin:0;padding:0;"),
544
+ hr(style="margin:0.5em;padding:0;"),
545
+ h2(input$customer, style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
546
+ )
547
+ }
548
+
549
+ })
550
+ output$pred_potential_churn <- renderUI({
551
+ if(input$customer == "---All Customers---"){
552
+ tagList(
553
+ h5("Potential Churn Customer", style="font-weight:bold;margin:0;padding:0;"),
554
+ hr(style="margin:0.5em;padding:0;"),
555
+ paste0(scales::number(sum(outpred()$.pred_class == "Yes"), accuracy = 1), " (", scales::percent(sum(outpred()$.pred_class == "Yes")/nrow(outpred()), accuracy = 0.01), ")") %>%
556
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
557
+ )
558
+ } else {
559
+ tagList(
560
+ h5("Churn Probability", style="font-weight:bold;margin:0;padding:0;"),
561
+ hr(style="margin:0.5em;padding:0;"),
562
+ scales::percent(outpred() %>%
563
+ filter(customer_id == input$customer) %>%
564
+ pull(.pred_Yes), accuracy = 0.01) %>%
565
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
566
+ )
567
+ }
568
+ })
569
+ output$pred_monthly_charge <- renderUI({
570
+ if(input$customer == "---All Customers---"){
571
+ tagList(
572
+ h5("Avg Monthly Charges", style="font-weight:bold;margin:0;padding:0;"),
573
+ hr(style="margin:0.5em;padding:0;"),
574
+ scales::number(mean(outpred()$monthly_charge), accuracy = 0.01, big.mark = ",", prefix = "$") %>%
575
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
576
+ )
577
+ } else {
578
+ tagList(
579
+ h5("Avg Monthly Charges", style="font-weight:bold;margin:0;padding:0;"),
580
+ hr(style="margin:0.5em;padding:0;"),
581
+ scales::number(outpred() %>%
582
+ filter(customer_id == input$customer) %>%
583
+ pull(monthly_charge), accuracy = 0.01,
584
+ big.mark = ",", prefix = "$") %>%
585
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
586
+ )
587
+ }
588
+ })
589
+ output$pred_total_charge <- renderUI({
590
+ if(input$customer == "---All Customers---"){
591
+ tagList(
592
+ h5("Total Charges", style="font-weight:bold;margin:0;padding:0;"),
593
+ hr(style="margin:0.5em;padding:0;"),
594
+ scales::number(sum(outpred()$total_charges),
595
+ accuracy = 0.01, big.mark = ",", prefix = "$") %>%
596
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
597
+ )
598
+ } else {
599
+ tagList(
600
+ h5("Total Charges", style="font-weight:bold;margin:0;padding:0;"),
601
+ hr(style="margin:0.5em;padding:0;"),
602
+ scales::number(outpred() %>%
603
+ filter(customer_id == input$customer) %>%
604
+ pull(total_charges), accuracy = 0.01,
605
+ big.mark = ",", prefix = "$") %>%
606
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
607
+ )
608
+ }
609
+ })
610
+ output$pred_avg_long_dist <- renderUI({
611
+ if(input$customer == "---All Customers---"){
612
+ tagList(
613
+ h5("Avg Monthly Long Dist. Chrg", style="font-weight:bold;margin:0;padding:0;"),
614
+ hr(style="margin:0.5em;padding:0;"),
615
+ scales::number(mean(outpred()$avg_monthly_long_distance_charges),
616
+ accuracy = 0.01, big.mark = ",", prefix = "$") %>%
617
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
618
+ )
619
+ } else {
620
+ tagList(
621
+ h5("Avg Monthly Long Dist. Chrg", style="font-weight:bold;margin:0;padding:0;"),
622
+ hr(style="margin:0.5em;padding:0;"),
623
+ scales::number(outpred() %>%
624
+ filter(customer_id == input$customer) %>%
625
+ pull(avg_monthly_long_distance_charges), accuracy = 0.01,
626
+ big.mark = ",", prefix = "$") %>%
627
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
628
+ )
629
+ }
630
+ })
631
+ output$pred_avg_cltv <- renderUI({
632
+ if(input$customer == "---All Customers---"){
633
+ tagList(
634
+ h5("Avg CLTV", style="font-weight:bold;margin:0;padding:0;"),
635
+ hr(style="margin:0.5em;padding:0;"),
636
+ scales::number(mean(outpred()$cltv), accuracy = 0.01, big.mark = ",") %>%
637
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
638
+ )
639
+ } else {
640
+ tagList(
641
+ h5("CLTV", style="font-weight:bold;margin:0;padding:0;"),
642
+ hr(style="margin:0.5em;padding:0;"),
643
+ scales::number(outpred() %>%
644
+ filter(customer_id == input$customer) %>%
645
+ pull(cltv), accuracy = 1, big.mark = ",") %>%
646
+ h2(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
647
+ )
648
+ }
649
+ })
650
+
651
+
652
+ output$pred_pie_gender <- renderEcharts4r({
653
+ if(input$customer == "---All Customers---"){
654
+ outpred() |>
655
+ count(gender) |>
656
+ mutate(pct = round(n/sum(n)*100, 2)) |>
657
+ e_charts(gender) |>
658
+ e_pie(pct,
659
+ startAngle = 90) |>
660
+ e_labels(show = FALSE) %>%
661
+ e_title("% by Gender") |>
662
+ e_legend(show = TRUE, type = "plain", orient = "vertical", left = "right") |>
663
+ e_dims(height = 200) |>
664
+ e_tooltip(
665
+ formatter = htmlwidgets::JS("function(params){
666
+ return(params.name + ': ' + params.value + '%')
667
+ }")
668
  )
669
+ } else {
670
+ fm <- reactive(outpred() |>
671
+ filter(customer_id == input$customer) %>%
672
+ pull(gender))
673
+
674
+ outpred() |>
675
+ filter(customer_id == input$customer) %>%
676
+ count(gender) |>
677
+ mutate(pct = round(n/sum(n)*100, 2)) |>
678
+ e_charts(gender) |>
679
+ e_pie(pct,
680
+ startAngle = 90) |>
681
+ e_image_g(top = "10%",
682
+ left = "30%",
683
+ z = 999,
684
+ style = list(image = paste0(fm(), ".png"),
685
+ width = 150,
686
+ height = 150)
687
+ ) %>%
688
+ e_labels(show = FALSE) %>%
689
+ e_title("Gender") %>%
690
+ e_dims(height = 200)
691
+ }
692
+ })
693
+
694
+ output$pred_sr_citizen <- renderUI({
695
+ if(input$customer == "---All Customers---"){
696
+ tagList(
697
+ h5("Sr. Citizen", style="font-weight:bold;margin:0;padding:0;"),
698
+ hr(style="margin:0.5em;padding:0;"),
699
+ outpred() %>%
700
+ mutate(senior_citizen = age > 65) %>%
701
+ pull(senior_citizen) %>%
702
+ mean() %>%
703
+ scales::percent(accuracy = 0.01) %>%
704
+ h3(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
705
+ )
706
+ } else {
707
+ tagList(
708
+ h5("Age", style="font-weight:bold;margin:0;padding:0;"),
709
+ hr(style="margin:0.5em;padding:0;"),
710
+ outpred() %>%
711
+ filter(customer_id == input$customer) %>%
712
+ pull(age) %>%
713
+ h3(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
714
+ )
715
+ }
716
+ })
717
+
718
+ output$pred_married <- renderUI({
719
+ if(input$customer == "---All Customers---"){
720
+ tagList(
721
+ h5("Married", style="font-weight:bold;margin:0;padding:0;"),
722
+ hr(style="margin:0.5em;padding:0;"),
723
+ outpred() %>%
724
+ mutate(married = married == "Yes") %>%
725
+ pull(married) %>%
726
+ mean() %>%
727
+ scales::percent(accuracy = 0.01) %>%
728
+ h3(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
729
+ )
730
+ } else {
731
+ tagList(
732
+ h5("Married", style="font-weight:bold;margin:0;padding:0;"),
733
+ hr(style="margin:0.5em;padding:0;"),
734
+ outpred() %>%
735
+ filter(customer_id == input$customer) %>%
736
+ pull(married) %>%
737
+ h3(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
738
+ )
739
+ }
740
+ })
741
+
742
+ output$pred_dependents <- renderUI({
743
+ if(input$customer == "---All Customers---"){
744
+ tagList(
745
+ h5("Dependents", style="font-weight:bold;margin:0;padding:0;"),
746
+ hr(style="margin:0.5em;padding:0;"),
747
+ outpred() %>%
748
+ mutate(dependents = number_of_dependents > 0) %>%
749
+ pull(dependents) %>%
750
+ mean() %>%
751
+ scales::percent(accuracy = 0.01) %>%
752
+ h3(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
753
+ )
754
+ } else {
755
+ tagList(
756
+ h5("Dependents", style="font-weight:bold;margin:0;padding:0;"),
757
+ hr(style="margin:0.5em;padding:0;"),
758
+ outpred() %>%
759
+ filter(customer_id == input$customer) %>%
760
+ pull(number_of_dependents) %>%
761
+ mean() %>%
762
+ scales::number(big.mark = ",") %>%
763
+ h3(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
764
+ )
765
+ }
766
+ })
767
+
768
+ output$pred_referred <- renderUI({
769
+ if(input$customer == "---All Customers---"){
770
+ tagList(
771
+ h5("Ref Friend", style="font-weight:bold;margin:0;padding:0;"),
772
+ hr(style="margin:0.5em;padding:0;"),
773
+ outpred() %>%
774
+ mutate(referred_a_friend = referred_a_friend == "Yes") %>%
775
+ pull(referred_a_friend) %>%
776
+ mean() %>%
777
+ scales::percent(accuracy = 0.01) %>%
778
+ h3(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
779
+ )
780
+ } else {
781
+ tagList(
782
+ h5("Ref Friend", style="font-weight:bold;margin:0;padding:0;"),
783
+ hr(style="margin:0.5em;padding:0;"),
784
+ outpred() %>%
785
+ filter(customer_id == input$customer) %>%
786
+ pull(referred_a_friend) %>%
787
+ h3(style="font-weight:bold;margin:0;padding:0;color:#0c5896;")
788
+ )
789
+ }
790
+ })
791
+
792
+ output$pred_location <- renderLeaflet({
793
+ tag.map.title <- tags$style(HTML("
794
+ .leaflet-control.map-title {
795
+ transform: translate(-50%,20%);
796
+ position: float !important;
797
+ left: 80%;
798
+ margin-top: -50%;
799
+ text-align: left;
800
+ padding-left: 10px;
801
+ padding-right: 10px;
802
+ background: transparent;
803
+ font-weight: bold;
804
+ font-size: 20px;
805
+ }"))
806
+
807
+ title <- tags$div(
808
+ tag.map.title, HTML("Location")
809
+ )
810
+
811
+ pal <- colorFactor(palette = c("blue", "firebrick"), domain = outpred()$.pred_class)
812
+
813
+ if(input$customer == "---All Customers---"){
814
+ outpred() %>%
815
+ # filter(customer_id == input$customer) %>%
816
+ left_join(locations, join_by(customer_id)) %>%
817
+ count(city, longitude, latitude) %>%
818
+ leaflet() %>%
819
+ addTiles() %>%
820
+ # addMarkers(lng = ~longitude, lat = ~latitude,
821
+ # clusterOptions = markerClusterOptions()
822
+ # ) %>%
823
+ addCircles(lng = ~longitude, lat = ~latitude,
824
+ color = ~pal(outpred()$.pred_class),
825
+ popup = ~htmltools::htmlEscape(paste0(city, ": ", n))) %>%
826
+ addControl(title, position = "topleft", className="map-title") %>%
827
+ addLegend(pal = pal, values = outpred()$.pred_class)
828
+ } else {
829
+ cust_data <- outpred() %>%
830
+ filter(customer_id == input$customer) %>%
831
+ left_join(locations, join_by(customer_id))
832
+
833
+ cust_data %>%
834
+ leaflet() %>%
835
+ # setView(lng = ~longitude, lat = ~latitude, zoom = 17) %>%
836
+ addTiles() %>%
837
+ # addMarkers(lng = ~longitude, lat = ~latitude,
838
+ # clusterOptions = markerClusterOptions()
839
+ # ) %>%
840
+ addMarkers(lng = ~longitude, lat = ~latitude,
841
+ popup = ~htmltools::htmlEscape(city)) %>%
842
+ addControl(title, position = "topleft", className="map-title")
843
+
844
+ }
845
+ })
846
+ output$pred_map <- renderUI({
847
+ leafletOutput("pred_location")
848
+ })
849
+
850
+ output$pred_payment <- renderEcharts4r({
851
+ if(input$customer == "---All Customers---"){
852
+ outpred() |>
853
+ count(payment_method) |>
854
+ mutate(pct = round(n/sum(n), 4)) |>
855
+ arrange(pct) %>%
856
+ ungroup() %>%
857
+ e_charts(payment_method, reorder = TRUE) |>
858
+ e_bar(pct, legend = FALSE) |>
859
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
860
+ e_flip_coords() %>%
861
+ e_title("Payment Method") |>
862
+ e_dims(width = 600, height = 200) |>
863
+ e_grid(left = "20%", top = "12.5%", bottom = "25%") %>%
864
+ e_tooltip(
865
+ formatter = htmlwidgets::JS("function(params){
866
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
867
+ }")
868
+
869
+ )
870
+ } else {
871
+ pm <- reactive(outpred() %>%
872
+ filter(customer_id == input$customer) %>%
873
+ pull(payment_method) %>%
874
+ str_replace("\\s", "-"))
875
+ #
876
+ # outpred() %>%
877
+ # filter(customer_id == input$customer) %>%
878
+ # e_charts() %>%
879
+ # e_image_g(top = "10%",
880
+ # left = "40%",
881
+ # z = -999,
882
+ # style = list(image = paste0(pm(), ".png"),
883
+ # width = 150,
884
+ # height = 150)
885
+ # ) |>
886
+ # e_dims(width = 600, height = 200) %>%
887
+ # e_title("Payment Method")
888
+ outpred() |>
889
+ filter(customer_id == input$customer) %>%
890
+ count(payment_method) |>
891
+ mutate(pct = round(n/sum(n), 4)) |>
892
+ arrange(pct) %>%
893
+ ungroup() %>%
894
+ e_charts(payment_method, reorder = TRUE) |>
895
+ e_bar(pct, legend = FALSE) |>
896
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
897
+ e_flip_coords() %>%
898
+ e_title("Payment Method") |>
899
+ e_dims(width = 600, height = 200) |>
900
+ e_image_g(top = "10%",
901
+ left = "40%",
902
+ z = 999,
903
+ style = list(image = paste0(pm(), ".png"),
904
+ width = 150,
905
+ height = 150)
906
+ ) |>
907
+ e_grid(left = "20%", top = "12.5%", bottom = "25%") %>%
908
+ e_tooltip(
909
+ formatter = htmlwidgets::JS("function(params){
910
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
911
+ }")
912
+
913
+ )
914
+ }
915
+ })
916
+
917
+ output$pred_paperless <- renderEcharts4r({
918
+ if(input$customer == "---All Customers---"){
919
+ outpred() |>
920
+ count(paperless_billing) |>
921
+ mutate(pct = round(n/sum(n)*100, 2)) |>
922
+ e_charts(paperless_billing) %>%
923
+ e_pie(pct) |>
924
+ e_labels(show = FALSE) %>%
925
+ e_title("Paperless Billing") |>
926
+ e_legend(show = TRUE, type = "plain", orient = "vertical", left = "right") |>
927
+ e_dims(height = 190) |>
928
+ e_tooltip(
929
+ formatter = htmlwidgets::JS("function(params){
930
+ return(params.name + ': ' + params.value + '%')
931
+ }")
932
+ )
933
+ } else {
934
+ pp <- reactive(outpred() %>%
935
+ filter(customer_id == input$customer) %>%
936
+ pull(paperless_billing) %>%
937
+ str_replace("\\s", "-"))
938
 
939
+ outpred() %>%
940
+ filter(customer_id == input$customer) %>%
941
+ count(paperless_billing) |>
942
+ mutate(pct = round(n/sum(n)*100, 2)) |>
943
+ e_charts(paperless_billing) %>%
944
+ e_pie(pct) |>
945
+ e_labels(show = FALSE) %>%
946
+ e_image_g(top = "15%",
947
+ left = "40%",
948
+ z = 999,
949
+ style = list(image = paste0(pp(), ".png"),
950
+ width = 120,
951
+ height = 120)
952
+ ) |>
953
+ e_dims(width = 200, height = 190) %>%
954
+ e_title("Paperless Billing")
955
+ }
956
+ })
957
+
958
+ output$pred_offer <- renderEcharts4r({
959
+ if(input$customer == "---All Customers---"){
960
+ outpred() |>
961
+ count(offer) |>
962
+ mutate(offer = str_remove(offer, "Offer "),
963
+ pct = round(n/sum(n), 4)) |>
964
+ arrange(n) %>%
965
+ e_charts(offer) |>
966
+ e_bar(pct, legend = FALSE) |>
967
+ e_title("Offer") |>
968
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
969
+ e_flip_coords() %>%
970
+ e_dims(height = 200) |>
971
+ e_grid(left = "15%", top = "12.5%", bottom = "25%", right = "10%") %>%
972
+ e_tooltip(
973
+ formatter = htmlwidgets::JS("function(params){
974
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
975
+ }")
976
+ )
977
+ } else {
978
+ po <- reactive(outpred() %>%
979
+ filter(customer_id == input$customer) %>%
980
+ mutate(offer = str_remove(offer, "Offer ")) %>%
981
+ pull(offer) %>%
982
+ str_replace("\\s", "-"))
983
+
984
+ outpred() %>%
985
+ filter(customer_id == input$customer) %>%
986
+ mutate(offer = str_remove(offer, "Offer ")) %>%
987
+ count(offer) |>
988
+ mutate(offer = str_remove(offer, "Offer "),
989
+ pct = round(n/sum(n), 4)) |>
990
+ arrange(n) %>%
991
+ e_charts(offer) |>
992
+ e_bar(pct, legend = FALSE) |>
993
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
994
+ e_flip_coords() %>%
995
+ e_image_g(top = "15%",
996
+ left = "40%",
997
+ z = 999,
998
+ style = list(image = paste0(po(), ".png"),
999
+ width = 120,
1000
+ height = 120)
1001
+ ) |>
1002
+ e_grid(left = "15%", top = "12.5%", bottom = "25%", right = "10%") %>%
1003
+ e_dims(width = 200, height = 200) %>%
1004
+ e_title("Offer")
1005
+ }
1006
+ })
1007
+
1008
+ output$pred_tenure <- renderEcharts4r({
1009
+ if(input$customer == "---All Customers---"){
1010
+ outpred() |>
1011
+ mutate(tenure_grp = case_when(tenure_in_months < 12 ~ " < 1 year",
1012
+ tenure_in_months < 24 ~ " < 2 year",
1013
+ tenure_in_months < 36 ~ " < 3 year",
1014
+ tenure_in_months < 48 ~ " < 4 year",
1015
+ TRUE ~ "4+ year")) %>%
1016
+ count(tenure_grp) %>%
1017
+ mutate(pct = round(n/sum(n), 4)) |>
1018
+ arrange(n) %>%
1019
+ e_charts(tenure_grp) |>
1020
+ e_bar(pct, legend = FALSE) |>
1021
+ e_title("Tenure") |>
1022
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
1023
+ e_flip_coords() %>%
1024
+ e_dims(height = 200) |>
1025
+ e_grid(left = "25%", top = "12.5%", bottom = "25%", right = "10%") %>%
1026
+ e_tooltip(
1027
+ formatter = htmlwidgets::JS("function(params){
1028
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
1029
+ }")
1030
+ )
1031
+ } else {
1032
+ outpred() |>
1033
+ filter(customer_id == input$customer) %>%
1034
+ mutate(tenure_grp = case_when(tenure_in_months < 12 ~ " < 1 year",
1035
+ tenure_in_months < 24 ~ " < 2 year",
1036
+ tenure_in_months < 36 ~ " < 3 year",
1037
+ tenure_in_months < 48 ~ " < 4 year",
1038
+ TRUE ~ "4+ year")) %>%
1039
+ count(tenure_grp) %>%
1040
+ mutate(pct = round(n/sum(n), 4)) |>
1041
+ arrange(n) %>%
1042
+ e_charts(tenure_grp) |>
1043
+ e_bar(pct, legend = FALSE) |>
1044
+ e_title("Tenure") |>
1045
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
1046
+ e_flip_coords() %>%
1047
+ e_dims(height = 200) |>
1048
+ e_grid(left = "25%", top = "12.5%", bottom = "25%", right = "10%") %>%
1049
+ e_tooltip(
1050
+ formatter = htmlwidgets::JS("function(params){
1051
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
1052
+ }")
1053
+ )
1054
+ }
1055
+ })
1056
+
1057
+ output$pred_contract <- renderEcharts4r({
1058
+ if(input$customer == "---All Customers---"){
1059
+ outpred() |>
1060
+ count(contract) %>%
1061
+ mutate(pct = round(n/sum(n), 4)) |>
1062
+ arrange(n) %>%
1063
+ e_charts(contract) |>
1064
+ e_bar(pct, legend = FALSE) |>
1065
+ e_title("Contract Type") |>
1066
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
1067
+ e_flip_coords() %>%
1068
+ e_dims(height = 200) |>
1069
+ e_grid(left = "45%", top = "12.5%", bottom = "25%", right = "10%") %>%
1070
+ e_tooltip(
1071
+ formatter = htmlwidgets::JS("function(params){
1072
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
1073
+ }")
1074
+ )
1075
+ } else {
1076
+ outpred() |>
1077
+ filter(customer_id == input$customer) %>%
1078
+ count(contract) %>%
1079
+ mutate(pct = round(n/sum(n), 4)) |>
1080
+ arrange(n) %>%
1081
+ e_charts(contract) |>
1082
+ e_bar(pct, legend = FALSE) |>
1083
+ e_title("Contract Type") |>
1084
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
1085
+ e_flip_coords() %>%
1086
+ e_dims(height = 200) |>
1087
+ e_grid(left = "45%", top = "12.5%", bottom = "25%", right = "10%") %>%
1088
+ e_tooltip(
1089
+ formatter = htmlwidgets::JS("function(params){
1090
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
1091
+ }")
1092
  )
1093
+ }
1094
+ })
1095
+
1096
+ output$pred_internet_type <- renderEcharts4r({
1097
+ if(input$customer == "---All Customers---"){
1098
+ outpred() |>
1099
+ count(internet_type) |>
1100
+ mutate(pct = round(n/sum(n), 4)) |>
1101
+ arrange(n) %>%
1102
+ e_charts(internet_type) |>
1103
+ e_bar(pct, legend = FALSE) |>
1104
+ e_title("Internet Service Type") |>
1105
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
1106
+ e_flip_coords() %>%
1107
+ e_dims(width = 600, height = 285) |>
1108
+ e_grid(left = "15%", top = "12.5%", bottom = "20%", right = "15%") %>%
1109
+ e_tooltip(
1110
+ formatter = htmlwidgets::JS("function(params){
1111
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
1112
+ }")
1113
+ )
1114
+ } else {
1115
+ outpred() |>
1116
+ filter(customer_id == input$customer) %>%
1117
+ count(internet_type) |>
1118
+ mutate(pct = round(n/sum(n), 4)) |>
1119
+ arrange(n) %>%
1120
+ e_charts(internet_type) |>
1121
+ e_bar(pct, legend = FALSE) |>
1122
+ e_title("Internet Service Type") |>
1123
+ e_y_axis(formatter = e_axis_formatter(style = "percent")) %>%
1124
+ e_flip_coords() %>%
1125
+ e_dims(width = 600, height = 285) |>
1126
+ e_grid(left = "15%", top = "12.5%", bottom = "20%", right = "15%") %>%
1127
+ e_tooltip(
1128
+ formatter = htmlwidgets::JS("function(params){
1129
+ return(params.name + ': ' + Math.round(params.value[0]*10000)/100 + '%')
1130
+ }")
1131
+ )
1132
+ }
1133
+ })
1134
 
1135
+ observe({
1136
+ if(input$customer == "---All Customers---"){
1137
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb1", value = round(sum(outpred()$premium_tech_support == "Yes")/nrow(outpred())*100, 2), title = "Premium Tech Support")
1138
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb2", value = round(sum(outpred()$phone_service == "Yes")/nrow(outpred())*100, 2), title = "Phone Service")
1139
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb3", value = round(sum(outpred()$multiple_lines == "Yes")/nrow(outpred())*100, 2), title = "Multiple Lines")
1140
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb4", value = round(sum(outpred()$online_security == "Yes")/nrow(outpred())*100, 2), title = "Online Security")
1141
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb5", value = round(sum(outpred()$online_backup == "Yes")/nrow(outpred())*100, 2), title = "Online Backup")
1142
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb6", value = round(sum(outpred()$device_protection_plan == "Yes")/nrow(outpred())*100, 2), title = "Device Protection Plan")
1143
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb7", value = round(sum(outpred()$streaming_tv == "Yes")/nrow(outpred())*100, 2), title = "Streaming TV")
1144
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb8", value = round(sum(outpred()$streaming_music == "Yes")/nrow(outpred())*100, 2), title = "Streaming Music")
1145
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb9", value = round(sum(outpred()$streaming_movies == "Yes")/nrow(outpred())*100, 2), title = "Streaming Movies")
1146
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb10", value = round(sum(outpred()$unlimited_data == "Yes")/nrow(outpred())*100, 2), title = "Unlimited Data")
1147
+ } else {
1148
+ cust_data <- outpred() %>%
1149
+ filter(customer_id == input$customer)
1150
+
1151
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb1", value = (cust_data$premium_tech_support == "Yes")*100, title = "Premium Tech Support")
1152
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb2", value = (cust_data$phone_service == "Yes")*100, title = "Phone Service")
1153
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb3", value = (cust_data$multiple_lines == "Yes")*100, title = "Multiple Lines")
1154
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb4", value = (cust_data$online_security == "Yes")*100, title = "Online Security")
1155
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb5", value = (cust_data$online_backup == "Yes")*100, title = "Online Backup")
1156
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb6", value = (cust_data$device_protection_plan == "Yes")*100, title = "Device Protection Plan")
1157
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb7", value = (cust_data$streaming_tv == "Yes")*100, title = "Streaming TV")
1158
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb8", value = (cust_data$streaming_music == "Yes")*100, title = "Streaming Music")
1159
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb9", value = (cust_data$streaming_movies == "Yes")*100, title = "Streaming Movies")
1160
+ shinyWidgets::updateProgressBar(session = session, id = "pred_pb10", value = (cust_data$unlimited_data == "Yes")*100, title = "Unlimited Data")
1161
+ }
1162
+ })
1163
+ }
1164
 
1165
  shinyApp(ui, server)