library(readxl)
## Warning: package 'readxl' was built under R version 4.4.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.3
## 
## 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(lubridate)
## Warning: package 'lubridate' was built under R version 4.4.3
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
# Baca data
df <- read_excel("C:/Users/ASUS/Downloads/resampling data iklim harian.xlsx")

# Lihat struktur data
glimpse(df)
## Rows: 2,525
## Columns: 11
## $ Tanggal <dttm> 2017-02-01, 2017-02-02, 2017-02-03, 2017-02-04, 2017-02-05, 2…
## $ Tn      <dbl> 25.0, 23.8, 23.0, 23.2, 24.2, 25.0, 23.8, 24.6, 23.2, 23.2, 23…
## $ Tx      <dbl> 30.8, 29.2, 30.2, 30.8, 31.2, 31.0, 31.0, 30.6, 28.4, 28.4, 26…
## $ Tavg    <dbl> 26.2, 25.7, 26.1, 27.4, 27.3, 27.7, 27.9, 21.2, 25.8, 25.8, 25…
## $ RH_avg  <dbl> 86, 87, 85, 82, 84, 82, 78, 76, 89, 89, 95, 96, 91, 86, 87, 88…
## $ RR      <dbl> 4.0000000, 24.0000000, 17.0000000, 23.0000000, 11.0000000, 0.0…
## $ ss      <dbl> 5.3, 0.8, 2.3, 4.2, 5.7, 5.7, 5.2, 4.9, 0.0, 0.0, 0.0, 0.7, 4.…
## $ ff_x    <dbl> 6, 5, 5, 7, 5, 8, 9, 10, 8, 8, 3, 6, 6, 6, 8, 10, 4, 9, 5, 4, …
## $ ddd_x   <dbl> 315, 315, 315, 315, 315, 315, 270, 270, 315, 315, 315, 315, 31…
## $ ff_avg  <dbl> 4, 3, 3, 4, 4, 5, 6, 6, 1, 4, 8, 3, 2, 4, 3, 3, 2, 3, 3, 3, 3,…
## $ ddd_car <chr> "NW", "NW", "NW", "NW", "NW", "NW", "W", "W", "NW", "W", "NW",…
# Ubah Tanggal ke format Date + tambah Tahun & Bulan
df <- df %>%
  mutate(
    Tanggal = as.Date(Tanggal),
    Tahun = format(Tanggal, "%Y"),
    Bulan = format(Tanggal, "%m")
  )

# Cek missing value per kolom
colSums(is.na(df))
## Tanggal      Tn      Tx    Tavg  RH_avg      RR      ss    ff_x   ddd_x  ff_avg 
##       0       0       0       0       0       0       0       0       0       0 
## ddd_car   Tahun   Bulan 
##     138       0       0
# Lihat 6 baris awal data
head(df)
## # A tibble: 6 × 13
##   Tanggal       Tn    Tx  Tavg RH_avg    RR    ss  ff_x ddd_x ff_avg ddd_car
##   <date>     <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl> <chr>  
## 1 2017-02-01  25    30.8  26.2     86     4   5.3     6   315      4 NW     
## 2 2017-02-02  23.8  29.2  25.7     87    24   0.8     5   315      3 NW     
## 3 2017-02-03  23    30.2  26.1     85    17   2.3     5   315      3 NW     
## 4 2017-02-04  23.2  30.8  27.4     82    23   4.2     7   315      4 NW     
## 5 2017-02-05  24.2  31.2  27.3     84    11   5.7     5   315      4 NW     
## 6 2017-02-06  25    31    27.7     82     0   5.7     8   315      5 NW     
## # ℹ 2 more variables: Tahun <chr>, Bulan <chr>
library(ggplot2)

# Hitung rata-rata RR per Tahun-Bulan
df_monthly <- df %>%
  group_by(Tahun, Bulan) %>%
  summarise(RR_mean = mean(RR, na.rm = TRUE)) %>%
  ungroup()
## `summarise()` has grouped output by 'Tahun'. You can override using the
## `.groups` argument.
# Pastikan Tahun & Bulan urut
df_monthly$Tahun <- as.factor(df_monthly$Tahun)
df_monthly$Bulan <- factor(df_monthly$Bulan, 
                           levels = sprintf("%02d", 1:12),
                           labels = month.abb)
ggplot(df_monthly, aes(x = Bulan, y = Tahun, fill = RR_mean)) +
  geom_tile(color = "white") +
  scale_fill_gradient(low = "lightblue", high = "darkblue", 
                      name = "RR (mm)") +
  labs(title = "Heatmap Curah Hujan Rata-rata Bulanan",
       x = "Bulan", y = "Tahun") +
  theme_minimal()

Dari heatmap terlihat bahwa puncak curah hujan rata-rata terjadi pada awal tahun (Januari–Maret) dan akhir tahun (Oktober–Desember). Sebaliknya, periode musim kemarau (Juni–Agustus) menunjukkan curah hujan yang lebih rendah. Pola ini konsisten tiap tahun meskipun intensitasnya bervariasi, misalnya pada Februari 2018 terlihat sebagai periode dengan curah hujan tertinggi dalam dataset. Hal ini menunjukkan kuatnya pengaruh monsun Asia dan Australia terhadap pola iklim di Semarang.

df$Bulan <- factor(df$Bulan, 
                   levels = sprintf("%02d", 1:12),
                   labels = month.abb)
ggplot(df, aes(x = Bulan, y = Tavg)) +
  geom_boxplot(fill = "skyblue", color = "darkblue") +
  labs(title = "Boxplot Suhu Rata-rata Harian per Bulan",
       x = "Bulan", y = "Suhu Rata-rata (°C)") +
  theme_minimal()

Boxplot memperlihatkan bahwa suhu rata-rata harian di Semarang relatif stabil sepanjang tahun, dengan median suhu berada di kisaran 27–29°C. Namun, terdapat fluktuasi musiman kecil: suhu cenderung lebih tinggi pada Mei–November, sedangkan pada Januari–Maret cenderung sedikit lebih rendah. Adanya outlier menandakan kejadian ekstrem (misalnya hujan deras yang menurunkan suhu, atau gelombang panas lokal). Hal ini memberi gambaran variasi mikro-klimatik harian yang tidak tercermin dari median saja.

# Hitung rata-rata Tavg per tahun
df_yearly <- df %>%
  group_by(Tahun) %>%
  summarise(Tavg_mean = mean(Tavg, na.rm = TRUE))
ggplot(df_yearly, aes(x = as.numeric(Tahun), y = Tavg_mean)) +
  geom_line(color = "red", size = 1) +
  geom_point(color = "darkred", size = 2) +
  labs(title = "Tren Suhu Rata-rata Tahunan",
       x = "Tahun", y = "Suhu Rata-rata (°C)") +
  theme_minimal()
## 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.

Grafik tren suhu tahunan memperlihatkan fluktuasi dari tahun ke tahun, namun secara keseluruhan terdapat indikasi kenaikan suhu rata-rata pada periode pengamatan, dengan lonjakan signifikan pada tahun 2023. Kondisi ini sejalan dengan fenomena global warming dan juga bisa dipengaruhi faktor lokal, seperti urban heat island akibat pertumbuhan kota. Tren ini penting sebagai indikator awal perubahan iklim lokal, yang bisa berdampak pada kesehatan masyarakat, produktivitas pertanian, dan kebutuhan energi.

# Scatter plot hubungan curah hujan vs suhu rata-rata
ggplot(df, aes(x = RR, y = Tavg)) +
  geom_point(alpha = 0.4, color = "blue") +
  geom_smooth(method = "lm", se = FALSE, color = "red") +
  labs(
    title = "Hubungan Curah Hujan (RR) dengan Suhu Rata-rata (Tavg)",
    x = "Curah Hujan Harian (mm)",
    y = "Suhu Rata-rata Harian (°C)"
  ) +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Scatter plot menunjukkan hubungan antara curah hujan harian dengan suhu rata-rata. Dari hasil visualisasi terlihat pola hubungan negatif, di mana semakin tinggi curah hujan maka suhu rata-rata cenderung menurun. Hal ini logis secara fisik karena hujan yang lebat biasanya disertai pendinginan udara akibat penguapan dan pelepasan panas laten.Sebaran titik cukup lebar pada curah hujan rendah (0–20 mm), yang menandakan bahwa suhu pada hari tanpa hujan atau hujan ringan bisa sangat bervariasi, mulai dari 25°C hingga lebih dari 30°C. Garis regresi linear yang ditambahkan memperkuat indikasi adanya korelasi negatif meskipun tidak terlalu kuat. Inimenunjukkan bahwa kejadian hujan signifikan dapat menurunkan suhu harian, sehingga berperan dalam menjaga kenyamanan termal penduduk. Sebaliknya, periode tanpa hujan panjang berpotensi meningkatkan suhu ekstrem, yang dapat memengaruhi kesehatan, kebutuhan pendingin ruangan, serta produktivitas aktivitas luar ruangan.

# Histogram distribusi suhu rata-rata
ggplot(df, aes(x = Tavg)) +
  geom_histogram(binwidth = 0.5, fill = "skyblue", color = "black", alpha = 0.7) +
  labs(
    title = "Distribusi Suhu Rata-rata Harian",
    x = "Suhu Rata-rata (°C)",
    y = "Frekuensi"
  ) +
  theme_minimal()

Histogram memperlihatkan bahwa distribusi suhu rata-rata harian di Semarang cenderung mendekati distribusi normal, dengan puncak frekuensi berada di sekitar 27–28°C. Sebagian besar hari dalam periode pengamatan memiliki suhu rata-rata dalam rentang 26–29°C, menunjukkan bahwa iklim di kota ini relatif hangat dan stabil. Namun, distribusi juga menunjukkan ekor kiri dan kanan (tail) yang lebih jarang. Ekor kiri (suhu < 25°C) merepresentasikan hari-hari hujan lebat atau berawan tebal yang menurunkan suhu secara signifikan. Ekor kanan (suhu > 30°C) mengindikasikan hari-hari panas ekstrem, yang kemungkinan besar terjadi pada musim kemarau.