# Import library yang dibutuhkan
library(readr)     # untuk membaca csv
library(dplyr)     # untuk manipulasi data
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)   # untuk visualisasi
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.5.1
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(tseries)

Load Data

Load data wifi

# Baca dataset wifi
wifi_df <- read_csv("wifi.csv")
## Rows: 1883844 Columns: 7
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (4): Event Time, Uni, Building, Floor
## dbl  (2): Associated Client Count, Authenticated Client Count
## dttm (1): time
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(wifi_df)
## # A tibble: 6 × 7
##   time                `Event Time` Associated Client Co…¹ Authenticated Client…²
##   <dttm>              <chr>                         <dbl>                  <dbl>
## 1 2020-02-01 00:02:12 Sat Feb 01 …                    184                    182
## 2 2020-02-01 00:02:12 Sat Feb 01 …                      6                      6
## 3 2020-02-01 00:02:12 Sat Feb 01 …                     18                     18
## 4 2020-02-01 00:02:12 Sat Feb 01 …                     23                     23
## 5 2020-02-01 00:02:12 Sat Feb 01 …                     45                     45
## 6 2020-02-01 00:02:12 Sat Feb 01 …                     16                     16
## # ℹ abbreviated names: ¹​`Associated Client Count`,
## #   ²​`Authenticated Client Count`
## # ℹ 3 more variables: Uni <chr>, Building <chr>, Floor <chr>
 wifi_library <- wifi_df %>%
   filter(trimws(Building) == "Library") %>%
   mutate(time = ymd_hms(time))
 
 wifi_resampled <- wifi_library %>%
   mutate(time=floor_date(time,"10 minutes")) %>%
   group_by(time) %>%
   summarise(`Associated Client Count`=mean(`Associated Client Count`,na.rm=TRUE))
 
 wifi_resampled <- wifi_resampled %>%
  rename(occupancy = `Associated Client Count`)
 
 head(wifi_resampled)
## # A tibble: 6 × 2
##   time                occupancy
##   <dttm>                  <dbl>
## 1 2020-02-01 00:00:00      22.8
## 2 2020-02-01 00:10:00      20.6
## 3 2020-02-01 00:20:00      17.2
## 4 2020-02-01 00:30:00      15.4
## 5 2020-02-01 00:40:00      12.4
## 6 2020-02-01 00:50:00      10.5

Load data library

lib1 <- read_csv("library1.csv")
## Rows: 18864 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (2): name, units
## dbl  (3): reading, cumulative, rate
## dttm (1): ts
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
lib2 <- read_csv("library2.csv")
## Rows: 18864 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (2): name, units
## dbl  (3): reading, cumulative, rate
## dttm (1): ts
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
lib3 <- read_csv("library3.csv")
## Rows: 18864 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (2): name, units
## dbl  (3): reading, cumulative, rate
## dttm (1): ts
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(lib1)
## # A tibble: 6 × 6
##   ts                  name              reading units cumulative  rate
##   <dttm>              <chr>               <dbl> <chr>      <dbl> <dbl>
## 1 2020-01-01 00:00:00 MC065-L01/M9R2048 1489442 KWh      1489442    NA
## 2 2020-01-01 00:10:00 MC065-L01/M9R2048 1489449 KWh      1489449     7
## 3 2020-01-01 00:20:00 MC065-L01/M9R2048 1489456 KWh      1489456     7
## 4 2020-01-01 00:30:00 MC065-L01/M9R2048 1489464 KWh      1489464     8
## 5 2020-01-01 00:40:00 MC065-L01/M9R2048 1489471 KWh      1489471     7
## 6 2020-01-01 00:50:00 MC065-L01/M9R2048 1489479 KWh      1489479     8
head(lib2)
## # A tibble: 6 × 6
##   ts                  name               reading units cumulative  rate
##   <dttm>              <chr>                <dbl> <chr>      <dbl> <dbl>
## 1 2020-01-01 00:00:00 MC065-L01/M11R2056 2129016 KWh      2129016    NA
## 2 2020-01-01 00:10:00 MC065-L01/M11R2056 2129034 KWh      2129034    18
## 3 2020-01-01 00:20:00 MC065-L01/M11R2056 2129054 KWh      2129054    20
## 4 2020-01-01 00:30:00 MC065-L01/M11R2056 2129071 KWh      2129071    17
## 5 2020-01-01 00:40:00 MC065-L01/M11R2056 2129086 KWh      2129086    15
## 6 2020-01-01 00:50:00 MC065-L01/M11R2056 2129103 KWh      2129103    17
head(lib3)
## # A tibble: 6 × 6
##   ts                  name               reading units cumulative  rate
##   <dttm>              <chr>                <dbl> <chr>      <dbl> <dbl>
## 1 2020-01-01 00:00:00 MC065-L01/M13R2064 6914209 KWh      6914209    NA
## 2 2020-01-01 00:10:00 MC065-L01/M13R2064 6914266 KWh      6914266    57
## 3 2020-01-01 00:20:00 MC065-L01/M13R2064 6914310 KWh      6914310    44
## 4 2020-01-01 00:30:00 MC065-L01/M13R2064 6914376 KWh      6914376    66
## 5 2020-01-01 00:40:00 MC065-L01/M13R2064 6914439 KWh      6914439    63
## 6 2020-01-01 00:50:00 MC065-L01/M13R2064 6914474 KWh      6914474    35
lib1 <- lib1 %>%
  mutate(ts=ymd_hms(ts))%>%
  arrange(ts)
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `ts = ymd_hms(ts)`.
## Caused by warning:
## !  131 failed to parse.
lib2 <- lib2 %>%
  mutate(ts=ymd_hms(ts))%>%
  arrange(ts)
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `ts = ymd_hms(ts)`.
## Caused by warning:
## !  131 failed to parse.
lib3 <- lib3 %>%
  mutate(ts=ymd_hms(ts))%>%
  arrange(ts)
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `ts = ymd_hms(ts)`.
## Caused by warning:
## !  131 failed to parse.
electricity_df <- data.frame(
  time = lib1$ts,
  library_1 = lib1$rate,
  library_2 = lib2$rate,
  library_3 = lib3$rate,
  total_rate = lib1$rate + lib2$rate + lib3$rate
)

dim(electricity_df)
## [1] 18864     5
head(electricity_df)
##                  time library_1 library_2 library_3 total_rate
## 1 2020-01-01 00:10:00         7        18        57         82
## 2 2020-01-01 00:20:00         7        20        44         71
## 3 2020-01-01 00:30:00         8        17        66         91
## 4 2020-01-01 00:40:00         7        15        63         85
## 5 2020-01-01 00:50:00         8        17        35         60
## 6 2020-01-01 01:00:00         7        17        47         71
electricity_df <- electricity_df %>%
  mutate(
    across(
      c(library_1, library_2, library_3),
      ~ ifelse(is.na(.x), mean(head(.x, 144), na.rm = TRUE), .x)
    )
  ) %>%
  mutate(total_rate = library_1 + library_2 + library_3)

head(electricity_df)
##                  time library_1 library_2 library_3 total_rate
## 1 2020-01-01 00:10:00         7        18        57         82
## 2 2020-01-01 00:20:00         7        20        44         71
## 3 2020-01-01 00:30:00         8        17        66         91
## 4 2020-01-01 00:40:00         7        15        63         85
## 5 2020-01-01 00:50:00         8        17        35         60
## 6 2020-01-01 01:00:00         7        17        47         71
# Merge by time
merged_df <- inner_join(electricity_df, wifi_resampled, by = "time")

# Cek hasil
dim(merged_df)
## [1] 3657    6
head(merged_df)
##                  time library_1 library_2 library_3 total_rate occupancy
## 1 2020-02-01 00:10:00        13        11        73         97    20.625
## 2 2020-02-01 00:20:00        13        11        72         96    17.250
## 3 2020-02-01 00:30:00        11        15        74        100    15.375
## 4 2020-02-01 00:40:00        11        13        65         89    12.375
## 5 2020-02-01 00:50:00        11        16        64         91    10.500
## 6 2020-02-01 01:00:00        10        16        64         90     9.250

Data Cleaning

# Cek duplikasi index (kalau ada kolom time jadi index)
sum(duplicated(merged_df$time))
## [1] 0
# Cek missing values per kolom
colSums(is.na(merged_df))
##       time  library_1  library_2  library_3 total_rate  occupancy 
##          0          0          0          0          0          0
# Deskripsi data
summary(merged_df)
##       time                       library_1       library_2       library_3     
##  Min.   :2020-02-01 00:10:00   Min.   : 7.00   Min.   : 7.00   Min.   : 29.00  
##  1st Qu.:2020-02-07 09:30:00   1st Qu.:11.00   1st Qu.:19.00   1st Qu.: 73.00  
##  Median :2020-02-13 18:50:00   Median :15.00   Median :33.00   Median :104.00  
##  Mean   :2020-02-13 18:52:54   Mean   :15.18   Mean   :32.44   Mean   : 95.68  
##  3rd Qu.:2020-02-20 04:20:00   3rd Qu.:19.00   3rd Qu.:45.00   3rd Qu.:120.00  
##  Max.   :2020-02-26 13:40:00   Max.   :31.00   Max.   :64.00   Max.   :136.00  
##    total_rate      occupancy      
##  Min.   : 49.0   Min.   :  2.375  
##  1st Qu.:103.0   1st Qu.: 18.625  
##  Median :151.0   Median : 99.125  
##  Mean   :143.3   Mean   :148.696  
##  3rd Qu.:183.0   3rd Qu.:250.125  
##  Max.   :219.0   Max.   :512.125
# Pilih kolom numerik yang relevan (tanpa time)
num_cols <- merged_df %>%
  select(library_1, library_2, library_3, occupancy)

# Reshape untuk ggplot
df_melt <- melt(num_cols)
## No id variables; using all as measure variables
# Plot boxplot
ggplot(df_melt, aes(x = variable, y = value)) +
  geom_boxplot(fill = "skyblue", color = "black") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Boxplot of Library Energy Consumption and Occupancy",
       x = "Variable", y = "Value")

# Hitung IQR
Q1 <- quantile(merged_df$library_3, 0.25, na.rm = TRUE)
Q3 <- quantile(merged_df$library_3, 0.75, na.rm = TRUE)
IQR_val <- Q3 - Q1

lower_bound <- Q1 - 1.5 * IQR_val
upper_bound <- Q3 + 1.5 * IQR_val

# cari outlier
outliers <- merged_df[merged_df$library_3 < lower_bound | 
                        merged_df$library_3 > upper_bound, ]

nrow(outliers)
## [1] 0

Visualization

Time Series

#library occupancy & energy consumption 
library(ggplot2)

ggplot(merged_df, aes(x = time)) +
  geom_line(aes(y = occupancy, color = "Library Occupancy (WiFi)"), size = 0.8) +
  geom_line(aes(y = total_rate, color = "Library Energy Consumption"), size = 0.8) +
  scale_color_manual(values = c("Library Occupancy (WiFi)" = "blue",
                                "Library Energy Consumption" = "orange")) +
  labs(title = "Time Series of Library Occupancy and Energy Consumption (10-min interval)",
       x = "Date",
       y = "Count / Energy Rate",
       color = "") +
  theme_minimal() +
  theme(legend.position = "top",
        plot.title = element_text(hjust = 0.5))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Scatter Plot

library(ggplot2)
ggplot(merged_df, aes(x = occupancy, y = total_rate)) +
  geom_point(alpha = 0.4, colour = "blue", size = 2) +
  ggtitle("Scatter Plot: Occupancy vs Energy Consumption") +
  xlab("Occupancy (WiFi clients)") +
  ylab("Energy Consumption (kWh or units)") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5)
  ) +
  geom_smooth(method = "loess", se = FALSE, linetype = "dashed", alpha = 0.6)
## `geom_smooth()` using formula = 'y ~ x'

Daily Profiles

library(ggplot2)
library(dplyr)
library(tidyr)
## 
## Attaching package: 'tidyr'
## The following object is masked from 'package:reshape2':
## 
##     smiths
library(lubridate)

# Buat kolom jam-menit (waktu dalam sehari) dan tanggal
merged_df <- merged_df %>%
  mutate(
    time_of_day = format(time, "%H:%M:%S"),
    date = as.Date(time)
  )

# Pivot untuk occupancy - menggunakan tidyr::pivot_wider
occupancy_daily <- merged_df %>%
  select(time_of_day, date, occupancy) %>%
  pivot_wider(
    names_from = date,
    values_from = occupancy,
    values_fn = mean  # mengambil rata-rata jika ada duplikasi
  )

# Pivot untuk energy 
energy_daily <- merged_df %>%
  select(time_of_day, date, total_rate) %>%
  pivot_wider(
    names_from = date,
    values_from = total_rate,
    values_fn = mean  # mengambil rata-rata jika ada duplikasi
  )

# Plot Occupancy Daily Profiles

occupancy_plot =ggplot() +
  lapply(names(occupancy_daily)[-1], function(col) {
    geom_line(data = occupancy_daily, 
              aes(x = time_of_day, y = .data[[col]], group = 1), 
              alpha = 0.2, color = "blue")
  }) +
  labs(title = "Daily Profiles of Library Occupancy",
       x = "Time of Day",
       y = "Occupancy") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "none")

print(occupancy_plot)
## Warning: Removed 61 rows containing missing values or values outside the scale range
## (`geom_line()`).

# Plot Energy Daily Profiles
energy_plot = ggplot() +
  lapply(names(energy_daily)[-1], function(col) {
    geom_line(data = energy_daily, 
              aes(x = time_of_day, y = .data[[col]], group = 1), 
              alpha = 0.2, color = "orange")
  }) +
  labs(title = "Daily Profiles of Library Energy Consumption",
       x = "Time of Day",
       y = "Energy Consumption") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "none") + scale_y_continuous(limits = c(50,225), breaks=seq(50,225,25))

print(energy_plot)
## Warning: Removed 61 rows containing missing values or values outside the scale range
## (`geom_line()`).

library(ggplot2)
library(dplyr)
library(tidyr)

# Buat kolom jam-menit (waktu dalam sehari) dan tanggal
merged_df <- merged_df %>%
  mutate(
    time_of_day = format(time, "%H:%M:%S"),
    date = as.Date(time)
  )

# Pivot untuk occupancy - menggunakan pivot_wider
occupancy_daily <- merged_df %>%
  select(time_of_day, date, occupancy) %>%
  pivot_wider(
    names_from = date,
    values_from = occupancy,
    values_fn = mean
  ) %>%
  # Hitung rata-rata untuk setiap time_of_day
  mutate(average = rowMeans(select(., -time_of_day), na.rm = TRUE))

# Pivot untuk energy - menggunakan pivot_wider
energy_daily <- merged_df %>%
  select(time_of_day, date, total_rate) %>%
  pivot_wider(
    names_from = date,
    values_from = total_rate,
    values_fn = mean
  ) %>%
  # Hitung rata-rata untuk setiap time_of_day
  mutate(average = rowMeans(select(., -time_of_day), na.rm = TRUE))

# Plot Occupancy Daily Profiles
ggplot() +
  # Plot semua hari dengan transparansi
  lapply(names(occupancy_daily)[-c(1, ncol(occupancy_daily))], function(col) {
    geom_line(data = occupancy_daily, 
              aes(x = time_of_day, y = .data[[col]], group = 1), 
              alpha = 0.2, color = "blue")
  }) +
  # Plot garis rata-rata (average)
  geom_line(data = occupancy_daily, 
            aes(x = time_of_day, y = average, group = 1), 
            color = "black", size = 1, linetype = "solid") +
  labs(title = "Daily Profiles of Library Occupancy",
       x = "Time of Day",
       y = "Occupancy") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "none")
## Warning: Removed 61 rows containing missing values or values outside the scale range
## (`geom_line()`).

# Plot Energy Daily Profiles
ggplot() +
  # Plot semua hari dengan transparansi
  lapply(names(energy_daily)[-c(1, ncol(energy_daily))], function(col) {
    geom_line(data = energy_daily, 
              aes(x = time_of_day, y = .data[[col]], group = 1), 
              alpha = 0.2, color = "orange")
  }) +
  # Plot garis rata-rata (average)
  geom_line(data = energy_daily, 
            aes(x = time_of_day, y = average, group = 1), 
            color = "black", size = 1, linetype = "solid") +
  labs(title = "Daily Profiles of Library Energy Consumption",
       x = "Time of Day",
       y = "Energy Consumption") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "none") +
  scale_y_continuous(limits = c(50, 225), breaks = seq(50, 225, 25))
## Warning: Removed 61 rows containing missing values or values outside the scale range
## (`geom_line()`).

Analysis

Peak Hours of Occupancy

avg_occupancy <- occupancy_daily %>%
  mutate(avg = rowMeans(select(., -time_of_day), na.rm = TRUE)) %>%
  select(time_of_day, avg)

# Pastikan kolom time_of_day jadi format waktu (tanpa tanggal)
avg_occupancy <- avg_occupancy %>%
  mutate(time_of_day = hms(time_of_day))

# Identifikasi peak lagi (supaya match class baru)
peak_row <- avg_occupancy %>%
  filter(avg == max(avg, na.rm = TRUE))

# Plot
ggplot(avg_occupancy, aes(x = time_of_day, y = avg)) +
  geom_line(color = "steelblue", linewidth = 1) +
  geom_point(data = peak_row, aes(x = time_of_day, y = avg),
             color = "red", size = 3) +
  scale_x_time() +
  labs(
    title = "Average Daily Profile of Library Occupancy",
    x = "Time of Day",
    y = "Occupancy"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    panel.grid.major.x = element_blank(),  # hilangkan grid vertikal
    panel.grid.minor = element_blank()
  )

Correlation

# Hitung korelasi
corr <- cor(merged_df$occupancy, merged_df$total_rate, use = "complete.obs")
cat("Correlation:", corr, "\n")
## Correlation: 0.8789519
# Regresi linear (total_rate ~ occupancy)
model <- lm(total_rate ~ occupancy, data = merged_df)

# Ringkasan model
summary(model)
## 
## Call:
## lm(formula = total_rate ~ occupancy, data = merged_df)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -57.17 -15.63   1.72  16.24  51.08 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 1.036e+02  4.965e-01   208.6   <2e-16 ***
## occupancy   2.673e-01  2.399e-03   111.4   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 20.89 on 3655 degrees of freedom
## Multiple R-squared:  0.7726, Adjusted R-squared:  0.7725 
## F-statistic: 1.241e+04 on 1 and 3655 DF,  p-value: < 2.2e-16

Mismatch

merged_df <- merged_df %>%
  mutate(
    predicted_energy = predict(model, newdata = merged_df),
    residual = total_rate - predicted_energy
  )

# 3. Threshold mismatch
threshold <- 1.5 * sd(merged_df$residual, na.rm = TRUE)

# 4. Filter mismatch
mismatch <- merged_df %>%
  filter(abs(residual) > threshold)

cat("Jumlah mismatch:", nrow(mismatch), "\n")
## Jumlah mismatch: 484
print(mismatch %>% select(occupancy, total_rate, predicted_energy, residual))
##     occupancy total_rate predicted_energy  residual
## 1       7.375         71         105.5317 -34.53166
## 2       6.750         59         105.3646 -46.36462
## 3       9.000         69         105.9660 -36.96596
## 4       8.750         65         105.8991 -40.89914
## 5       5.875         71         105.1308 -34.13077
## 6       3.750         70         104.5628 -34.56285
## 7       3.750         65         104.5628 -39.56285
## 8       3.750         53         104.5628 -51.56285
## 9       3.750         56         104.5628 -48.56285
## 10      3.500         61         104.4960 -43.49603
## 11      3.625         68         104.5294 -36.52944
## 12      5.625         73         105.0640 -32.06396
## 13    109.625        166         132.8590  33.14105
## 14    113.500        168         133.8946  34.10542
## 15    119.375        168         135.4647  32.53527
## 16    196.750        192         156.1439  35.85606
## 17    154.875        180         144.9524  35.04755
## 18    146.750        178         142.7810  35.21904
## 19     47.875        150         116.3557  33.64433
## 20      4.625         72         104.7967 -32.79670
## 21      5.500         63         105.0306 -42.03055
## 22      5.250         72         104.9637 -32.96374
## 23    206.875        191         158.8499  32.15006
## 24    200.625        193         157.1796  35.82043
## 25     85.875        163         126.5115  36.48846
## 26     78.750        163         124.6073  38.39269
## 27     73.250        158         123.1374  34.86261
## 28     49.375        149         116.7566  32.24344
## 29     25.500        142         110.3757  31.62426
## 30     13.125         74         107.0684 -33.06840
## 31    437.500        187         220.4867 -33.48668
## 32    447.500        188         223.1593 -35.15927
## 33    447.000        188         223.0256 -35.02565
## 34    442.125        189         221.7228 -32.72275
## 35    462.500        189         227.1682 -38.16817
## 36    104.875        167         131.5895  35.41053
## 37     68.625        154         121.9013  32.09869
## 38     60.750        160         119.7966  40.20336
## 39     13.500         74         107.1686 -33.16863
## 40     11.500         69         106.6341 -37.63411
## 41     13.750         67         107.2354 -40.23544
## 42      9.000         72         105.9660 -33.96596
## 43      9.625         70         106.1330 -36.13300
## 44      9.875         71         106.1998 -35.19981
## 45      9.375         72         106.0662 -34.06618
## 46      9.375         66         106.0662 -40.06618
## 47      9.500         62         106.0996 -44.09959
## 48     10.375         69         106.3334 -37.33344
## 49     10.875         71         106.4671 -35.46707
## 50     10.750         73         106.4337 -33.43366
## 51    493.500        203         235.4532 -32.45321
## 52    487.875        198         233.9499 -35.94988
## 53    445.750        191         222.6916 -31.69157
## 54    226.375        197         164.0615  32.93849
## 55    184.750        195         152.9368  42.06317
## 56    179.125        183         151.4335  31.56651
## 57    165.375        183         147.7587  35.24133
## 58    160.250        183         146.3890  36.61103
## 59    148.000        191         143.1150  47.88496
## 60    135.875        176         139.8745  36.12549
## 61    126.000        184         137.2353  46.76467
## 62    124.000        180         136.7008  43.29919
## 63    117.875        167         135.0638  31.93616
## 64    111.000        167         133.2264  33.77357
## 65    103.875        168         131.3222  36.67779
## 66     87.250        177         126.8790  50.12098
## 67     80.125        170         124.9748  45.02521
## 68     72.625        164         122.9703  41.02965
## 69     64.375        167         120.7655  46.23454
## 70     50.000        168         116.9236  51.07640
## 71     47.500        151         116.2555  34.74455
## 72     44.625        158         115.4871  42.51292
## 73     41.250        149         114.5851  34.41492
## 74     14.750         68         107.5027 -39.50270
## 75     12.500         67         106.9014 -39.90137
## 76     13.125         73         107.0684 -34.06840
## 77      7.000         68         105.4314 -37.43144
## 78      7.250         66         105.4983 -39.49825
## 79      7.750         73         105.6319 -32.63188
## 80      7.250         60         105.4983 -45.49825
## 81      9.125         66         105.9994 -39.99937
## 82      7.250         73         105.4983 -32.49825
## 83      8.375         73         105.7989 -32.79892
## 84     12.125         67         106.8011 -39.80114
## 85     13.375         62         107.1352 -45.13522
## 86     13.000         51         107.0350 -56.03500
## 87     13.250         54         107.1018 -53.10181
## 88     10.500         54         106.3668 -52.36685
## 89      7.375         59         105.5317 -46.53166
## 90      8.000         54         105.6987 -51.69870
## 91      9.250         66         106.0328 -40.03277
## 92      8.750         69         105.8991 -36.89914
## 93      7.500         69         105.5651 -36.56507
## 94      7.375         71         105.5317 -34.53166
## 95      7.125         73         105.4648 -32.46485
## 96      7.750         55         105.6319 -50.63188
## 97      8.625         59         105.8657 -46.86574
## 98      9.750         68         106.1664 -38.16640
## 99      9.750         72         106.1664 -34.16640
## 100    35.500         79         113.0483 -34.04834
## 101   128.750        171         137.9703  33.02971
## 102   116.375        172         134.6630  37.33705
## 103   107.625        166         132.3244  33.67557
## 104    98.125        162         129.7855  32.21453
## 105    93.375        169         128.5160  40.48402
## 106    86.375        158         126.6452  31.35483
## 107    63.000        157         120.3980  36.60203
## 108     9.500         74         106.0996 -32.09959
## 109   105.625        168         131.7899  36.21009
## 110   193.375        194         155.2419  38.75806
## 111   141.875        176         141.4781  34.52193
## 112   114.500        166         134.1618  31.83816
## 113   110.250        167         133.0260  33.97401
## 114    80.250        157         125.0082  31.99180
## 115     7.125         65         105.4648 -40.46485
## 116     8.500         61         105.8323 -44.83233
## 117     3.500         66         104.4960 -38.49603
## 118     8.625         67         105.8657 -38.86574
## 119     9.000         67         105.9660 -38.96596
## 120     9.000         66         105.9660 -39.96596
## 121     6.250         69         105.2310 -36.23099
## 122     4.375         63         104.7299 -41.72988
## 123     4.875         69         104.8635 -35.86351
## 124     6.875         73         105.3980 -32.39803
## 125    12.000         75         106.7677 -31.76774
## 126    13.250         75         107.1018 -32.10181
## 127    22.500         78         109.5740 -31.57396
## 128   119.000        168         135.3645  32.63549
## 129   133.875        175         139.3400  35.66000
## 130   228.125        197         164.5292  32.47079
## 131   224.500        196         163.5604  32.43961
## 132   166.000        188         147.9257  40.07429
## 133   138.625        179         140.6095  38.39052
## 134   137.250        181         140.2420  40.75800
## 135   136.000        174         139.9079  34.09208
## 136   130.750        174         138.5048  35.49519
## 137   126.625        177         137.4024  39.59764
## 138   126.750        170         137.4358  32.56423
## 139   111.250        174         133.2932  40.70675
## 140   103.875        175         131.3222  43.67779
## 141    98.375        179         129.8523  49.14772
## 142    98.000        174         129.7521  44.24794
## 143    96.875        173         129.4514  43.54861
## 144    95.375        177         129.0505  47.94950
## 145    90.625        174         127.7810  46.21898
## 146    81.875        173         125.4425  47.55750
## 147    78.750        171         124.6073  46.39269
## 148    74.750        167         123.5383  43.46173
## 149    71.125        164         122.5695  41.43054
## 150    64.625        161         120.8323  40.16773
## 151    57.875        163         119.0283  43.97173
## 152    53.625        164         117.8924  46.10758
## 153    48.750        164         116.5895  47.41047
## 154    20.375        142         109.0060  32.99396
## 155     6.375         72         105.2644 -33.26440
## 156     6.000         72         105.1642 -33.16418
## 157     6.000         73         105.1642 -32.16418
## 158    15.875         74         107.8034 -33.80337
## 159   118.125        167         135.1307  31.86934
## 160   134.000        184         139.3734  44.62660
## 161   134.625        175         139.5404  35.45956
## 162   144.125        175         142.0794  32.92059
## 163   159.250        180         146.1217  33.87829
## 164   180.750        187         151.8678  35.13221
## 165   182.000        185         152.2019  32.79814
## 166   185.750        188         153.2041  34.79591
## 167   142.750        177         141.7119  35.28808
## 168   123.625        172         136.6006  35.39941
## 169   121.500        169         136.0327  32.96734
## 170   108.125        165         132.4581  32.54194
## 171    92.875        165         128.3824  36.61765
## 172    85.625        159         126.4447  32.55528
## 173    84.125        165         126.0438  38.95617
## 174    80.250        166         125.0082  40.99180
## 175    70.875        159         122.5026  36.49736
## 176    14.500         71         107.4359 -36.43589
## 177    13.500         73         107.1686 -34.16863
## 178    13.375         72         107.1352 -35.13522
## 179     7.875         73         105.6653 -32.66529
## 180     7.875         67         105.6653 -38.66529
## 181     8.375         65         105.7989 -40.79892
## 182     7.875         72         105.6653 -33.66529
## 183     7.625         61         105.5985 -44.59848
## 184     7.875         62         105.6653 -43.66529
## 185     8.875         71         105.9326 -34.93255
## 186   449.000        192         223.5602 -31.56016
## 187   446.875        189         222.9922 -33.99224
## 188   430.875        184         218.7161 -34.71608
## 189   439.875        185         221.1214 -36.12142
## 190   454.500        192         225.0301 -33.03009
## 191   469.500        192         229.0390 -37.03899
## 192   471.250        194         229.5067 -35.50669
## 193   481.750        194         232.3129 -38.31291
## 194   487.000        193         233.7160 -40.71603
## 195   443.125        190         221.9900 -31.99001
## 196   436.250        184         220.1526 -36.15260
## 197     8.625         70         105.8657 -35.86574
## 198    11.000         70         106.5005 -36.50048
## 199    11.250         67         106.5673 -39.56729
## 200    12.875         62         107.0016 -45.00159
## 201    10.625         70         106.4003 -36.40026
## 202     8.000         64         105.6987 -41.69870
## 203    10.875         59         106.4671 -47.46707
## 204    10.875         60         106.4671 -46.46707
## 205    10.750         55         106.4337 -51.43366
## 206     5.250         57         104.9637 -47.96374
## 207     5.000         66         104.8969 -38.89692
## 208     5.875         61         105.1308 -44.13077
## 209     5.500         66         105.0306 -39.03055
## 210     5.500         50         105.0306 -55.03055
## 211     5.375         60         104.9971 -44.99714
## 212     5.375         52         104.9971 -52.99714
## 213     7.000         71         105.4314 -34.43144
## 214     8.750         65         105.8991 -40.89914
## 215   461.875        193         227.0011 -34.00113
## 216   477.375        199         231.1437 -32.14365
## 217   480.500        196         231.9788 -35.97884
## 218   479.000        192         231.5780 -39.57795
## 219   474.500        198         230.3753 -32.37528
## 220   493.000        191         235.3196 -44.31958
## 221   506.250        190         238.8608 -48.86077
## 222   500.125        194         237.2238 -43.22381
## 223   469.875        197         229.1392 -32.13921
## 224   471.625        198         229.6069 -31.60691
## 225   466.875        190         228.3374 -38.33743
## 226   152.750        180         144.3845  35.61548
## 227   143.750        174         141.9792  32.02082
## 228    12.125         66         106.8011 -40.80114
## 229    12.625         65         106.9348 -41.93477
## 230    14.250         51         107.3691 -56.36907
## 231    14.500         73         107.4359 -34.43589
## 232    14.500         55         107.4359 -52.43589
## 233    14.625         58         107.4693 -49.46929
## 234     8.750         66         105.8991 -39.89914
## 235     8.250         64         105.7655 -41.76551
## 236     8.625         63         105.8657 -42.86574
## 237     9.375         62         106.0662 -44.06618
## 238    10.000         56         106.2332 -50.23322
## 239     9.875         62         106.1998 -44.19981
## 240     9.750         49         106.1664 -57.16640
## 241     9.750         74         106.1664 -32.16640
## 242     9.875         72         106.1998 -34.19981
## 243     9.625         72         106.1330 -34.13300
## 244    11.250         73         106.5673 -33.56729
## 245   411.500        181         213.5379 -32.53793
## 246   419.750        177         215.7428 -38.74282
## 247   425.000        184         217.1459 -33.14593
## 248   437.750        182         220.5535 -38.55349
## 249   430.000        182         218.4822 -36.48223
## 250   412.250        177         213.7384 -36.73838
## 251   401.500        177         210.8653 -33.86534
## 252   196.750        189         156.1439  32.85606
## 253    59.750        152         119.5294  32.47062
## 254    16.250         71         107.9036 -36.90359
## 255    17.125         75         108.1374 -33.13744
## 256     9.375         60         106.0662 -46.06618
## 257    12.125         60         106.8011 -46.80114
## 258    12.000         70         106.7677 -36.76774
## 259    11.750         67         106.7009 -39.70092
## 260    10.500         69         106.3668 -37.36685
## 261     9.000         60         105.9660 -45.96596
## 262     9.125         51         105.9994 -54.99937
## 263    11.625         61         106.6675 -45.66751
## 264     9.500         69         106.0996 -37.09959
## 265     9.250         64         106.0328 -42.03277
## 266     6.500         69         105.2978 -36.29781
## 267   444.875        191         222.4577 -31.45772
## 268   460.000        194         226.5000 -32.50002
## 269   135.250        179         139.7075  39.29252
## 270   123.000        172         136.4335  35.56645
## 271   107.750        170         132.3578  37.64216
## 272   102.500        167         130.9547  36.04527
## 273    82.000        163         125.4759  37.52409
## 274    76.875        159         124.1062  34.89380
## 275    18.500         75         108.5049 -33.50492
## 276    15.875         74         107.8034 -33.80337
## 277    15.000         74         107.5695 -33.56952
## 278    13.625         69         107.2020 -38.20203
## 279    13.125         74         107.0684 -33.06840
## 280    13.750         66         107.2354 -41.23544
## 281    13.750         66         107.2354 -41.23544
## 282    14.250         68         107.3691 -39.36907
## 283    14.500         68         107.4359 -39.43589
## 284    16.125         74         107.8702 -33.87018
## 285    21.125         72         109.2065 -37.20648
## 286   207.875        194         159.1172  34.88280
## 287   183.750        187         152.6696  34.33043
## 288   167.625        187         148.3600  38.63999
## 289   160.000        187         146.3222  40.67785
## 290   124.250        169         136.7676  32.23238
## 291     6.875         63         105.3980 -42.39803
## 292    10.875         73         106.4671 -33.46707
## 293     8.125         71         105.7321 -34.73211
## 294     2.375         69         104.1954 -35.19536
## 295     3.750         69         104.5628 -35.56285
## 296     3.500         64         104.4960 -40.49603
## 297     3.500         59         104.4960 -45.49603
## 298     3.250         53         104.4292 -51.42922
## 299     3.500         68         104.4960 -36.49603
## 300     9.750         74         106.1664 -32.16640
## 301     6.500         68         105.2978 -37.29781
## 302     3.000         73         104.3624 -31.36240
## 303     3.375         63         104.4626 -41.46262
## 304     3.125         64         104.3958 -40.39581
## 305     3.000         64         104.3624 -40.36240
## 306     3.250         60         104.4292 -44.42922
## 307     3.125         58         104.3958 -46.39581
## 308     4.000         62         104.6297 -42.62966
## 309     4.375         70         104.7299 -34.72988
## 310     4.875         72         104.8635 -32.86351
## 311    17.000         72         108.1040 -36.10403
## 312   195.875        188         155.9101  32.08991
## 313   168.750        181         148.6607  32.33933
## 314   168.750        182         148.6607  33.33933
## 315   167.750        187         148.3934  38.60659
## 316   159.000        189         146.0549  42.94511
## 317   155.250        182         145.0527  36.94733
## 318   152.250        185         144.2509  40.74911
## 319   145.750        182         142.5137  39.48630
## 320   139.000        177         140.7097  36.29030
## 321   140.750        176         141.1774  34.82259
## 322   134.000        181         139.3734  41.62660
## 323   128.625        178         137.9369  40.06312
## 324   121.125        169         135.9324  33.06756
## 325   116.250        172         134.6295  37.37045
## 326   104.125        167         131.3890  35.61098
## 327    18.250         76         108.4381 -32.43811
## 328    14.875         73         107.5361 -34.53611
## 329    18.750         65         108.5717 -43.57174
## 330    19.125         75         108.6720 -33.67196
## 331    17.875         71         108.3379 -37.33789
## 332    11.875         70         106.7343 -36.73433
## 333    11.500         60         106.6341 -46.63411
## 334    11.875         68         106.7343 -38.73433
## 335    12.000         67         106.7677 -39.76774
## 336    10.750         73         106.4337 -33.43366
## 337    10.750         71         106.4337 -35.43366
## 338    10.375         70         106.3334 -36.33344
## 339    11.500         72         106.6341 -34.63411
## 340    14.125         69         107.3357 -38.33566
## 341   480.500        198         231.9788 -33.97884
## 342   483.000        200         232.6470 -32.64699
## 343   482.875        201         232.6136 -31.61358
## 344   486.375        201         233.5490 -32.54899
## 345   446.375        190         222.8586 -32.85861
## 346   132.500        175         138.9725  36.02749
## 347   102.750        167         131.0215  35.97846
## 348    89.000        159         127.3467  31.65328
## 349    81.750        162         125.4091  36.59091
## 350    39.250        152         114.0506  37.94944
## 351    16.500         71         107.9704 -36.97041
## 352    18.250         59         108.4381 -49.43811
## 353    18.000         71         108.3713 -37.37129
## 354    18.625         72         108.5383 -36.53833
## 355    18.375         69         108.4715 -39.47152
## 356    11.125         74         106.5339 -32.53389
## 357    10.375         72         106.3334 -34.33344
## 358    10.875         69         106.4671 -37.46707
## 359    12.625         65         106.9348 -41.93477
## 360    13.000         71         107.0350 -36.03500
## 361    15.250         67         107.6363 -40.63633
## 362    18.750         75         108.5717 -33.57174
## 363   503.125        206         238.0256 -32.02559
## 364   509.000        208         239.5957 -31.59574
## 365   179.750        183         151.6005  31.39947
## 366   183.000        189         152.4691  36.53088
## 367   178.625        184         151.2999  32.70014
## 368   166.875        185         148.1596  36.84044
## 369   165.500        189         147.7921  41.20792
## 370   163.125        183         147.1573  35.84266
## 371   160.000        185         146.3222  38.67785
## 372   150.250        178         143.7164  34.28363
## 373   135.375        174         139.7409  34.25911
## 374    95.750        165         129.1507  35.84927
## 375    58.250        154         119.1285  34.87151
## 376   234.000        202         166.0994  35.90064
## 377   205.250        192         158.4156  33.58435
## 378   188.375        186         153.9056  32.09436
## 379   129.125        175         138.0705  36.92949
## 380    15.500         74         107.7031 -33.70315
## 381    18.625         75         108.5383 -33.53833
## 382    17.625         72         108.2711 -36.27107
## 383    13.000         73         107.0350 -34.03500
## 384    11.125         74         106.5339 -32.53389
## 385    11.875         67         106.7343 -39.73433
## 386   199.750        194         156.9457  37.05428
## 387   188.750        197         154.0059  42.99414
## 388   183.125        190         152.5025  37.49747
## 389   173.375        189         149.8967  39.10325
## 390   168.000        187         148.4602  38.53977
## 391   164.250        190         147.4580  42.54200
## 392   158.625        190         145.9547  44.04533
## 393   152.000        183         144.1841  38.81592
## 394   142.125        181         141.5449  39.45511
## 395   136.500        182         140.0416  41.95845
## 396   127.000        173         137.5026  35.49741
## 397   122.750        179         136.3667  42.63327
## 398   119.875        178         135.5984  42.40164
## 399   107.500        176         132.2910  43.70897
## 400    99.000        172         130.0193  41.98068
## 401    91.500        164         128.0149  35.98513
## 402    82.875        171         125.7098  45.29024
## 403    77.250        169         124.2064  44.79358
## 404    69.875        163         122.2354  40.76462
## 405    65.625        157         121.0995  35.90047
## 406    55.625        151         118.4269  32.57306
## 407    10.750         72         106.4337 -34.43366
## 408    11.125         70         106.5339 -36.53389
## 409    11.250         72         106.5673 -34.56729
## 410   211.750        195         160.1528  34.84717
## 411   203.625        192         157.9814  34.01865
## 412   151.250        179         143.9836  35.01637
## 413   142.625        180         141.6785  38.32148
## 414   130.375        173         138.4046  34.59541
## 415    99.000        164         130.0193  33.98068
## 416    93.625        175         128.5828  46.41720
## 417    91.125        161         127.9146  33.08535
## 418     4.375         73         104.7299 -31.72988
## 419     4.750         70         104.8301 -34.83011
## 420   119.750        169         135.5650  33.43505
## 421    67.250        158         121.5338  36.46617
## 422     5.375         72         104.9971 -32.99714
## 423     5.875         65         105.1308 -40.13077
## 424     6.875         68         105.3980 -37.39803
## 425     7.125         66         105.4648 -39.46485
## 426     7.750         73         105.6319 -32.63188
## 427     7.375         74         105.5317 -31.53166
## 428     7.375         70         105.5317 -35.53166
## 429     7.625         64         105.5985 -41.59848
## 430     7.625         66         105.5985 -39.59848
## 431   180.625        184         151.8344  32.16562
## 432   169.250        181         148.7943  32.20570
## 433    61.250        152         119.9303  32.06973
## 434    18.625         68         108.5383 -40.53833
## 435    22.125         67         109.4737 -42.47374
## 436    22.500         75         109.5740 -34.57396
## 437    13.625         73         107.2020 -34.20203
## 438    17.250         68         108.1708 -40.17085
## 439    19.375         67         108.7388 -41.73878
## 440   101.625        164         130.7209  33.27912
## 441   207.000        193         158.8834  34.11665
## 442   163.125        190         147.1573  42.84266
## 443   156.875        179         145.4870  33.51303
## 444   150.625        180         143.8166  36.18341
## 445   147.125        175         142.8812  32.11881
## 446   133.375        182         139.2064  42.79363
## 447   107.750        175         132.3578  42.64216
## 448    81.250        169         125.2755  43.72454
## 449    17.250         69         108.1708 -39.17085
## 450    13.250         61         107.1018 -46.10181
## 451    16.500         68         107.9704 -39.97041
## 452    16.625         57         108.0038 -51.00381
## 453    17.125         73         108.1374 -35.13744
## 454    13.500         63         107.1686 -44.16863
## 455    10.250         69         106.3000 -37.30003
## 456    10.875         62         106.4671 -44.46707
## 457    11.250         66         106.5673 -40.56729
## 458    10.625         64         106.4003 -42.40026
## 459    11.750         64         106.7009 -42.70092
## 460    11.500         63         106.6341 -43.63411
## 461    11.875         69         106.7343 -37.73433
## 462   496.750        203         236.3218 -33.32181
## 463   511.625        206         240.2973 -34.29729
## 464   196.250        193         156.0103  36.98969
## 465   163.500        187         147.2576  39.74244
## 466   158.000        183         145.7876  37.21237
## 467   156.625        178         145.4202  32.57985
## 468   136.375        174         140.0081  33.99186
## 469   130.125        175         138.3378  36.66223
## 470   116.000        167         134.5627  32.43727
## 471    12.250         70         106.8346 -36.83455
## 472    12.250         75         106.8346 -31.83455
## 473    13.250         71         107.1018 -36.10181
## 474    10.875         56         106.4671 -50.46707
## 475    14.250         55         107.3691 -52.36907
## 476    13.750         61         107.2354 -46.23544
## 477     8.000         74         105.6987 -31.69870
## 478     8.875         65         105.9326 -40.93255
## 479     8.375         69         105.7989 -36.79892
## 480     8.250         74         105.7655 -31.76551
## 481     8.125         71         105.7321 -34.73211
## 482    11.125         71         106.5339 -35.53389
## 483    65.500        157         121.0661  35.93388
## 484    66.875        172         121.4336  50.56639
#Visualisasi
ggplot(merged_df, aes(x = occupancy, y = total_rate)) +
  geom_point(alpha = 0.4, color = "steelblue", size = 2, aes(label = NULL)) +
  geom_point(data = mismatch, aes(x = occupancy, y = total_rate),
             color = "red", size = 2.5, alpha = 0.8) +
  geom_line(aes(y = predicted_energy), color = "black", linewidth = 1) +
  labs(
    x = "Occupancy",
    y = "Energy Consumption",
    title = "Occupancy vs Energy with Mismatch Highlighted"
  ) +
  theme_minimal()

Weekend vs Weekday Comparison

Split Weekdays & Weekend

library(dplyr)
library(ggplot2)

# Tambah kolom hari dan kategori weekday/weekend
merged_df <- merged_df %>%
  mutate(
    day = weekdays(time),
    day_type = ifelse(weekdays(time) %in% c("Saturday", "Sunday"), "Weekend", "Weekday")
  )

Visualisasi

Time Series

ggplot(merged_df, aes(x = time, y = occupancy, color = day_type)) +
  geom_line(alpha = 0.7, linewidth = 0.8) +
  labs(title = "Time Series of Occupancy: Weekday vs Weekend",
       x = "Date",
       y = "Occupancy",
       color = "Day Type") +
  scale_color_manual(values = c("Weekday" = "maroon", "Weekend" = "darkblue")) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

ggplot(merged_df, aes(x = time, y = total_rate, color = day_type)) +
  geom_line(alpha = 0.7, linewidth = 0.8) +
  labs(title = "Time Series of Energy Consumption: Weekday vs Weekend",
       x = "Date",
       y = "Energy Consumption",
       color = "Day Type") +
  scale_color_manual(values = c("Weekday" = "blue", "Weekend" = "red")) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Scatter Plot

ggplot(merged_df, aes(x = occupancy, y = total_rate, color = day_type)) +
  geom_point(alpha = 0.5, size = 1.5) +
  labs(title = "Scatter Plot: Occupancy vs Energy Consumption",
       x = "Occupancy (WiFi Clients)", 
       y = "Energy Consumption (kWh)",
       color = "Day Type") +
  scale_color_manual(values = c("Weekday" = "skyblue", "Weekend" = "darkred")) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Daily Profiles

occupancy_profile <- merged_df %>%
  group_by(day_type, time_of_day) %>%
  summarise(avg_occupancy = mean(occupancy, na.rm = TRUE))
## `summarise()` has grouped output by 'day_type'. You can override using the
## `.groups` argument.
ggplot(occupancy_profile, aes(x = time_of_day, y = avg_occupancy, color = day_type, group = day_type)) +
  geom_line(size = 1) +
  labs(title = "Daily Profiles - Occupancy",
       x = "Time of Day", y = "Average Occupancy", color = "Day Type") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(hjust = 0.5))

energy_profile <- merged_df %>%
  group_by(day_type, time_of_day) %>%
  summarise(avg_energy = mean(total_rate, na.rm = TRUE))
## `summarise()` has grouped output by 'day_type'. You can override using the
## `.groups` argument.
ggplot(energy_profile, aes(x = time_of_day, y = avg_energy, color = day_type, group = day_type)) +
  geom_line(size = 1) +
  labs(title = "Daily Profiles - Energy Consumption",
       x = "Time of Day", y = "Average Energy Consumption (kWh)", color = "Day Type") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(hjust = 0.5))