For Homework 4, we developed a shiny app to visualize the electricity consumption.
In this app:
User can filter the data by selecting a beginning and an end date.
With display button, user can display the filtered data as a table; this summary table includes the date, hour, consumption and average temperature values.
With plot button, user can reach 3 plots;
1- Average hourly consumption over the filtered time period
2- Average hourly temperature values for multiple cities and overall average
3- (BONUS) Two days ahead forecasted consumption values
Plots are rescaled with each date selection to reflect on the min and max values of selected dates.
Since we user lag-48 approach for forecasting, to see the forecasting plot; the selected end date should be no later than December 27, 2019. If user selects an end date after this date, a warning is displayed below the date range selection component.
If user selects an end date before the starting date, a warning message is displayed for the use; stating that the end date should be on or after the start date.
# Include libraries
library("data.table")
library("shiny")
# Create the user interface for the app
ui = fluidPage(
headerPanel("Electricity Consumption"),
column(4, mainPanel(
# Ask for dates to be filted
dateRangeInput("date_range_input",
"Please select a date range; and click \"Display\" to see consumption and temperature values as a table, and click \"Plot\" to see the statistics of consumption and temperature as a plot. Please note that for forecasting plot; end date should be on or before December 27, 2019.",
start = "2017-01-01",
end = "2019-12-29",
min = "2017-01-01",
max = "2019-12-29",
weekstart = 1,
width = "400px",),
actionButton("button_display", "Display"),
actionButton("button_plot", "Plot"),
textOutput("warning"),
)),
# Create table for data display
column(4, tableOutput("table")),
# Create plot for graphing
column(4, plotOutput("plot_consumption"),
plotOutput("plot_temperature"),
plotOutput("plot_forecast"))
)
# Create the server for the app
server = function(input, output)
{
# Store data to be displayed
data = fread("ETM58D_Spring20 HW 4_electricity_load_Turkey.csv")
# Convert "Date" to "Date" type
data_date = data
data_date[, Date:=as.Date(Date, format = '%Y-%m-%d')]
# Filter data for table
data_table_output = eventReactive(input$button_display, {
shiny::validate(
shiny::need(input$date_range_input[2]>input$date_range_input[1],"Warning: End date must be on or after start date!")
)
# if (as.integer(input$date_range_input[2]) < as.integer(input$date_range_input[1]))
# output$warning = renderText("Warning: End date must be on or after start date!")
# else
{
output$warning = renderText("")
filtered_data = data_date[data_date$Date >= input$date_range_input[1] &
data_date$Date <= input$date_range_input[2]]
data_table = filtered_data[, 1:3]
data_table = data_table[, "Avg Temp":=((filtered_data$T_1 +
filtered_data$T_2 +
filtered_data$T_3 +
filtered_data$T_4 +
filtered_data$T_5 +
filtered_data$T_6 +
filtered_data$T_7)/7)]
# Convert back "Date" to "Character" type
data_display = data_table
data_display[, Date:=as.character(Date)]
}
})
# Filter data for consumption plot
data_plot_consumption = eventReactive(input$button_plot, {
if (as.integer(input$date_range_input[2]) < as.integer(input$date_range_input[1]))
output$warning = renderText("Warning: End date must be on or after start date!")
else
{
output$warning = renderText("")
filtered_data = data_date[data_date$Date >= input$date_range_input[1] &
data_date$Date <= input$date_range_input[2]]
# Calculate data for consumption plot
data_plot_c = unique(filtered_data[,list(Hour)])
data_plot_c = data_plot_c[, Avg_Consumption := 0]
for(i in 0:23)
data_plot_c[i + 1, 2] = mean(filtered_data$Consumption[filtered_data$Hour == i])
plot(data_plot_c$Hour, data_plot_c$Avg_Consumption, type = "b", col = "blue", xlab = "Hours", ylab = "Average Consumption", main = "Consumption Plot")
}
})
# Filter data for temperature plot
data_plot_temperature = eventReactive(input$button_plot, {
if (as.integer(input$date_range_input[2]) < as.integer(input$date_range_input[1]))
output$warning = renderText("Warning: End date must be on or after start date!")
else
{
output$warning = renderText("")
filtered_data = data_date[data_date$Date >= input$date_range_input[1] &
data_date$Date <= input$date_range_input[2]]
# Calculate data for temperature plot
data_plot_t = unique(filtered_data[,list(Hour)])
data_plot_t = data_plot_t[, Avg_T1 := 0]
data_plot_t = data_plot_t[, Avg_T2 := 0]
data_plot_t = data_plot_t[, Avg_T3 := 0]
data_plot_t = data_plot_t[, Avg_T4 := 0]
data_plot_t = data_plot_t[, Avg_T5 := 0]
data_plot_t = data_plot_t[, Avg_T6 := 0]
data_plot_t = data_plot_t[, Avg_T7 := 0]
data_plot_t = data_plot_t[, Avg_Temperature := 0]
for(i in 0:23)
{
data_plot_t[i + 1, 2] = mean(filtered_data$T_1[filtered_data$Hour == i])
data_plot_t[i + 1, 3] = mean(filtered_data$T_2[filtered_data$Hour == i])
data_plot_t[i + 1, 4] = mean(filtered_data$T_3[filtered_data$Hour == i])
data_plot_t[i + 1, 5] = mean(filtered_data$T_4[filtered_data$Hour == i])
data_plot_t[i + 1, 6] = mean(filtered_data$T_5[filtered_data$Hour == i])
data_plot_t[i + 1, 7] = mean(filtered_data$T_6[filtered_data$Hour == i])
data_plot_t[i + 1, 8] = mean(filtered_data$T_7[filtered_data$Hour == i])
data_plot_t[i + 1, 9] = mean(c(filtered_data$T_1[filtered_data$Hour == i],
filtered_data$T_2[filtered_data$Hour == i],
filtered_data$T_3[filtered_data$Hour == i],
filtered_data$T_4[filtered_data$Hour == i],
filtered_data$T_5[filtered_data$Hour == i],
filtered_data$T_6[filtered_data$Hour == i],
filtered_data$T_7[filtered_data$Hour == i]))
}
y_min = min(data_plot_t$Avg_Temperature,
data_plot_t$Avg_T1,
data_plot_t$Avg_T2,
data_plot_t$Avg_T3,
data_plot_t$Avg_T4,
data_plot_t$Avg_T5,
data_plot_t$Avg_T6,
data_plot_t$Avg_T7)
y_max = max(data_plot_t$Avg_Temperature,
data_plot_t$Avg_T1,
data_plot_t$Avg_T2,
data_plot_t$Avg_T3,
data_plot_t$Avg_T4,
data_plot_t$Avg_T5,
data_plot_t$Avg_T6,
data_plot_t$Avg_T7)
plot(data_plot_t$Hour, data_plot_t$Avg_Temperature, type = "b", col = 1, xlab = "Hours", ylab = "Average Temperature", main = "Temperature Plot", ylim = c(y_min, y_max))
points(data_plot_t$Hour, data_plot_t$Avg_T1, type = "l", col = 2)
lines(data_plot_t$Hour, data_plot_t$Avg_T1, type = "l", col = 2)
points(data_plot_t$Hour, data_plot_t$Avg_T2, type = "l", col = 3)
lines(data_plot_t$Hour, data_plot_t$Avg_T2, type = "l", col = 3)
points(data_plot_t$Hour, data_plot_t$Avg_T3, type = "l", col = 4)
lines(data_plot_t$Hour, data_plot_t$Avg_T3, type = "l", col = 4)
points(data_plot_t$Hour, data_plot_t$Avg_T4, type = "l", col = 5)
lines(data_plot_t$Hour, data_plot_t$Avg_T4, type = "l", col = 5)
points(data_plot_t$Hour, data_plot_t$Avg_T5, type = "l", col = 6)
lines(data_plot_t$Hour, data_plot_t$Avg_T5, type = "l", col = 6)
points(data_plot_t$Hour, data_plot_t$Avg_T6, type = "l", col = 7)
lines(data_plot_t$Hour, data_plot_t$Avg_T6, type = "l", col = 7)
points(data_plot_t$Hour, data_plot_t$Avg_T7, type = "l", col = 8)
lines(data_plot_t$Hour, data_plot_t$Avg_T7, type = "l", col = 8)
legend("topleft", legend = c("Avg","T1","T2","T3","T4","T5","T6","T7"), col=1:8, pch=1)
}
})
# Filter data for forecast plot
data_plot_forecast = eventReactive(input$button_plot, {
if (as.integer(input$date_range_input[2]) > as.Date("2019-12-27"))
output$warning = renderText("Warning: For forecasting; please pick a date on or before December 27, 2019!")
else if (as.integer(input$date_range_input[2]) < as.integer(input$date_range_input[1]))
output$warning = renderText("Warning: End date must be on or after start date!")
else
{
output$warning = renderText("")
# Add forecast data and remove N/A's
data_date = data_date[, lag_48:=shift(data_date[,3],48)]
data_date = data_date[complete.cases(data_date)]
filtered_data = data_date[data_date$Date == as.character(input$date_range_input[2] + 2)]
plot(filtered_data$Hour, filtered_data$lag_48, type = "b", col = "green", xlab = "Hours", ylab = "Forecast", main = "Lag 48 Forecast Plot")
}
})
# Display data
output$table = renderTable({input$button_display
data_table_output()
})
output$plot_consumption = renderPlot({input$button_plot
data_plot_consumption()
grid()
})
output$plot_temperature = renderPlot({input$button_plot
data_plot_temperature()
grid()
})
output$plot_forecast = renderPlot({input$button_plot
data_plot_forecast()
grid()
})
}
# Call shiny
shinyApp(ui = ui, server = server)