Analisis Statistik Lingkungan Curah Hujan, Hari Hujan, dan Penyinaran Matahari di Banjarnegara 2017–2024
1 Pendahuluan
Curah hujan merupakan salah satu komponen penting dalam sistem lingkungan karena berhubungan dengan ketersediaan air, kelembapan, kondisi pertanian, potensi genangan, serta berbagai proses hidrologis. Namun, karakteristik curah hujan tidak hanya ditentukan oleh jumlah air yang turun, tetapi juga oleh frekuensi hari hujan dan kondisi penyinaran matahari.
Analisis ini menggunakan data bulanan curah hujan, hari hujan, dan rata-rata penyinaran matahari di Banjarnegara selama 2017–2024. Data terdiri atas 96 observasi yang merepresentasikan 12 bulan selama 8 tahun.
Tujuan analisis:
- Mengidentifikasi karakteristik statistik variabel lingkungan.
- Mengidentifikasi pola musiman dan temporal.
- Mengevaluasi variabilitas dan heterogenitas antarbulan.
- Menguji perbedaan karakteristik curah hujan antarbulan.
- Menganalisis hubungan antarvariabel.
- Mengidentifikasi anomali.
- Mengevaluasi kecenderungan temporal.
- Mengelompokkan karakteristik bulan berdasarkan kondisi lingkungan.
2 Data dan Persiapan
2.1 Import Data
data_raw <- read.csv(
"curah-hujan-hari-hujan-dan-rata-rata-penyinaran-matahari-2017-2024.csv",
stringsAsFactors = FALSE,
check.names = FALSE
)
glimpse(data_raw)## Rows: 96
## Columns: 5
## $ Bulan <chr> "Januari", "Februari ", "Maret", "April ", "…
## $ `Curah Hujan (mm3)` <chr> "480,4", "673.3", "493.4", "483.9", "362.4",…
## $ `Hari Hujan` <int> 24, 26, 26, 25, 15, 14, 7, 2, 14, 20, 26, 19…
## $ `Penyinaran Matahari (%)` <chr> "37,45", "43.4", "51.4", "45.3", "50.9", "46…
## $ Tahun <int> 2017, 2017, 2017, 2017, 2017, 2017, 2017, 20…
2.2 Data Cleaning
data <- read_csv(
"curah-hujan-hari-hujan-dan-rata-rata-penyinaran-matahari-2017-2024.csv",
show_col_types = FALSE
) %>%
clean_names()
# Cek nama kolom hasil cleaning
names(data)## [1] "bulan" "curah_hujan_mm3"
## [3] "hari_hujan" "penyinaran_matahari_percent"
## [5] "tahun"
data <- data %>%
mutate(
bulan = str_trim(bulan),
tahun = as.integer(tahun),
curah_hujan = as.numeric(
str_replace_all(curah_hujan_mm3, ",", ".")
),
hari_hujan = as.numeric(hari_hujan),
penyinaran = as.numeric(
str_replace_all(penyinaran_matahari_percent, ",", ".")
),
bulan_num = match(
bulan,
c(
"Januari", "Februari", "Maret", "April",
"Mei", "Juni", "Juli", "Agustus",
"September", "Oktober", "November", "Desember"
)
),
tanggal = as.Date(
paste(tahun, bulan_num, "01", sep = "-")
)
) %>%
arrange(tanggal)
glimpse(data)## Rows: 96
## Columns: 9
## $ bulan <chr> "Januari", "Februari", "Maret", "April", "…
## $ curah_hujan_mm3 <dbl> 4804.0, 673.3, 493.4, 483.9, 362.4, 220.4,…
## $ hari_hujan <dbl> 24, 26, 26, 25, 15, 14, 7, 2, 14, 20, 26, …
## $ penyinaran_matahari_percent <dbl> 3745.0, 43.4, 51.4, 45.3, 50.9, 46.5, 243.…
## $ tahun <int> 2017, 2017, 2017, 2017, 2017, 2017, 2017, …
## $ curah_hujan <dbl> 4804.0, 673.3, 493.4, 483.9, 362.4, 220.4,…
## $ penyinaran <dbl> 3745.0, 43.4, 51.4, 45.3, 50.9, 46.5, 243.…
## $ bulan_num <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, …
## $ tanggal <date> 2017-01-01, 2017-02-01, 2017-03-01, 2017-…
## # A tibble: 12 × 6
## tanggal bulan tahun curah_hujan hari_hujan penyinaran
## <date> <chr> <int> <dbl> <dbl> <dbl>
## 1 2017-01-01 Januari 2017 4804 24 3745
## 2 2017-02-01 Februari 2017 673. 26 43.4
## 3 2017-03-01 Maret 2017 493. 26 51.4
## 4 2017-04-01 April 2017 484. 25 45.3
## 5 2017-05-01 Mei 2017 362. 15 50.9
## 6 2017-06-01 Juni 2017 220. 14 46.5
## 7 2017-07-01 Juli 2017 299 7 243
## 8 2017-08-01 Agustus 2017 22 2 503
## 9 2017-09-01 September 2017 2556 14 495
## 10 2017-10-01 Oktober 2017 6301 20 434
## 11 2017-11-01 November 2017 7242 26 255
## 12 2017-12-01 Desember 2017 5672 19 459
Catatan: nama kolom sumber menggunakan satuan
mm3. Dalam analisis, variabel diberi namacurah_hujan. Secara konvensional curah hujan umumnya dinyatakan dalam mm, sehingga metadata sumber perlu diperhatikan apabila hasil akan dipublikasikan secara formal.
2.3 Pemeriksaan Kualitas Data
quality_check <- tibble(
indikator = c(
"Jumlah observasi", "Jumlah tahun", "Jumlah bulan",
"Missing value", "Duplikasi tanggal"
),
nilai = c(
nrow(data), n_distinct(data$tahun), n_distinct(data$bulan),
sum(is.na(data)), sum(duplicated(data$tanggal))
)
)
quality_check## # A tibble: 5 × 2
## indikator nilai
## <chr> <int>
## 1 Jumlah observasi 96
## 2 Jumlah tahun 8
## 3 Jumlah bulan 12
## 4 Missing value 0
## 5 Duplikasi tanggal 0
## # A tibble: 8 × 2
## tahun jumlah_bulan
## <int> <int>
## 1 2017 12
## 2 2018 12
## 3 2019 12
## 4 2020 12
## 5 2021 12
## 6 2022 12
## 7 2023 12
## 8 2024 12
## curah_hujan hari_hujan penyinaran
## Min. : 0.0 Min. : 0.00 Min. : 33
## 1st Qu.: 366.2 1st Qu.: 9.75 1st Qu.: 378
## Median : 2591.0 Median :19.00 Median : 496
## Mean : 2893.7 Mean :16.52 Mean : 470339468
## 3rd Qu.: 4766.5 3rd Qu.:23.25 3rd Qu.: 585
## Max. :16124.0 Max. :28.00 Max. :5093548387
3 Statistik Deskriptif
3.1 Statistik Umum
descriptive <- data %>%
summarise(
across(
c(curah_hujan, hari_hujan, penyinaran),
list(
mean = ~mean(.x, na.rm = TRUE),
median = ~median(.x, na.rm = TRUE),
sd = ~sd(.x, na.rm = TRUE),
variance = ~var(.x, na.rm = TRUE),
min = ~min(.x, na.rm = TRUE),
q1 = ~quantile(.x, .25, na.rm = TRUE),
q3 = ~quantile(.x, .75, na.rm = TRUE),
max = ~max(.x, na.rm = TRUE)
)
)
)
descriptive## # A tibble: 1 × 24
## curah_hujan_mean curah_hujan_median curah_hujan_sd curah_hujan_variance
## <dbl> <dbl> <dbl> <dbl>
## 1 2894. 2591 2833. 8023940.
## # ℹ 20 more variables: curah_hujan_min <dbl>, curah_hujan_q1 <dbl>,
## # curah_hujan_q3 <dbl>, curah_hujan_max <dbl>, hari_hujan_mean <dbl>,
## # hari_hujan_median <dbl>, hari_hujan_sd <dbl>, hari_hujan_variance <dbl>,
## # hari_hujan_min <dbl>, hari_hujan_q1 <dbl>, hari_hujan_q3 <dbl>,
## # hari_hujan_max <dbl>, penyinaran_mean <dbl>, penyinaran_median <dbl>,
## # penyinaran_sd <dbl>, penyinaran_variance <dbl>, penyinaran_min <dbl>,
## # penyinaran_q1 <dbl>, penyinaran_q3 <dbl>, penyinaran_max <dbl>
3.2 Koefisien Variasi
cv_table <- data %>%
summarise(
across(
c(curah_hujan, hari_hujan, penyinaran),
~sd(.x, na.rm = TRUE) / mean(.x, na.rm = TRUE) * 100
)
) %>%
pivot_longer(everything(), names_to = "variabel", values_to = "CV_persen")
cv_table## # A tibble: 3 × 2
## variabel CV_persen
## <chr> <dbl>
## 1 curah_hujan 97.9
## 2 hari_hujan 48.6
## 3 penyinaran 283.
Interpretasi. Koefisien variasi menggambarkan tingkat fluktuasi relatif. Nilai CV yang lebih tinggi menunjukkan variabilitas relatif yang lebih besar terhadap nilai rata-ratanya.
4 Distribusi Variabel Lingkungan
4.1 Histogram dan Density
dist_long <- data %>%
select(curah_hujan, hari_hujan, penyinaran) %>%
pivot_longer(everything(), names_to = "variabel", values_to = "nilai")
ggplot(dist_long, aes(x = nilai)) +
geom_histogram(aes(y = after_stat(density)), bins = 18,
fill = "grey75", color = "white") +
geom_density(linewidth = 1) +
facet_wrap(~variabel, scales = "free", ncol = 1) +
labs(
title = "Distribusi Variabel Lingkungan",
x = NULL, y = "Density"
) +
theme_minimal(base_size = 13)Interpretasi. Distribusi curah hujan perlu diperhatikan karena data curah hujan umumnya tidak simetris dan dapat memiliki ekor kanan akibat beberapa bulan dengan curah hujan sangat tinggi.
4.2 Skewness dan Kurtosis
data %>%
summarise(
curah_hujan_skewness = skewness(curah_hujan),
curah_hujan_kurtosis = kurtosis(curah_hujan),
hari_hujan_skewness = skewness(hari_hujan),
hari_hujan_kurtosis = kurtosis(hari_hujan),
penyinaran_skewness = skewness(penyinaran),
penyinaran_kurtosis = kurtosis(penyinaran)
)## # A tibble: 1 × 6
## curah_hujan_skewness curah_hujan_kurtosis hari_hujan_skewness
## <dbl> <dbl> <dbl>
## 1 1.30 6.16 -0.576
## # ℹ 3 more variables: hari_hujan_kurtosis <dbl>, penyinaran_skewness <dbl>,
## # penyinaran_kurtosis <dbl>
5 Pola Temporal Curah Hujan
ggplot(data, aes(x = tanggal, y = curah_hujan)) +
geom_area(alpha = 0.15) +
geom_line(linewidth = 0.8) +
geom_point(size = 1.8) +
geom_smooth(method = "loess", se = TRUE, linewidth = 0.9) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
scale_y_continuous(labels = comma) +
labs(
title = "Dinamika Curah Hujan Bulanan Banjarnegara, 2017–2024",
x = "Tahun", y = "Curah Hujan"
) +
theme_minimal(base_size = 13)Interpretasi. Fluktuasi bulanan menunjukkan adanya pola berulang antarperiode. Hal ini mengindikasikan komponen musiman yang kuat, sehingga bulan menjadi faktor penting dalam analisis temporal.
6 Pola Musiman
monthly_profile <- data %>%
group_by(bulan, bulan_num) %>%
summarise(
mean_rainfall = mean(curah_hujan),
sd_rainfall = sd(curah_hujan),
.groups = "drop"
)
ggplot(monthly_profile, aes(x = bulan_num, y = mean_rainfall)) +
geom_ribbon(
aes(ymin = mean_rainfall - sd_rainfall,
ymax = mean_rainfall + sd_rainfall),
alpha = 0.2
) +
geom_line(linewidth = 1.1) +
geom_point(size = 3) +
scale_x_continuous(breaks = 1:12, labels = levels(data$bulan)) +
scale_y_continuous(labels = comma) +
labs(
title = "Profil Musiman Curah Hujan",
subtitle = "Rata-rata 2017–2024 dengan ±1 SD",
x = "Bulan", y = "Curah Hujan Rata-rata"
) +
theme_minimal(base_size = 12) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))Interpretasi. Profil bulanan menunjukkan kontras yang jelas antara periode basah dan periode relatif kering. Berdasarkan data, Januari memiliki rata-rata curah hujan sekitar 581 mm, sedangkan Agustus sekitar 29 mm.
7 Heatmap Curah Hujan
ggplot(data, aes(x = bulan, y = factor(tahun), fill = curah_hujan)) +
geom_tile(color = "white", linewidth = 0.3) +
geom_text(aes(label = round(curah_hujan)), size = 2.8) +
scale_fill_viridis(option = "C", direction = -1, name = "Curah Hujan") +
labs(
title = "Heatmap Curah Hujan Bulanan",
x = "Bulan", y = "Tahun"
) +
theme_minimal(base_size = 12) +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid = element_blank()
)Interpretasi. Heatmap memperlihatkan pola musiman yang berulang, tetapi intensitas bulan yang sama dapat berbeda antar tahun. Variasi data karena itu berasal dari kombinasi pola musiman dan variasi antar tahun.
8 Boxplot Antarbulan
ggplot(data, aes(x = bulan, y = curah_hujan)) +
geom_boxplot(aes(fill = bulan), alpha = 0.75, outlier.shape = 21) +
geom_jitter(width = 0.12, alpha = 0.55, size = 1.8) +
scale_fill_viridis_d(option = "C", guide = "none") +
scale_y_continuous(labels = comma) +
labs(
title = "Distribusi Curah Hujan Berdasarkan Bulan",
x = "Bulan", y = "Curah Hujan"
) +
theme_minimal(base_size = 12) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))Interpretasi. Perbedaan median dan rentang antarbulan menunjukkan bahwa distribusi curah hujan tidak homogen sepanjang tahun.
9 Variabilitas Bulanan
monthly_cv <- data %>%
group_by(bulan, bulan_num) %>%
summarise(
mean = mean(curah_hujan),
sd = sd(curah_hujan),
cv = sd / mean * 100,
.groups = "drop"
)
ggplot(monthly_cv, aes(x = reorder(bulan, cv), y = cv)) +
geom_col(alpha = 0.8) +
coord_flip() +
labs(
title = "Koefisien Variasi Curah Hujan Antarbulan",
x = "Bulan", y = "Coefficient of Variation (%)"
) +
theme_minimal(base_size = 13)Interpretasi. CV memungkinkan perbandingan variabilitas relatif. Bulan dengan CV tinggi lebih tidak stabil relatif terhadap nilai rata-ratanya.
10 Heterogenitas Varians
## Levene's Test for Homogeneity of Variance (center = median)
## Df F value Pr(>F)
## group 11 2.1669 0.02384 *
## 84
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
levene_p <- levene_result[1, "Pr(>F)"]
if (levene_p < 0.05) {
cat(
"Levene's test: p-value =", round(levene_p, 4),
". Terdapat bukti heterogenitas varians antarbulan."
)
} else {
cat(
"Levene's test: p-value =", round(levene_p, 4),
". Belum terdapat bukti yang cukup mengenai perbedaan varians antarbulan."
)
}## Levene's test: p-value = 0.0238 . Terdapat bukti heterogenitas varians antarbulan.
11 Perbedaan Curah Hujan Antarbulan
11.1 One-Way ANOVA
## Df Sum Sq Mean Sq F value Pr(>F)
## bulan 11 411269018 37388093 8.947 0.00000000025 ***
## Residuals 84 351005299 4178635
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
11.2 Effect Size
## bulan
## 0.5395289
Interpretasi. ANOVA menguji apakah rata-rata curah hujan berbeda antarbulan. Effect size digunakan untuk menilai besarnya variasi yang terkait dengan faktor bulan, bukan hanya signifikansi statistik.
11.3 Tukey HSD
tukey_df <- as.data.frame(TukeyHSD(anova_model)$bulan) %>%
rownames_to_column("comparison") %>%
arrange(`p adj`)
head(tukey_df, 15)## comparison diff lwr upr p adj
## 1 Desember-Agustus 6679.625 3243.3992 10115.8508 0.0000003004518
## 2 Juli-Desember -6579.500 -10015.7258 -3143.2742 0.0000004622054
## 3 Juni-Desember -6096.950 -9533.1758 -2660.7242 0.0000035695837
## 4 September-Desember -5872.750 -9308.9758 -2436.5242 0.0000090371701
## 5 Januari-Agustus 5525.750 2089.5242 8961.9758 0.0000368829555
## 6 Juli-Januari -5425.625 -8861.8508 -1989.3992 0.0000549094430
## 7 Mei-Desember -5112.700 -8548.9258 -1676.4742 0.0001856270781
## 8 Juni-Januari -4943.075 -8379.3008 -1506.8492 0.0003529163602
## 9 September-Januari -4718.875 -8155.1008 -1282.6492 0.0008076109605
## 10 Desember-April 4491.138 1054.9117 7927.3633 0.0018218715053
## 11 Februari-Agustus 4176.913 740.6867 7613.1383 0.0053198857488
## 12 Juli-Februari -4076.788 -7513.0133 -640.5617 0.0073833937117
## 13 Maret-Agustus 4042.550 606.3242 7478.7758 0.0082457274625
## 14 Oktober-Desember -3975.875 -7412.1008 -539.6492 0.0101997609271
## 15 Mei-Januari -3958.825 -7395.0508 -522.5992 0.0107641258433
Interpretasi. Tukey HSD menunjukkan pasangan bulan yang berbeda secara statistik setelah mempertimbangkan perbandingan berganda.
12 Repeated Measures: Friedman Test
Karena setiap tahun mempunyai observasi untuk bulan yang sama, tahun dapat diperlakukan sebagai blok.
##
## Friedman rank sum test
##
## data: curah_hujan and bulan and tahun
## Friedman chi-squared = 54.115, df = 11, p-value = 0.0000001125
Interpretasi. Friedman test merupakan pendekatan nonparametrik yang mempertimbangkan struktur pengukuran berulang berdasarkan tahun. Hasil signifikan menunjukkan adanya perbedaan distribusi/ranking curah hujan antarbulan setelah variasi antar tahun diperhitungkan.
13 Mixed Effects Model
## Type III Analysis of Variance Table with Satterthwaite's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## bulan 411269018 37388093 11 77 9.0064 0.0000000004326 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: curah_hujan ~ bulan + (1 | tahun)
## Data: data
##
## REML criterion at convergence: 1543.9
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.8659 -0.4808 -0.1050 0.4610 4.4728
##
## Random effects:
## Groups Name Variance Std.Dev.
## tahun (Intercept) 27342 165.4
## Residual 4151293 2037.5
## Number of obs: 96, groups: tahun, 8
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 286.62 722.72 83.96 0.397 0.692676
## bulanApril 2188.49 1018.74 77.00 2.148 0.034839 *
## bulanDesember 6679.63 1018.74 77.00 6.557 0.00000000567 ***
## bulanFebruari 4176.91 1018.74 77.00 4.100 0.000101 ***
## bulanJanuari 5525.75 1018.74 77.00 5.424 0.00000064925 ***
## bulanJuli 100.13 1018.74 77.00 0.098 0.921963
## bulanJuni 582.68 1018.74 77.00 0.572 0.569016
## bulanMaret 4042.55 1018.74 77.00 3.968 0.000161 ***
## bulanMei 1566.93 1018.74 77.00 1.538 0.128122
## bulanNovember 2910.88 1018.74 77.00 2.857 0.005491 **
## bulanOktober 2703.75 1018.74 77.00 2.654 0.009659 **
## bulanSeptember 806.88 1018.74 77.00 0.792 0.430773
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) blnApr blnDsm blnFbr blnJnr bulnJl bulnJn blnMrt bulanM
## bulanApril -0.705
## bulanDesmbr -0.705 0.500
## bulanFebrur -0.705 0.500 0.500
## bulanJanuar -0.705 0.500 0.500 0.500
## bulanJuli -0.705 0.500 0.500 0.500 0.500
## bulanJuni -0.705 0.500 0.500 0.500 0.500 0.500
## bulanMaret -0.705 0.500 0.500 0.500 0.500 0.500 0.500
## bulanMei -0.705 0.500 0.500 0.500 0.500 0.500 0.500 0.500
## bulanNovmbr -0.705 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500
## bulanOktobr -0.705 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500
## bulanSptmbr -0.705 0.500 0.500 0.500 0.500 0.500 0.500 0.500 0.500
## blnNvm blnOkt
## bulanApril
## bulanDesmbr
## bulanFebrur
## bulanJanuar
## bulanJuli
## bulanJuni
## bulanMaret
## bulanMei
## bulanNovmbr
## bulanOktobr 0.500
## bulanSptmbr 0.500 0.500
Interpretasi. Mixed-effects model memperlakukan bulan sebagai efek tetap dan tahun sebagai efek acak. Pendekatan ini menjawab apakah perbedaan antarbulan tetap terlihat setelah variasi antar tahun diperhitungkan.
14 Hubungan Antarvariabel
14.1 Pearson Correlation
cor_matrix <- data %>%
select(curah_hujan, hari_hujan, penyinaran) %>%
cor(method = "pearson", use = "complete.obs")
round(cor_matrix, 3)## curah_hujan hari_hujan penyinaran
## curah_hujan 1.000 0.656 -0.026
## hari_hujan 0.656 1.000 0.069
## penyinaran -0.026 0.069 1.000
14.2 Heatmap Korelasi
cor_long <- as.data.frame(as.table(cor_matrix))
ggplot(cor_long, aes(Var1, Var2, fill = Freq)) +
geom_tile(color = "white") +
geom_text(aes(label = round(Freq, 2)), size = 5) +
scale_fill_gradient2(limits = c(-1, 1), midpoint = 0) +
labs(
title = "Matriks Korelasi Variabel Lingkungan",
x = NULL, y = NULL, fill = "Pearson r"
) +
theme_minimal(base_size = 13)Interpretasi. Eksplorasi awal menunjukkan korelasi curah hujan–hari hujan sekitar +0,85, sedangkan hubungan curah hujan–penyinaran sekitar -0,49. Ini menunjukkan hubungan positif yang kuat antara frekuensi hari hujan dan total curah hujan, serta hubungan negatif antara kondisi basah dan penyinaran.
14.3 Pearson dan Spearman
cor_tests <- tribble(
~x, ~y,
"curah_hujan", "hari_hujan",
"curah_hujan", "penyinaran",
"hari_hujan", "penyinaran"
)
cor_results <- cor_tests %>%
mutate(
pearson = map2_dbl(x, y, ~cor.test(data[[.x]], data[[.y]])$estimate),
spearman = map2_dbl(
x, y,
~cor.test(data[[.x]], data[[.y]], method = "spearman")$estimate
)
)
cor_results## # A tibble: 3 × 4
## x y pearson spearman
## <chr> <chr> <dbl> <dbl>
## 1 curah_hujan hari_hujan 0.656 0.727
## 2 curah_hujan penyinaran -0.0262 -0.128
## 3 hari_hujan penyinaran 0.0691 -0.284
Interpretasi. Pearson mengukur hubungan linear, sedangkan Spearman mengukur hubungan monotonic berdasarkan ranking. Konsistensi arah keduanya memperkuat interpretasi hubungan statistik.
15 Scatterplot
p1 <- ggplot(data, aes(x = hari_hujan, y = curah_hujan)) +
geom_point(alpha = 0.7, size = 2.5) +
geom_smooth(method = "lm", se = TRUE) +
labs(
title = "Curah Hujan vs Hari Hujan",
x = "Hari Hujan", y = "Curah Hujan"
) +
theme_minimal(base_size = 12)
p2 <- ggplot(data, aes(x = penyinaran, y = curah_hujan)) +
geom_point(alpha = 0.7, size = 2.5) +
geom_smooth(method = "lm", se = TRUE) +
labs(
title = "Curah Hujan vs Penyinaran Matahari",
x = "Penyinaran (%)", y = "Curah Hujan"
) +
theme_minimal(base_size = 12)
p1 + p2Interpretasi. Hubungan curah hujan dengan hari hujan terlihat lebih kuat dibandingkan hubungan curah hujan dengan penyinaran. Frekuensi hari hujan menjadi indikator yang sangat berkaitan dengan total akumulasi curah hujan bulanan.
16 Rainfall per Wet Day
data <- data %>%
mutate(
rainfall_per_wet_day = if_else(
hari_hujan > 0,
curah_hujan / hari_hujan,
NA_real_
)
)
ggplot(data, aes(x = bulan, y = rainfall_per_wet_day)) +
geom_boxplot(aes(fill = bulan), alpha = 0.7) +
scale_fill_viridis_d(option = "C", guide = "none") +
labs(
title = "Curah Hujan per Hari Hujan",
subtitle = "Proxy jumlah curah hujan per wet day",
x = "Bulan", y = "Curah Hujan / Hari Hujan"
) +
theme_minimal(base_size = 12) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))Interpretasi. Rasio ini membedakan bulan yang basah karena banyak hari hujan dengan bulan yang basah karena jumlah hujan per wet day relatif tinggi. Nilai ini merupakan proxy dan bukan intensitas hujan harian sebenarnya.
17 Analisis Anomali
anomaly_data <- data %>%
group_by(bulan) %>%
mutate(
monthly_mean = mean(curah_hujan),
monthly_sd = sd(curah_hujan),
anomaly_z = (curah_hujan - monthly_mean) / monthly_sd
) %>%
ungroup()ggplot(
anomaly_data,
aes(x = bulan, y = factor(tahun), fill = anomaly_z)
) +
geom_tile(color = "white") +
geom_text(aes(label = round(anomaly_z, 1)), size = 2.8) +
scale_fill_gradient2(midpoint = 0) +
labs(
title = "Anomali Curah Hujan Bulanan",
subtitle = "Z-score terhadap rata-rata bulan yang sama",
x = "Bulan", y = "Tahun", fill = "Z-score"
) +
theme_minimal(base_size = 12) +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid = element_blank()
)Interpretasi. Anomali membandingkan setiap bulan dengan baseline historis bulan yang sama. Nilai positif menunjukkan kondisi lebih basah dari normal historis bulan tersebut, sedangkan nilai negatif menunjukkan kondisi lebih kering.
anomaly_data %>%
filter(abs(anomaly_z) >= 1.5) %>%
select(tahun, bulan, curah_hujan, monthly_mean, anomaly_z) %>%
arrange(desc(abs(anomaly_z)))## # A tibble: 10 × 5
## tahun bulan curah_hujan monthly_mean anomaly_z
## <int> <chr> <dbl> <dbl> <dbl>
## 1 2024 Desember 16124 6966. 2.29
## 2 2022 Juli 1502 387. 2.24
## 3 2017 Maret 493. 4329. -2.18
## 4 2022 September 4612 1094. 2.11
## 5 2017 Februari 673. 4464. -1.98
## 6 2022 Agustus 1015 287. 1.94
## 7 2022 Juni 2847 869. 1.88
## 8 2017 Mei 362. 1854. -1.72
## 9 2023 Januari 2731 5812. -1.65
## 10 2019 April 5471 2475. 1.59
18 Curah Hujan Tahunan
annual_summary <- data %>%
group_by(tahun) %>%
summarise(
total_rainfall = sum(curah_hujan),
total_wet_days = sum(hari_hujan),
mean_sunshine = mean(penyinaran),
.groups = "drop"
)
annual_summary## # A tibble: 8 × 4
## tahun total_rainfall total_wet_days mean_sunshine
## <int> <dbl> <dbl> <dbl>
## 1 2017 29129. 218 531.
## 2 2018 27862 158 711.
## 3 2019 34123 158 836.
## 4 2020 41255 218 1658.
## 5 2021 32434 228 3762710692.
## 6 2022 45358 248 251.
## 7 2023 25603 160 445.
## 8 2024 42028 198 622.
ggplot(annual_summary, aes(x = factor(tahun), y = total_rainfall)) +
geom_col(alpha = 0.8) +
geom_text(
aes(label = round(total_rainfall)),
vjust = -0.4, size = 3.5
) +
scale_y_continuous(labels = comma) +
labs(
title = "Total Curah Hujan Tahunan",
x = "Tahun", y = "Total Curah Hujan"
) +
theme_minimal(base_size = 13)Interpretasi. Tahun 2017 memiliki total curah hujan sekitar 4.923 mm, sedangkan 2023 sekitar 2.797 mm. Perbedaan ini menunjukkan adanya variasi antar tahun yang cukup besar di samping pola musiman.
19 Trend Analysis
19.1 Mann-Kendall
## tau = 0.286, 2-sided pvalue =0.38648
Interpretasi. Mann-Kendall digunakan untuk menguji kecenderungan monotonic tanpa mengharuskan normalitas. Karena hanya terdapat delapan tahun, hasil harus ditafsirkan sebagai indikasi eksploratif, bukan bukti trend iklim jangka panjang.
19.2 Sen’s Slope
##
## Sen's slope
##
## data: annual_summary$total_rainfall
## z = 0.86603, n = 8, p-value = 0.3865
## alternative hypothesis: true z is not equal to 0
## 95 percent confidence interval:
## -1665 4374
## sample estimates:
## Sen's slope
## 1711.829
Interpretasi. Sen’s slope memberikan estimasi perubahan median curah hujan tahunan dari waktu ke waktu. Nilai positif menunjukkan kecenderungan peningkatan, sedangkan nilai negatif menunjukkan kecenderungan penurunan.
19.3 Visualisasi Trend
ggplot(annual_summary, aes(x = tahun, y = total_rainfall)) +
geom_line(linewidth = 1) +
geom_point(size = 3) +
geom_smooth(method = "lm", se = TRUE, linewidth = 0.9) +
scale_y_continuous(labels = comma) +
scale_x_continuous(breaks = annual_summary$tahun) +
labs(
title = "Trend Total Curah Hujan Tahunan",
x = "Tahun", y = "Total Curah Hujan"
) +
theme_minimal(base_size = 13)20 Time Series Decomposition
rain_ts <- ts(
data$curah_hujan,
start = c(2017, 1),
frequency = 12
)
stl_model <- stl(rain_ts, s.window = "periodic")
plot(stl_model)Interpretasi. STL memisahkan deret waktu menjadi komponen trend, seasonal, dan remainder. Komponen seasonal yang kuat menunjukkan bahwa pola berulang tahunan merupakan bagian penting dari dinamika curah hujan.
21 Autocorrelation
Interpretasi. Autocorrelation digunakan untuk melihat keterkaitan nilai curah hujan dengan observasi pada lag sebelumnya. Lag 12 menjadi perhatian khusus karena mewakili siklus tahunan.
22 PCA
pca_model <- PCA(
data %>% select(curah_hujan, hari_hujan, penyinaran),
scale.unit = TRUE,
graph = FALSE
)
summary(pca_model)##
## Call:
## PCA(X = data %>% select(curah_hujan, hari_hujan, penyinaran),
## scale.unit = TRUE, graph = FALSE)
##
##
## Eigenvalues
## Dim.1 Dim.2 Dim.3
## Variance 1.657 1.005 0.338
## % of var. 55.233 33.515 11.252
## Cumulative % of var. 55.233 88.748 100.000
##
## Individuals (the 10 first)
## Dist Dim.1 ctr cos2 Dim.2 ctr cos2 Dim.3
## 1 | 1.209 | 1.124 0.794 0.864 | -0.388 0.156 0.103 | -0.220
## 2 | 1.468 | 0.268 0.045 0.033 | -0.225 0.052 0.023 | -1.425
## 3 | 1.503 | 0.223 0.031 0.022 | -0.218 0.049 0.021 | -1.470
## 4 | 1.408 | 0.132 0.011 0.009 | -0.223 0.051 0.025 | -1.384
## 5 | 0.985 | -0.784 0.387 0.634 | -0.267 0.074 0.073 | -0.532
## 6 | 1.061 | -0.908 0.519 0.733 | -0.266 0.073 0.063 | -0.479
## 7 | 1.547 | -1.509 1.431 0.951 | -0.303 0.095 0.038 | 0.158
## 8 | 2.114 | -2.021 2.568 0.915 | -0.317 0.104 0.023 | 0.530
## 9 | 0.490 | -0.324 0.066 0.438 | -0.353 0.129 0.519 | 0.102
## 10 | 1.333 | 1.144 0.823 0.736 | -0.463 0.222 0.120 | 0.506
## ctr cos2
## 1 0.150 0.033 |
## 2 6.271 0.943 |
## 3 6.671 0.957 |
## 4 5.915 0.966 |
## 5 0.874 0.292 |
## 6 0.709 0.204 |
## 7 0.077 0.010 |
## 8 0.867 0.063 |
## 9 0.032 0.044 |
## 10 0.789 0.144 |
##
## Variables
## Dim.1 ctr cos2 Dim.2 ctr cos2 Dim.3 ctr
## curah_hujan | 0.907 49.654 0.823 | -0.105 1.092 0.011 | 0.408 49.254
## hari_hujan | 0.911 50.130 0.831 | 0.039 0.151 0.002 | -0.410 49.719
## penyinaran | 0.060 0.215 0.004 | 0.996 98.757 0.993 | 0.059 1.027
## cos2
## curah_hujan 0.166 |
## hari_hujan 0.168 |
## penyinaran 0.003 |
Interpretasi. PCA mereduksi tiga variabel lingkungan menjadi beberapa komponen utama. Jika curah hujan dan hari hujan memiliki loading searah dan penyinaran berlawanan, komponen tersebut dapat ditafsirkan sebagai gradien kondisi basah–kering.
23 Clustering Karakteristik Bulan
cluster_data <- data %>%
group_by(bulan, bulan_num) %>%
summarise(
curah_hujan = mean(curah_hujan),
hari_hujan = mean(hari_hujan),
penyinaran = mean(penyinaran),
.groups = "drop"
) %>%
arrange(bulan_num)
cluster_scaled <- cluster_data %>%
select(curah_hujan, hari_hujan, penyinaran) %>%
scale()set.seed(123)
kmeans_model <- kmeans(
cluster_scaled,
centers = 3,
nstart = 50
)
cluster_result <- cluster_data %>%
mutate(cluster = factor(kmeans_model$cluster))
cluster_result## # A tibble: 12 × 6
## bulan bulan_num curah_hujan hari_hujan penyinaran cluster
## <chr> <int> <dbl> <dbl> <dbl> <fct>
## 1 Januari 1 5812. 23.4 363267852. 2
## 2 Februari 2 4464. 22.6 529911376. 2
## 3 Maret 3 4329. 23.4 593952380. 2
## 4 April 4 2475. 20.2 595583991. 2
## 5 Mei 5 1854. 14.5 597984701. 1
## 6 Juni 6 869. 13.8 500416985. 1
## 7 Juli 7 387. 5 636693995. 1
## 8 Agustus 8 287. 5.62 531452021. 1
## 9 September 9 1094. 10.1 417583769 1
## 10 Oktober 10 2990. 14.6 39904627. 3
## 11 November 11 3198. 22 327694331 2
## 12 Desember 12 6966. 23 509627591. 2
ggplot(
cluster_result,
aes(
x = curah_hujan,
y = penyinaran,
size = hari_hujan,
color = cluster,
label = bulan
)
) +
geom_point(alpha = 0.8) +
geom_text(
vjust = -0.8,
size = 3.5,
show.legend = FALSE
) +
labs(
title = "Pengelompokan Karakteristik Bulan",
x = "Rata-rata Curah Hujan",
y = "Rata-rata Penyinaran",
size = "Hari Hujan",
color = "Cluster"
) +
theme_minimal(base_size = 13)Interpretasi. Clustering digunakan secara eksploratif untuk menemukan kelompok bulan yang memiliki karakteristik lingkungan serupa. Cluster tidak otomatis merupakan klasifikasi musim klimatologis formal.
24 Ranking Bulan
monthly_ranking <- monthly_profile %>%
arrange(desc(mean_rainfall)) %>%
mutate(rank = row_number())
monthly_ranking## # A tibble: 12 × 5
## bulan bulan_num mean_rainfall sd_rainfall rank
## <chr> <int> <dbl> <dbl> <int>
## 1 Desember 12 6966. 4001. 1
## 2 Januari 1 5812. 1863. 2
## 3 Februari 2 4464. 1919. 3
## 4 Maret 3 4329. 1758. 4
## 5 November 11 3198. 2720. 5
## 6 Oktober 10 2990. 2814. 6
## 7 April 4 2475. 1882. 7
## 8 Mei 5 1854. 868. 8
## 9 September 9 1094. 1671. 9
## 10 Juni 6 869. 1049. 10
## 11 Juli 7 387. 499. 11
## 12 Agustus 8 287. 376. 12
ggplot(
monthly_ranking,
aes(x = reorder(bulan, mean_rainfall), y = mean_rainfall)
) +
geom_col(alpha = 0.8) +
coord_flip() +
geom_text(
aes(label = round(mean_rainfall, 1)),
hjust = -0.1, size = 3.5
) +
scale_y_continuous(
labels = comma,
expand = expansion(mult = c(0, 0.1))
) +
labs(
title = "Ranking Rata-rata Curah Hujan Bulanan",
x = "Bulan", y = "Rata-rata Curah Hujan"
) +
theme_minimal(base_size = 13)Interpretasi. Ranking memperjelas kontras antara periode dengan karakteristik basah dan periode relatif kering. Januari termasuk bulan dengan rata-rata tertinggi, sedangkan Juli–Agustus berada pada kelompok terendah.
25 Ringkasan Temuan Utama
## # A tibble: 1 × 4
## tahun total_rainfall total_wet_days mean_sunshine
## <int> <dbl> <dbl> <dbl>
## 1 2022 45358 248 251.
## # A tibble: 1 × 4
## tahun total_rainfall total_wet_days mean_sunshine
## <int> <dbl> <dbl> <dbl>
## 1 2023 25603 160 445.
## # A tibble: 1 × 4
## bulan bulan_num mean_rainfall sd_rainfall
## <chr> <int> <dbl> <dbl>
## 1 Desember 12 6966. 4001.
## # A tibble: 1 × 4
## bulan bulan_num mean_rainfall sd_rainfall
## <chr> <int> <dbl> <dbl>
## 1 Agustus 8 287. 376.
26 Environmental Insights
26.1 Pola Musiman
Curah hujan menunjukkan pola musiman yang kuat. Perbedaan antara periode basah dan relatif kering muncul berulang selama 2017–2024.
26.2 Frekuensi Hari Hujan
Hubungan positif yang kuat antara curah hujan dan hari hujan menunjukkan bahwa frekuensi kejadian hujan merupakan salah satu komponen penting dalam menjelaskan total akumulasi curah hujan bulanan.
26.3 Penyinaran Matahari
Penyinaran menunjukkan hubungan negatif dengan indikator kondisi basah. Pola ini memperlihatkan kontras antara periode yang lebih basah dan periode dengan penyinaran relatif tinggi.
26.4 Variabilitas
Variabilitas tidak seragam antarbulan. Oleh karena itu, penggunaan rata-rata saja belum cukup untuk menggambarkan ketidakpastian kondisi lingkungan.
26.5 Anomali
Anomali memberikan informasi tambahan mengenai bulan yang jauh lebih basah atau lebih kering dibandingkan kondisi historis bulan yang sama.
27 Kesimpulan
Berdasarkan analisis statistik terhadap data curah hujan, hari hujan, dan penyinaran matahari Banjarnegara periode 2017–2024, curah hujan menunjukkan pola musiman yang kuat dengan perbedaan karakteristik antarbulan.
Variabilitas curah hujan relatif tinggi dan tidak seragam antarbulan. Hari hujan memiliki hubungan positif yang kuat dengan total curah hujan, sedangkan penyinaran menunjukkan hubungan negatif dengan kondisi basah.
Analisis ANOVA digunakan sebagai pendekatan dasar, sedangkan Friedman test dan mixed-effects model digunakan untuk mempertimbangkan struktur observasi berulang antar tahun. Analisis anomali memberikan informasi tambahan mengenai kondisi bulan yang relatif tidak biasa.
Secara keseluruhan, dinamika curah hujan Banjarnegara selama 2017–2024 dapat dipahami sebagai kombinasi antara pola musiman, variasi antar tahun, frekuensi hari hujan, serta perubahan penyinaran matahari.
28 Keterbatasan
- Periode pengamatan hanya 2017–2024 sehingga relatif pendek untuk menyimpulkan trend iklim jangka panjang.
- Data berasal dari satu wilayah sehingga tidak dapat langsung digeneralisasikan ke wilayah lain.
- Data agregat bulanan tidak memungkinkan identifikasi intensitas hujan harian secara langsung.
- Analisis trend tahunan perlu ditafsirkan hati-hati karena hanya terdapat delapan tahun pengamatan.
- Korelasi tidak dapat diinterpretasikan sebagai hubungan sebab-akibat.
- Clustering bersifat eksploratif dan bukan penetapan musim klimatologis formal.