library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.0 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(lubridate)
library(dplyr)
library(stringr)
library(janitor)
##
## Attaching package: 'janitor'
##
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
df_wifi <- read.csv("C:/Users/wdarm/Documents/College/Semester 5/Data Mining & Visualization/WEEK 2/Library Wifi Analysis Project/wifi.csv")
df_energy1 <- read.csv("C:/Users/wdarm/Documents/College/Semester 5/Data Mining & Visualization/WEEK 2/Library Wifi Analysis Project/library1.csv")
df_energy2 <- read.csv("C:/Users/wdarm/Documents/College/Semester 5/Data Mining & Visualization/WEEK 2/Library Wifi Analysis Project/library2.csv")
df_energy3 <- read.csv("C:/Users/wdarm/Documents/College/Semester 5/Data Mining & Visualization/WEEK 2/Library Wifi Analysis Project/library3.csv")
# Menampilkan 5 baris pertama
head(df_wifi)
## time Event.Time Associated.Client.Count
## 1 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 184
## 2 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 6
## 3 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 18
## 4 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 23
## 5 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 45
## 6 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 16
## Authenticated.Client.Count Uni Building
## 1 182 Lancaster University Graduate College
## 2 6 Lancaster University Management School
## 3 18 Lancaster University SW hse 32-33
## 4 23 Lancaster University SW hse 29
## 5 45 Lancaster University Furness outer
## 6 16 Lancaster University Slaidburn House (LUSU)
## Floor
## 1 A Floor
## 2 C Floor
## 3 D Floor
## 4 B floor
## 5 C floor
## 6 E floor
# --- ALUR KERJA PEMBERSIHAN DATA LENGKAP ---
# Ini mengubah "Building" -> "building", "Associated Client Count" -> "associated_client_count", dll.
df_wifi <- df_wifi %>% clean_names()
# Hapus duplikat menggunakan nama kolom yang sudah bersih
# Menampilkan jumlah baris sebelum penghapusan
cat(sprintf("Jumlah baris awal di df_wifi: %d\n", nrow(df_wifi)))
## Jumlah baris awal di df_wifi: 1883844
# Hapus baris duplikat berdasarkan kolom-kolom yang sudah bersih
# .keep_all = TRUE memastikan semua kolom lain dipertahankan
df_wifi_cleaned <- df_wifi %>%
distinct(time, building, floor, associated_client_count, .keep_all = TRUE)
# Menampilkan jumlah baris setelah penghapusan
cat(sprintf("Jumlah baris di df_wifi setelah duplikat sempurna dihapus: %d\n", nrow(df_wifi_cleaned)))
## Jumlah baris di df_wifi setelah duplikat sempurna dihapus: 1876495
# Tampilkan beberapa baris pertama dari data yang sudah bersih
head(df_wifi_cleaned)
## time event_time associated_client_count
## 1 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 184
## 2 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 6
## 3 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 18
## 4 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 23
## 5 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 45
## 6 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 16
## authenticated_client_count uni building
## 1 182 Lancaster University Graduate College
## 2 6 Lancaster University Management School
## 3 18 Lancaster University SW hse 32-33
## 4 23 Lancaster University SW hse 29
## 5 45 Lancaster University Furness outer
## 6 16 Lancaster University Slaidburn House (LUSU)
## floor
## 1 A Floor
## 2 C Floor
## 3 D Floor
## 4 B floor
## 5 C floor
## 6 E floor
# Mengambil hanya data yang berasal dari gedung "Library"
search_term <- 'library'
df_wifi_library <- df_wifi_cleaned %>%
filter(str_to_lower(str_trim(building)) == search_term)
# Tampilkan beberapa baris pertama untuk memastikan filter berhasil
head(df_wifi_library)
## time event_time associated_client_count
## 1 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 29
## 2 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 0
## 3 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 21
## 4 2020-02-01 00:02:12 Sat Feb 01 00:02:12 UTC 2020 38
## 5 2020-02-01 00:07:34 Sat Feb 01 00:07:34 UTC 2020 0
## 6 2020-02-01 00:07:34 Sat Feb 01 00:07:34 UTC 2020 33
## authenticated_client_count uni building floor
## 1 28 Lancaster University Library A floor
## 2 0 Lancaster University Library LG floor
## 3 20 Lancaster University Library C floor
## 4 37 Lancaster University Library B floor
## 5 0 Lancaster University Library LG floor
## 6 31 Lancaster University Library A floor
library(lubridate)
# Konversi kolom 'time' di data WiFi
# Tanda '$' digunakan untuk mengakses kolom dalam sebuah dataframe
df_wifi_library$time <- as_datetime(df_wifi_library$time)
# Konversi kolom 'ts' di setiap data energi
df_energy1$ts <- as_datetime(df_energy1$ts)
df_energy2$ts <- as_datetime(df_energy2$ts)
df_energy3$ts <- as_datetime(df_energy3$ts)
# Tampilkan beberapa baris pertama untuk verifikasi
head(df_energy1)
## ts name reading units cumulative rate
## 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
# --- Pengecekan Duplikat Berdasarkan Kolom Waktu ---
# Cek duplikat di kolom 'time' pada df_wifi_library
# sum(duplicated(df$kolom)) adalah cara R untuk menghitung nilai duplikat dalam sebuah kolom
cat(sprintf("Jumlah duplikat di df_wifi_library (kolom time): %d\n", sum(duplicated(df_wifi_library$time))))
## Jumlah duplikat di df_wifi_library (kolom time): 21489
# Cek duplikat di kolom 'ts' pada data energi
cat(sprintf("Jumlah duplikat di df_energy1 (kolom ts): %d\n", sum(duplicated(df_energy1$ts))))
## Jumlah duplikat di df_energy1 (kolom ts): 0
cat(sprintf("Jumlah duplikat di df_energy2 (kolom ts): %d\n", sum(duplicated(df_energy2$ts))))
## Jumlah duplikat di df_energy2 (kolom ts): 0
cat(sprintf("Jumlah duplikat di df_energy3 (kolom ts): %d\n\n", sum(duplicated(df_energy3$ts))))
## Jumlah duplikat di df_energy3 (kolom ts): 0
# --- Menghapus Duplikat pada Data Energi ---
# Sesuai logika: Data Energi duplikat dihapus, Data WiFi tidak.
# 'distinct()' akan mempertahankan baris pertama untuk setiap timestamp unik.
df_energy1 <- df_energy1 %>% distinct(ts, .keep_all = TRUE)
df_energy2 <- df_energy2 %>% distinct(ts, .keep_all = TRUE)
df_energy3 <- df_energy3 %>% distinct(ts, .keep_all = TRUE)
cat("Duplikat pada data energi telah dihapus.\n")
## Duplikat pada data energi telah dihapus.
# Verifikasi bahwa duplikat di data energi sekarang sudah nol
cat(sprintf("Jumlah duplikat di df_energy1 setelah dihapus: %d\n", sum(duplicated(df_energy1$ts))))
## Jumlah duplikat di df_energy1 setelah dihapus: 0
# Cek data yang kosong (NA) pada setiap kolom di dataframe energy
missing_df1 <- colSums(is.na(df_energy1))
missing_df2 <- colSums(is.na(df_energy2))
missing_df3 <- colSums(is.na(df_energy3))
# Tampilkan hasilnya
print(missing_df1)
## ts name reading units cumulative rate
## 0 0 3041 0 3041 3047
print(missing_df2)
## ts name reading units cumulative rate
## 0 0 3041 0 3041 3047
print(missing_df3)
## ts name reading units cumulative rate
## 0 0 3041 0 3041 3047
# Muat library
library(naniar)
# Membuat visualisasi data yang hilang pada df_energy1
# Fungsi ini secara otomatis membuat plot yang mirip dengan heatmap
vis_miss(df_energy1)

# Fungsi untuk mengisi nilai yang hilang (NA)
fill_missing_energy <- function(df) {
# Hitung rata-rata dari 144 baris pertama di kolom 'rate'
# na.rm = TRUE penting untuk menghitung rata-rata meskipun ada nilai NA di dalamnya
mean_first_144 <- mean(df$rate[1:144], na.rm = TRUE)
# Ganti semua nilai NA di kolom 'rate' dengan nilai rata-rata yang sudah dihitung
df <- df %>%
mutate(rate = replace_na(rate, mean_first_144))
# Kembalikan dataframe yang sudah diisi
return(df)
}
# Terapkan fungsi ke setiap dataframe energi
df_energy1 <- fill_missing_energy(df_energy1)
df_energy2 <- fill_missing_energy(df_energy2)
df_energy3 <- fill_missing_energy(df_energy3)
# (Opsional) Verifikasi bahwa sudah tidak ada lagi data yang hilang di df_energy1
print(sum(is.na(df_energy1$rate)))
## [1] 0
# > [1] 0
# 1. Gabungkan ketiga dataframe energi menjadi satu berdasarkan kolom 'ts'
# full_join akan memastikan semua baris dari semua dataframe diikutsertakan.
df_energy_combined <- df_energy1 %>%
full_join(df_energy2, by = "ts", suffix = c("_1", "_2")) %>%
full_join(df_energy3, by = "ts")
# Setelah join, kolom 'rate' akan otomatis diganti namanya menjadi rate_1, rate_2, dan rate
# untuk menghindari konflik nama.
# 2. Jumlahkan semua kolom 'rate' secara horizontal untuk mendapatkan total
# rowSums() menjumlahkan nilai per baris. na.rm = TRUE akan mengabaikan nilai NA.
df_energy_total <- df_energy_combined %>%
mutate(total_rate = rowSums(select(., starts_with("rate")), na.rm = TRUE)) %>%
# 3. Pilih hanya kolom yang kita butuhkan untuk hasil akhir
select(ts, total_rate)
# Tampilkan beberapa baris pertama untuk verifikasi
head(df_energy_total)
## ts total_rate
## 1 2020-01-01 00:00:00 64.81818
## 2 2020-01-01 00:10:00 82.00000
## 3 2020-01-01 00:20:00 71.00000
## 4 2020-01-01 00:30:00 91.00000
## 5 2020-01-01 00:40:00 85.00000
## 6 2020-01-01 00:50:00 60.00000
# --- Resample & Gabungkan Data ---
# 1. Resample data WiFi menjadi interval 10 menit
df_wifi_resampled <- df_wifi_library %>%
# Buat kolom baru 'time_floor' yang berisi timestamp dibulatkan ke 10 menit terdekat
mutate(time_floor = floor_date(time, "10 minutes")) %>%
# Kelompokkan data berdasarkan timestamp yang sudah dibulatkan
group_by(time_floor) %>%
# Hitung rata-rata untuk setiap grup dan beri nama kolom 'occupancy'
summarise(occupancy = mean(associated_client_count, na.rm = TRUE))
# Pastikan Anda menggunakan nama kolom yang sudah bersih: 'associated_client_count'
# 2. Gabungkan data WiFi yang sudah di-resample dengan data energi total
# inner_join akan menggabungkan baris yang memiliki timestamp yang cocok di kedua dataframe
df_final <- inner_join(
df_wifi_resampled,
df_energy_total,
by = c("time_floor" = "ts") # Cocokkan kolom 'time_floor' dari wifi dengan 'ts' dari energi
)
# --- Verifikasi Hasil ---
# Tampilkan 5 baris pertama dari DataFrame final
cat("DataFrame Gabungan Final (df_final):\n")
## DataFrame Gabungan Final (df_final):
print(head(df_final))
## # A tibble: 6 × 3
## time_floor occupancy total_rate
## <dttm> <dbl> <dbl>
## 1 2020-02-01 00:00:00 22.8 64.8
## 2 2020-02-01 00:10:00 20.6 97
## 3 2020-02-01 00:20:00 17.2 96
## 4 2020-02-01 00:30:00 15.4 100
## 5 2020-02-01 00:40:00 12.4 89
## 6 2020-02-01 00:50:00 10.5 91
# Cek juga informasi DataFrame (padanan dari .info())
# glimpse() memberikan ringkasan yang rapi tentang tipe data dan nilai awal setiap kolom
cat("\nInfo DataFrame Final:\n")
##
## Info DataFrame Final:
glimpse(df_final)
## Rows: 3,683
## Columns: 3
## $ time_floor <dttm> 2020-02-01 00:00:00, 2020-02-01 00:10:00, 2020-02-01 00:20…
## $ occupancy <dbl> 22.750000, 20.625000, 17.250000, 15.375000, 12.375000, 10.5…
## $ total_rate <dbl> 64.81818, 97.00000, 96.00000, 100.00000, 89.00000, 91.00000…
# Muat library ggplot2
library(ggplot2)
# --- Time Series Plot dengan Sumbu X yang Disesuaikan ---
# 1. Tentukan faktor skala (sama seperti sebelumnya)
scale_factor <- max(df_final$occupancy, na.rm = TRUE) / max(df_final$total_rate, na.rm = TRUE)
# 2. Buat plotnya
time_series_plot <- ggplot(df_final, aes(x = time_floor)) +
theme_bw() +
geom_line(aes(y = occupancy, color = "Okupansi (WiFi)"), size = 1) +
geom_line(aes(y = total_rate * scale_factor, color = "Konsumsi Energi"), size = 1) +
scale_y_continuous(
name = "Rata-rata Jumlah Pengguna WiFi",
sec.axis = sec_axis(~. / scale_factor, name = "Total Konsumsi Energi (rate)")
) +
scale_color_manual(
name = "Legenda",
values = c("Okupansi (WiFi)" = "blue", "Konsumsi Energi" = "red")
) +
labs(
title = "Tren Okupansi Perpustakaan vs. Konsumsi Energi",
x = "Tanggal"
) +
# 7. Atur tampilan sumbu X agar label tidak padat
scale_x_datetime(
date_breaks = "1 week", # Atur jarak antar label (misal: per 1 minggu)
date_labels = "%d %b %Y" # Atur format label (misal: "25 Jan 2023")
) +
# 8. Atur tema, termasuk memutar label sumbu X
theme(
axis.title.y.left = element_text(color = "blue"),
axis.text.y.left = element_text(color = "blue"),
axis.title.y.right = element_text(color = "red"),
axis.text.y.right = element_text(color = "red"),
plot.title = element_text(hjust = 0.5),
# Putar label sumbu X 45 derajat agar tidak tumpang tindih
axis.text.x = element_text(angle = 45, hjust = 1)
)
## 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.
# Tampilkan plot
print(time_series_plot)

# Simpan plot dengan lebar yang Anda inginkan (misal: 15 inci)
ggsave("time_series_plot_lebar.png", plot = time_series_plot, width = 15, height = 7, units = "in")
# --- Scatter Plot Korelasi: Okupansi vs. Konsumsi Energi ---
correlation_plot <- ggplot(df_final, aes(x = occupancy, y = total_rate)) +
# Tambahkan titik-titik data, 'alpha' membuat titik sedikit transparan untuk melihat tumpukan data
geom_point(alpha = 0.5, color = "dodgerblue") +
# Tambahkan garis regresi linear (metode "lm") untuk menunjukkan tren
# se = FALSE akan menyembunyikan pita confidence interval agar lebih bersih
geom_smooth(method = "lm", se = FALSE, color = "red") +
# Atur judul dan label sumbu
labs(
title = "Korelasi antara Okupansi dan Konsumsi Energi",
subtitle = "Setiap titik merepresentasikan interval 10 menit",
x = "Rata-rata Okupansi (Jumlah Perangkat WiFi)",
y = "Total Konsumsi Energi (rate)"
) +
# Gunakan tema yang bersih
theme_bw()
# Tampilkan plot
print(correlation_plot)
## `geom_smooth()` using formula = 'y ~ x'

# Simpan plot ke file
ggsave("correlation_plot.png", plot = correlation_plot, width = 10, height = 8)
## `geom_smooth()` using formula = 'y ~ x'
# --- Pola Rata-rata Harian ---
# Hitung rata-rata per jam
daily_pattern <- df_final %>%
# Ekstrak jam dari kolom timestamp
mutate(hour_of_day = hour(time_floor)) %>%
# Kelompokkan berdasarkan jam
group_by(hour_of_day) %>%
# Hitung rata-rata okupansi dan energi untuk setiap jam
summarise(
avg_occupancy = mean(occupancy, na.rm = TRUE),
avg_energy = mean(total_rate, na.rm = TRUE)
)
# Ubah data dari format 'lebar' ke 'panjang' agar mudah di-plot dengan ggplot2
daily_pattern_long <- daily_pattern %>%
pivot_longer(
cols = c("avg_occupancy", "avg_energy"),
names_to = "metric",
values_to = "average_value"
)
# Buat plot pola harian
daily_plot <- ggplot(daily_pattern_long, aes(x = hour_of_day, y = average_value, color = metric)) +
geom_line(size = 1.2) +
geom_point(size = 2.5) +
# Atur label sumbu X agar menampilkan setiap 2 jam
scale_x_continuous(breaks = seq(0, 23, by = 2)) +
# Atur judul dan label
labs(
title = "Pola Rata-rata Harian: Okupansi vs. Energi",
subtitle = "Menunjukkan tren penggunaan perpustakaan sepanjang hari",
x = "Jam dalam Sehari",
y = "Nilai Rata-rata",
color = "Metrik" # Judul untuk legenda
) +
# Atur label legenda secara manual
scale_color_manual(
labels = c("avg_energy" = "Konsumsi Energi", "avg_occupancy" = "Okupansi"),
values = c("avg_energy" = "red", "avg_occupancy" = "blue")
) +
theme_bw()
# Tampilkan plot
print(daily_plot)

# Simpan plot ke file
ggsave("daily_pattern_plot.png", plot = daily_plot, width = 12, height = 7)
# Muat library yang dibutuhkan
# --- Identifikasi Jam Puncak Okupansi ---
# Komentar: Pada plot pola harian, terlihat puncak okupansi terjadi sekitar sore hari.
# Menemukan jam dengan rata-rata okupansi tertinggi dari data yang sudah kita agregasi
peak_hour_data <- daily_pattern %>%
# Urutkan data berdasarkan okupansi rata-rata tertinggi dan ambil baris teratas
slice_max(order_by = avg_occupancy, n = 1)
# Ambil nilai jamnya saja
peak_hour <- peak_hour_data$hour_of_day
cat(sprintf("Jam tersibuk di perpustakaan (puncak okupansi) rata-rata terjadi pada jam: %d:00\n", peak_hour))
## Jam tersibuk di perpustakaan (puncak okupansi) rata-rata terjadi pada jam: 15:00
# --- Pengaruh Okupansi terhadap Penggunaan Energi ---
# Menghitung korelasi antara okupansi dan konsumsi energi
# Gunakan argumen 'use = "complete.obs"' untuk mengabaikan baris dengan nilai NA
correlation <- cor(df_final$occupancy, df_final$total_rate, use = "complete.obs")
cat(sprintf("Koefisien korelasi antara okupansi dan konsumsi energi adalah: %.4f\n", correlation))
## Koefisien korelasi antara okupansi dan konsumsi energi adalah: 0.8782
# Komentar: Hasil scatter plot menunjukkan bahwa rate dan occupancy memiliki korelasi positif yang cukup tinggi.
# --- Memisahkan Data Weekday dan Weekend ---
# Gunakan mutate() untuk membuat kolom baru
df_final <- df_final %>%
mutate(
# 1. Buat kolom 'day_of_week' (Senin=1, Minggu=7)
day_of_week = wday(time_floor, week_start = 1),
# 2. Buat kolom 'day_type' berdasarkan nilai 'day_of_week'
# Jika hari <= 5 (Senin-Jumat), maka "Weekday", selain itu "Weekend"
day_type = if_else(day_of_week <= 5, "Weekday", "Weekend")
)
# Membuat dua DataFrame terpisah menggunakan filter()
df_weekday <- df_final %>%
filter(day_type == "Weekday")
df_weekend <- df_final %>%
filter(day_type == "Weekend")
# Mencetak hasil
cat("Data berhasil dipisahkan.\n")
## Data berhasil dipisahkan.
cat(sprintf("Jumlah data hari kerja (Weekday): %d baris\n", nrow(df_weekday)))
## Jumlah data hari kerja (Weekday): 2531 baris
cat(sprintf("Jumlah data akhir pekan (Weekend): %d baris\n", nrow(df_weekend)))
## Jumlah data akhir pekan (Weekend): 1152 baris
# Tampilkan beberapa baris dari salah satu dataframe baru untuk verifikasi
head(df_weekday)
## # A tibble: 6 × 5
## time_floor occupancy total_rate day_of_week day_type
## <dttm> <dbl> <dbl> <dbl> <chr>
## 1 2020-02-03 00:00:00 39.5 129 1 Weekday
## 2 2020-02-03 00:10:00 38.9 131 1 Weekday
## 3 2020-02-03 00:20:00 37.4 119 1 Weekday
## 4 2020-02-03 00:30:00 35.4 129 1 Weekday
## 5 2020-02-03 00:40:00 33.5 136 1 Weekday
## 6 2020-02-03 00:50:00 31.1 138 1 Weekday
# --- Scatter Plot Perbandingan: Hari Kerja vs. Akhir Pekan ---
# Kita menggunakan dataframe 'df_final' yang sudah memiliki kolom 'day_type'
scatter_comparison_plot <- ggplot(df_final, aes(x = occupancy, y = total_rate)) +
# 1. Buat scatter plot dengan titik transparan
# Warna titik akan dibedakan berdasarkan 'day_type'
geom_point(aes(color = day_type), alpha = 0.3) +
# 2. Tambahkan garis regresi
# Warna garis juga akan dibedakan berdasarkan 'day_type'
geom_smooth(aes(color = day_type), method = "lm", se = FALSE) +
# 3. KUNCI UTAMA: Buat plot terpisah untuk setiap nilai di kolom 'day_type'
facet_wrap(~ day_type) +
# 4. Atur warna secara manual agar sesuai dengan permintaan
scale_color_manual(
name = "Tipe Hari", # Judul legenda
values = c("Weekday" = "blue", "Weekend" = "red")
) +
# 5. Atur judul dan label
labs(
title = "Perbandingan Korelasi: Hari Kerja vs. Akhir Pekan",
x = "Okupansi (Pengguna WiFi)",
y = "Total Konsumsi Energi"
) +
# 6. Gunakan tema yang bersih dan atur legenda
theme_bw() +
theme(legend.position = "none") # Sembunyikan legenda karena facet sudah jelas
# Tampilkan plot
print(scatter_comparison_plot)
## `geom_smooth()` using formula = 'y ~ x'

# Simpan plot ke file
ggsave("scatter_comparison.png", plot = scatter_comparison_plot, width = 16, height = 7)
## `geom_smooth()` using formula = 'y ~ x'
# --- 1. Agregasi Data ---
daily_profiles <- df_final %>%
mutate(hour = hour(time_floor)) %>%
group_by(day_type, hour) %>%
summarise(
`Rata-rata Okupansi` = mean(occupancy, na.rm = TRUE),
`Rata-rata Energi` = mean(total_rate, na.rm = TRUE),
.groups = 'drop'
)
# --- 2. Ubah Format Data menjadi 'Long' untuk Faceting ---
# Ini adalah langkah kunci untuk membuat plot terpisah
daily_profiles_long <- daily_profiles %>%
pivot_longer(
cols = c("Rata-rata Okupansi", "Rata-rata Energi"),
names_to = "metric",
values_to = "average_value"
)
# --- 3. Buat Plot dengan Faceting ---
improved_daily_plot <- ggplot(daily_profiles_long, aes(x = hour, y = average_value, color = day_type)) +
# Tambahkan garis dan titik
geom_line(aes(linetype = day_type), size = 1.1) +
geom_point(size = 2.5) +
# KUNCI UTAMA: Buat panel terpisah untuk setiap metrik
# scales = "free_y" memastikan setiap panel punya skala Y sendiri-sendiri
facet_wrap(~ metric, scales = "free_y", ncol = 1) +
# Atur label, judul, dan tema
labs(
title = "Perbandingan Pola Harian: Hari Kerja vs. Akhir Pekan",
x = "Jam dalam Sehari (0-23)",
y = "Nilai Rata-rata",
color = "Tipe Hari",
linetype = "Tipe Hari"
) +
scale_x_continuous(breaks = seq(0, 23, by = 2)) +
# Atur warna dan gaya garis secara manual
scale_color_manual(values = c("Weekday" = "navy", "Weekend" = "cyan4")) +
scale_linetype_manual(values = c("Weekday" = "solid", "Weekend" = "dashed")) +
# Tema yang bersih dan posisikan legenda di atas
theme_bw() +
theme(
plot.title = element_text(hjust = 0.5, size = 16),
legend.position = "top",
strip.background = element_rect(fill = "lightblue"), # Warna latar judul panel
strip.text = element_text(face = "bold")
)
# Tampilkan plot baru yang lebih jelas
print(improved_daily_plot)

# Simpan plot yang sudah diperbaiki
ggsave("daily_profile_comparison_improved.png", plot = improved_daily_plot, width = 10, height = 9)