|
@@ -0,0 +1,135 @@
|
|
1
|
+library(reticulate)
|
|
2
|
+library(shiny)
|
|
3
|
+library(dplyr)
|
|
4
|
+library(ggplot2)
|
|
5
|
+library(shinycssloaders)
|
|
6
|
+library(TSA)
|
|
7
|
+theme_set(theme_bw())
|
|
8
|
+
|
|
9
|
+p <- import("pandas")
|
|
10
|
+aggdf <- p$read_pickle("../data/9-clusters.agg.pkl")
|
|
11
|
+aggdf$cluster <- factor(aggdf$cluster)
|
|
12
|
+sns <- import("seaborn")
|
|
13
|
+
|
|
14
|
+models <- readRDS('../models/1kmods.rds')
|
|
15
|
+clusters = names(models)
|
|
16
|
+cbp <- as.character(p$Series(sns$color_palette("colorblind", as.integer(length(clusters)))$as_hex()))
|
|
17
|
+names(cbp) <- clusters
|
|
18
|
+minhwm <- readRDS("../models/weatherMinharmonic.rds")
|
|
19
|
+maxhwm <- readRDS("../models/weatherMaxharmonic.rds")
|
|
20
|
+monthchoices <- 1:12
|
|
21
|
+names(monthchoices) <- month.name
|
|
22
|
+weekdaychoices = 1:7
|
|
23
|
+names(weekdaychoices) = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+ui <- navbarPage("Counties Power demand modelling", collapsible = TRUE, selected = "Prediction",
|
|
27
|
+ tabPanel("Data and model",
|
|
28
|
+ plotOutput("dataPlot") %>% withSpinner(type = 5),
|
|
29
|
+ fluidRow(
|
|
30
|
+ column(4,
|
|
31
|
+ selectInput("selDR", "Cluster", choices = clusters, selected = clusters[1])
|
|
32
|
+ ),
|
|
33
|
+ column(4,
|
|
34
|
+ dateRangeInput("dpDR", "Date range", start = min(as.Date(aggdf$read_time)),
|
|
35
|
+ end = max(as.Date(aggdf$read_time)),
|
|
36
|
+ min = min(as.Date(aggdf$read_time)),
|
|
37
|
+ max = max(as.Date(aggdf$read_time)),
|
|
38
|
+ format = "dd/mm/yyyy")
|
|
39
|
+ ),
|
|
40
|
+ column(4, p(paste("Point represents mean value of cluster, coloured line represents model prediction of",
|
|
41
|
+ "mean value of cluster."))
|
|
42
|
+ )
|
|
43
|
+ )),
|
|
44
|
+ tabPanel("Prediction",
|
|
45
|
+ plotOutput("predPlot") %>% withSpinner(type = 5),
|
|
46
|
+ fluidRow(
|
|
47
|
+ column(8,
|
|
48
|
+ sliderInput("temprange", "Temperature range", min = 0, max = 30, value = c(10, 18), width = "100%", post = " °C",
|
|
49
|
+ step = 0.5, dragRange = TRUE)),
|
|
50
|
+ column(2,
|
|
51
|
+ selectInput("predmon", "Month (approximate)", monthchoices, selected = 1, width = "100%")
|
|
52
|
+ ),
|
|
53
|
+ column(2,
|
|
54
|
+ selectInput("predday", "Day of week", weekdaychoices, selected = 2, width = "100%")
|
|
55
|
+ )
|
|
56
|
+ ),
|
|
57
|
+
|
|
58
|
+ h5("Number of ICPs of each cluster serviced by node:"),
|
|
59
|
+ fluidRow(
|
|
60
|
+ column(1, numericInput("c1v", "1:", value = 1, min = 0, step = 1, width = "100%"), offset = 0),
|
|
61
|
+ column(1, numericInput("c2v", "2:", value = 1, min = 0, step = 1, width = "100%")),
|
|
62
|
+ column(1, numericInput("c3v", "3:", value = 1, min = 0, step = 1, width = "100%")),
|
|
63
|
+ column(1, numericInput("c4v", "4:", value = 1, min = 0, step = 1, width = "100%")),
|
|
64
|
+ column(1, numericInput("c5v", "5:", value = 1, min = 0, step = 1, width = "100%")),
|
|
65
|
+ column(1, numericInput("c6v", "6:", value = 1, min = 0, step = 1, width = "100%")),
|
|
66
|
+ column(1, numericInput("c7v", "7:", value = 1, min = 0, step = 1, width = "100%")),
|
|
67
|
+ column(1, numericInput("c8v", "8:", value = 1, min = 0, step = 1, width = "100%")),
|
|
68
|
+ column(1, numericInput("c9v", "9:", value = 1, min = 0, step = 1, width = "100%"))
|
|
69
|
+ )
|
|
70
|
+
|
|
71
|
+ )
|
|
72
|
+ )
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+server <- function(input, output) {
|
|
76
|
+ output$dataPlot <- renderPlot({
|
|
77
|
+ clus <- input$selDR
|
|
78
|
+ fildf <- filter(aggdf, cluster %in% clus) %>%
|
|
79
|
+ mutate(r = resid(models[[clus]]), f = fitted(models[[clus]])) %>%
|
|
80
|
+ filter(read_time >= as.POSIXct(input$dpDR[1], tz = "UTC"), read_time <= as.POSIXct(input$dpDR[2], tz = "UTC"))
|
|
81
|
+
|
|
82
|
+ yrange = range(c(range(fildf$f), range(fildf$kwh_tot_mean)))
|
|
83
|
+ dplot <- ggplot(fildf, aes(x = read_time, y = f, color = cluster))
|
|
84
|
+
|
|
85
|
+ dplot <- dplot + geom_line(size = 2)
|
|
86
|
+
|
|
87
|
+ dplot <- dplot + geom_point(aes(y = kwh_tot_mean), color = "black")
|
|
88
|
+
|
|
89
|
+ dplot <- dplot + coord_cartesian(xlim = as.POSIXct(input$dpDR, tz = "UTC"),
|
|
90
|
+ ylim = c(yrange[1] - (yrange[2] - yrange[1]) * 0.05,
|
|
91
|
+ yrange[2] + (yrange[2] - yrange[1]) * 0.05),
|
|
92
|
+ expand = FALSE)
|
|
93
|
+
|
|
94
|
+ dplot <- dplot + scale_color_manual(values = cbp)
|
|
95
|
+ dplot <- dplot + theme(legend.position = "none")
|
|
96
|
+
|
|
97
|
+ dplot <- dplot + labs(y = "kwh", x = "Date/Time", caption = sprintf("Cluster: %s", clus))
|
|
98
|
+
|
|
99
|
+ return(dplot)
|
|
100
|
+ })
|
|
101
|
+
|
|
102
|
+ prediction <- reactive({
|
|
103
|
+ numeclus <- c(input$c1v,input$c2v,input$c3v,input$c4v,input$c5v,input$c6v,input$c7v,input$c8v,input$c9v)
|
|
104
|
+ numeclus[is.na(numeclus)] <- 0
|
|
105
|
+ ystart <- floor((as.numeric(input$predmon) - 0.5) / 12 * 365.25 * 48)
|
|
106
|
+ harm.y <- ts(1:48, frequency = 365.25 * 48, start = c(1, ystart)) %>% harmonic(2)
|
|
107
|
+ harm.w <- ts(1:48, frequency = 7 * 48, start = c(1, 48 * as.numeric(input$predday))) %>% harmonic(3)
|
|
108
|
+ harm.d <- ts(1:48, frequency = 48, start = c(1, 1)) %>% harmonic(3)
|
|
109
|
+ colnames(harm.y) <- sprintf("%s.%s.%s", "year", rep(c("cos", "sin"), each = ncol(harm.y)/2), rep(1:(ncol(harm.y)/2), times = 2))
|
|
110
|
+ colnames(harm.w) <- sprintf("%s.%s.%s", "week", rep(c("cos", "sin"), each = ncol(harm.w)/2), rep(1:(ncol(harm.w)/2), times = 2))
|
|
111
|
+ colnames(harm.d) <- sprintf("%s.%s.%s", "day", rep(c("cos", "sin"), each = ncol(harm.d)/2), rep(1:(ncol(harm.d)/2), times = 2))
|
|
112
|
+ yharm <- harmonic(ts(1:48, frequency = floor(365.25 * 48), start = c(1, ystart)), 2)
|
|
113
|
+ harnames <- paste0("yharm", colnames(yharm))
|
|
114
|
+ # yharm <- as.data.frame(yharm)
|
|
115
|
+ colnames(yharm) <- harnames
|
|
116
|
+ wmmin <- input$temprange[1] - predict(minhwm, as.data.frame(yharm))
|
|
117
|
+ wmmax <- input$temprange[2] - predict(maxhwm, as.data.frame(yharm))
|
|
118
|
+ predinp <- data.frame(resmin = wmmin, resmax = wmmax)
|
|
119
|
+ predinp <- cbind(predinp, harm.y, harm.w, harm.d)
|
|
120
|
+ predvec = rep(0, 48)
|
|
121
|
+ for (c in 1:length(clusters)) {
|
|
122
|
+ predvec <- predvec + numeclus[c] * predict(models[[c]], predinp)
|
|
123
|
+ }
|
|
124
|
+ return(data.frame(x = 1:48, y = predvec))
|
|
125
|
+ })
|
|
126
|
+
|
|
127
|
+ output$predPlot <- renderPlot({
|
|
128
|
+ predf <- prediction()
|
|
129
|
+ ggplot(predf, aes(x, y)) + geom_line()
|
|
130
|
+ })
|
|
131
|
+
|
|
132
|
+}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+shinyApp(ui = ui, server = server)
|