PEMODELAN LOCALLY COMPENSATED RIDGE IMPROVED GEOGRAPHICALLY TEMPORALLY WEIGHTED REGRESSION PADA DATA TINGKAT FERTILITAS (TFR) SULAWESI DAFTAR ISI 0. Pengaturan dan paket 1. Data 2. OLS 3. Bandwidth GWR (pemilihan kernel) 4. Pengujian asumsi (normalitas, heterogenitas spasial, multikolinearitas) 5. GWR 6. Matriks pembobot spasial W, Moran’s I, dan uji LM 7. GWR-SAR: bandwidth, estimator, dan estimasi 8. Perbandingan model
# ---- 0.1 Lokasi file (sesuaikan) ----
dir_kerja <- "C:/Users/ASUS/Downloads"
file_func <- file.path(dir_kerja, "FUNCTION_LCR-IGTWRne.R")
file_data <- file.path(dir_kerja, "Data_TFR_Sulawesi_2025.xlsx")
sheet_data <- "Data Gabungan"
# ---- 0.2 Pengaturan model ----
alpha <- 0.05 # taraf signifikansi
# ---- 0.3 Paket ----
# install.packages(c("readxl", "openxlsx", "lmtest", "car", "corrplot",
# "spdep", "MASS", "sp", "spgwr", "GWmodel")) # cukup sekali
paket <- c("readxl", # membaca data Excel
"openxlsx", # menyimpan hasil ke Excel
"lmtest", # bptest()
"car", # vif()
"corrplot", # plot korelasi
"spdep", # mat2listw(), moran.test()
"MASS", # ginv()
"sp", "spgwr", "GWmodel") # gold() untuk bandwidth CV
invisible(lapply(paket, library, character.only = TRUE))
## Warning: package 'readxl' was built under R version 4.5.3
## Warning: package 'openxlsx' was built under R version 4.5.3
## Warning: package 'lmtest' was built under R version 4.5.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.5.3
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Warning: package 'car' was built under R version 4.5.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.5.3
## Warning: package 'corrplot' was built under R version 4.5.3
## corrplot 0.95 loaded
## Warning: package 'spdep' was built under R version 4.5.3
## Loading required package: spData
## Warning: package 'spData' was built under R version 4.5.3
## To access larger datasets in this package, install the spDataLarge
## package with: `install.packages('spDataLarge',
## repos='https://nowosad.github.io/drat/', type='source')`
## Loading required package: sf
## Warning: package 'sf' was built under R version 4.5.3
## Linking to GEOS 3.14.1, GDAL 3.12.1, PROJ 9.7.1; sf_use_s2() is TRUE
## Warning: package 'MASS' was built under R version 4.5.3
## Warning: package 'sp' was built under R version 4.5.3
## Warning: package 'spgwr' was built under R version 4.5.3
## NOTE: This package does not constitute approval of GWR
## as a method of spatial analysis; see example(gwr)
## Warning: package 'GWmodel' was built under R version 4.5.3
## Loading required package: robustbase
## Warning: package 'robustbase' was built under R version 4.5.3
## Loading required package: Rcpp
## Warning: package 'Rcpp' was built under R version 4.5.3
## Welcome to GWmodel version 2.4-2.
# ---- 0.4 Fungsi buatan sendiri ----
source(file_func)
data <- data.frame(read_excel(file_data, sheet = sheet_data))
y <- data[, 5] # respon: TFR
x <- data[, c(6, 7, 9, 10)] # prediktor: RLS, TPAKP, TPT, MISKIN
coord <- data[, 3:4] # koordinat: Longitude, Latitude
n <- nrow(data)
D <- jarak.euclid(coord) # matriks jarak (dipakai di bagian 6 dan 7)
str(data)
## 'data.frame': 81 obs. of 10 variables:
## $ prov : chr "Sulawesi Utara" "Sulawesi Utara" "Sulawesi Utara" "Sulawesi Utara" ...
## $ kabkot : chr "Bolaang Mongondow" "Minahasa" "Kepulauan Sangihe" "Kepulauan Talaud" ...
## $ Longitude : num 282361 373638 450241 588654 335866 ...
## $ Latitude : num 299607 359465 613607 687412 341272 ...
## $ TFR : num 0.334 0.299 0.316 0.334 0.314 ...
## $ RLS : num 8.49 10.25 8.7 9.97 9.53 ...
## $ TPAKP : num 54.2 48.9 54.5 50.8 50 ...
## $ TPAKL : num 87.6 80.1 81.2 81 84.4 ...
## $ TPT : num 4.97 7.74 2.64 3.4 4.77 6.8 4.07 2.41 3.38 2.91 ...
## $ MISKIN....: num 6.98 5.88 10.91 8.34 8.26 ...
OLS <- lm(y ~ ., data = data.frame(y = y, x))
summary(OLS)
##
## Call:
## lm(formula = y ~ ., data = data.frame(y = y, x))
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.055565 -0.021499 -0.001962 0.016526 0.093182
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.2364334 0.0465002 5.085 2.57e-06 ***
## RLS 0.0024485 0.0044653 0.548 0.585066
## TPAKP 0.0012863 0.0005249 2.450 0.016567 *
## TPT -0.0048266 0.0032404 -1.489 0.140498
## MISKIN.... 0.0049704 0.0013841 3.591 0.000581 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.03276 on 76 degrees of freedom
## Multiple R-squared: 0.4186, Adjusted R-squared: 0.388
## F-statistic: 13.68 on 4 and 76 DF, p-value: 1.894e-08
kernel_uji <- c("exponential", "gaussian", "bisquare", "tricube")
bw_kernel <- sapply(kernel_uji, function(k)
bwd.gwr.twr(y = y, x = x, long.lat = coord, spasial = TRUE, kernel = k))
## Fixed bandwidth: 913788.5 CV score: 0.08278404
## Fixed bandwidth: 564865.3 CV score: 0.07721869
## Fixed bandwidth: 349218.9 CV score: 0.06918309
## Fixed bandwidth: 215942.1 CV score: 0.05921385
## Fixed bandwidth: 133572.5 CV score: 0.05017147
## Fixed bandwidth: 82665.27 CV score: 0.04482401
## Fixed bandwidth: 51202.88 CV score: 0.04320759
## Fixed bandwidth: 31758.06 CV score: 0.04866014
## Fixed bandwidth: 63220.45 CV score: 0.04341538
## Fixed bandwidth: 43775.62 CV score: 0.04369163
## Fixed bandwidth: 55793.18 CV score: 0.04318265
## Fixed bandwidth: 913788.5 CV score: 0.08883346
## Fixed bandwidth: 564865.3 CV score: 0.08346086
## Fixed bandwidth: 349218.9 CV score: 0.0721317
## Fixed bandwidth: 215942.1 CV score: 0.05790676
## Fixed bandwidth: 133572.5 CV score: 0.04626845
## Fixed bandwidth: 82665.27 CV score: 0.05214777
## Fixed bandwidth: 165034.9 CV score: 0.05114479
## Fixed bandwidth: 114127.7 CV score: 0.04366026
## Fixed bandwidth: 102110.1 CV score: 0.04555428
## Fixed bandwidth: 121554.9 CV score: 0.04456849
## Fixed bandwidth: 109537.4 CV score: 0.04493185
## Fixed bandwidth: 116964.6 CV score: 0.04399161
## Fixed bandwidth: 112374.3 CV score: 0.04346589
## Fixed bandwidth: 111290.7 CV score: 0.0433499
## Fixed bandwidth: 110621 CV score: 0.04490323
## Fixed bandwidth: 111704.6 CV score: 0.04339382
## Fixed bandwidth: 913788.5 CV score: 0.07517516
## Fixed bandwidth: 564865.3 CV score: 0.06106176
## Fixed bandwidth: 349218.9 CV score: 0.05044693
## Fixed bandwidth: 215942.1 CV score: 0.05595139
## Fixed bandwidth: 431588.5 CV score: 0.05306428
## Fixed bandwidth: 298311.7 CV score: 0.04744146
## Fixed bandwidth: 266849.3 CV score: 0.05838481
## Fixed bandwidth: 317756.5 CV score: 0.04830623
## Fixed bandwidth: 286294.1 CV score: 0.04677532
## Fixed bandwidth: 278866.9 CV score: 0.05560715
## Fixed bandwidth: 290884.4 CV score: 0.04708051
## Fixed bandwidth: 283457.2 CV score: 0.05493043
## Fixed bandwidth: 288047.5 CV score: 0.04689615
## Fixed bandwidth: 285210.5 CV score: 0.05472604
## Fixed bandwidth: 286963.8 CV score: 0.04682168
## Fixed bandwidth: 913788.5 CV score: 0.07731267
## Fixed bandwidth: 564865.3 CV score: 0.06287393
## Fixed bandwidth: 349218.9 CV score: 0.05055393
## Fixed bandwidth: 215942.1 CV score: 0.06188474
## Fixed bandwidth: 431588.5 CV score: 0.0537769
## Fixed bandwidth: 298311.7 CV score: 0.04713675
## Fixed bandwidth: 266849.3 CV score: 0.0592232
## Fixed bandwidth: 317756.5 CV score: 0.04834538
## Fixed bandwidth: 286294.1 CV score: 0.05593707
## Fixed bandwidth: 305738.9 CV score: 0.04762516
## Fixed bandwidth: 293721.4 CV score: 0.05522601
## Fixed bandwidth: 301148.6 CV score: 0.04733994
## Fixed bandwidth: 296558.3 CV score: 0.0550267
## Fixed bandwidth: 299395.3 CV score: 0.04721736
bw_kernel
## exponential gaussian bisquare tricube
## 55793.18 111290.70 286294.12 298311.68
bandwith.GWR <- unname(bw_kernel[1]) # bandwidth kernel terpilih
h_gwr <- bandwith.GWR
# ---- 4.1 Normalitas sisaan ----
sisaan_ols <- residuals(OLS)
print(ks.test(sisaan_ols, "pnorm", mean = mean(sisaan_ols), sd = sd(sisaan_ols)))
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: sisaan_ols
## D = 0.085734, p-value = 0.5616
## alternative hypothesis: two-sided
print(shapiro.test(sisaan_ols)) # lebih tepat untuk n kecil dan parameter diduga
##
## Shapiro-Wilk normality test
##
## data: sisaan_ols
## W = 0.96141, p-value = 0.01546
# ---- 4.2 Heterogenitas spasial (Breusch-Pagan) ----
BPTest_Spasial <- bptest(OLS, studentize = FALSE)
BPTest_Spasial
##
## Breusch-Pagan test
##
## data: OLS
## BP = 10.014, df = 4, p-value = 0.04018
# ---- 4.3 Multikolinearitas (VIF) ----
Multi <- vif(OLS)
Multi
## RLS TPAKP TPT MISKIN....
## 1.833854 1.354483 2.206433 1.605330
# ---- 4.4 Korelasi antar variabel ----
Korelasi <- corrplot(cor(data.frame(TFR = y, x)), method = "number")
gwr <- prog.gwr(y = y, x = x, long.lat = coord, bwd = bandwith.GWR, kernel = "exponential")
# ---- 5.1 Estimasi parameter ----
Estimasi_GWR <- data.frame(gwr$beta)
summary(Estimasi_GWR)
## X1 X2 X3
## Min. :-0.04657 Min. :-0.022236 Min. :-2.057e-03
## 1st Qu.: 0.19580 1st Qu.:-0.006839 1st Qu.: 1.688e-06
## Median : 0.28684 Median :-0.001852 Median : 6.967e-04
## Mean : 0.28640 Mean : 0.002150 Mean : 5.500e-04
## 3rd Qu.: 0.37988 3rd Qu.: 0.011345 3rd Qu.: 1.157e-03
## Max. : 0.55817 Max. : 0.035220 Max. : 2.709e-03
## X4 X5
## Min. :-0.0193255 Min. :-0.004200
## 1st Qu.:-0.0103342 1st Qu.: 0.001343
## Median :-0.0062097 Median : 0.003205
## Mean :-0.0040757 Mean : 0.004084
## 3rd Qu.: 0.0008578 3rd Qu.: 0.006443
## Max. : 0.0220731 Max. : 0.012530
# ---- 5.2 Matriks jarak dan pembobot ----
Matriks_Jarak <- data.frame(gwr$jarak)
Matriks_Pembobot_W <- data.frame(gwr$bobot)
# write.csv(Matriks_Pembobot_W, file = "Matriks_Pembobot_W.csv", row.names = FALSE)
# ---- 5.3 Kebaikan model ----
R.Square.Adj.GWR <- gwr$R_Square_Adj.GWR
R.Square.JKR.GWR <- gwr$R_Square.GWR
AIC.GWR <- gwr$AIC
kernel<- "exponential"
# ---- 6.1 W lag: kernel, diagonal 0, row-normalized ----
W_lag <- buat.W.lag(D, h_gwr, kernel)
# ---- 6.2 Moran's I pada TFR ----
lw <- mat2listw(W_lag, style = "W")
moran_tfr <- moran.test(data$TFR, lw, randomisation = TRUE, alternative = "two.sided")
print(moran_tfr)
##
## Moran I test under randomisation
##
## data: data$TFR
## weights: lw
##
## Moran I statistic standard deviate = 11.358, p-value < 2.2e-16
## alternative hypothesis: two.sided
## sample estimates:
## Moran I statistic Expectation Variance
## 0.530026989 -0.012500000 0.002281404
# ---- 6.3 Uji LM spasial pada OLS global ----
hasil_lm <- lm.spatial.tests(OLS, W_lag)
keputusan <- pilih.model.lm(hasil_lm, alpha = alpha)
print(hasil_lm, digits = 5)
## Uji Statistik df p.value
## 1 LMerr 49.1964 1 2.3157e-12
## 2 LMlag 61.0042 1 5.6952e-15
## 3 RLMerr 2.7745 1 9.5775e-02
## 4 RLMlag 14.5823 1 1.3417e-04
cat("=> Keputusan LM:", keputusan, "\n")
## => Keputusan LM: SAR
q <- 2 * ncol(x) + 1 # jumlah kolom instrumen
# ---- 7.1 Bandwidth dan estimator ----
# (a) Awal: WLS
bw.sar <- bwd.gwr.sar(y, x, coord, W_lag, kernel, "wls")
estimator <- "wls"
ESS_wls <- hitung.ESS(D, bw.sar$bw, kernel)
cat(sprintf("WLS: h = %.2f, min ESS = %.2f, q = %d\n", bw.sar$bw, min(ESS_wls), q))
## WLS: h = 68328.26, min ESS = 1.33, q = 9
# (b) 2SLS dipakai hanya jika ESS minimum pada bandwidth BARU masih > q
if (min(ESS_wls) > q) {
bw2 <- bwd.gwr.sar(y, x, coord, W_lag, kernel, "2sls")
ESS2 <- hitung.ESS(D, bw2$bw, kernel)
cat(sprintf("2SLS: h = %.2f, min ESS = %.2f\n", bw2$bw, min(ESS2)))
if (min(ESS2) > q) {
bw.sar <- bw2
estimator <- "2sls"
} else {
message("ESS 2SLS <= q pada bandwidth baru -> tetap WLS")
}
}
# (c) Cek batas grid
if (bw.sar$idx_grid %in% c(1, nrow(bw.sar$grid)))
warning("Optimum jatuh di batas grid: perlebar rentang bandwidth.")
# ---- 7.2 Estimasi akhir ----
fit <- prog.gwr.sar(y, x, coord, W_lag, bw.sar$bw, kernel, estimator)
cat(sprintf("=> Estimator = %s, h optimum = %.2f (CV = %.5f)\n",
fit$estimator, bw.sar$bw, bw.sar$cv))
## => Estimator = wls, h optimum = 68328.26 (CV = 0.04082)
# ---- 7.3 Parameter lokal ----
Estimasi_GWRSAR <- data.frame(coord, fit$beta)
print(summary(Estimasi_GWRSAR))
## Longitude Latitude Rho Intercept
## Min. :-286460 Min. :-504107 Min. :-0.5498 Min. :-0.09014
## 1st Qu.:-176467 1st Qu.:-270339 1st Qu.: 0.1269 1st Qu.: 0.01529
## Median : 8909 Median :-104925 Median : 0.6269 Median : 0.08106
## Mean : 25406 Mean : -26631 Mean : 0.5018 Mean : 0.13925
## 3rd Qu.: 172975 3rd Qu.: 281036 3rd Qu.: 0.7343 3rd Qu.: 0.33472
## Max. : 588654 Max. : 687412 Max. : 1.2580 Max. : 0.45962
## RLS TPAKP TPT
## Min. :-0.0189923 Min. :-2.270e-03 Min. :-0.0170834
## 1st Qu.:-0.0086700 1st Qu.: 6.494e-05 1st Qu.:-0.0086037
## Median :-0.0036049 Median : 5.840e-04 Median :-0.0061715
## Mean :-0.0007472 Mean : 5.039e-04 Mean :-0.0045891
## 3rd Qu.: 0.0075244 3rd Qu.: 9.933e-04 3rd Qu.:-0.0002186
## Max. : 0.0268045 Max. : 2.260e-03 Max. : 0.0159560
## MISKIN....
## Min. :-0.003606
## 1st Qu.: 0.001441
## Median : 0.002627
## Mean : 0.003141
## 3rd Qu.: 0.004714
## Max. : 0.010531
Rho_lokal <- fit$beta[, "Rho"]
cat(sprintf("Proporsi |rho_i| >= 1 (melanggar stasioneritas): %.3f\n",
mean(abs(Rho_lokal) >= 1)))
## Proporsi |rho_i| >= 1 (melanggar stasioneritas): 0.074
cat(sprintf("Proporsi lokasi signifikan (alpha = %g):\n", alpha))
## Proporsi lokasi signifikan (alpha = 0.05):
print(round(colMeans(fit$pval < alpha), 3))
## Rho Intercept RLS TPAKP TPT MISKIN....
## 0.741 0.148 0.049 0.148 0.185 0.185
# ---- 7.5 Uji kebaikan model (F-test) ----
print(round(fit$F_test, 5))
## F df1 df2 p
## 0.80167 39.39985 75.00000 0.22596
# ---- 7.6 Uji signifikansi parameter lokal (Uji F2) ----
# Pastikan fit sudah di-generate dengan fungsi yang baru dimodifikasi
hasil_f2 <- uji_f2_spasial(fit = fit, alpha = alpha)
print(hasil_f2)
## Variabel F2_Statistik df1 df2 p_value Status
## 1 Rho 5.53 6.71 39.4 < 0.001 Signifikan
## 2 Intercept 7.41 7.00 39.4 < 0.001 Signifikan
## 3 RLS 5.63 7.92 39.4 < 0.001 Signifikan
## 4 TPAKP 2.79 7.80 39.4 0.01569 Signifikan
## 5 TPT 5.66 9.08 39.4 < 0.001 Signifikan
## 6 MISKIN.... 5.10 7.32 39.4 < 0.001 Signifikan
gwr0 <- prog.gwr.sar(y, x, coord, W_lag, h_gwr, kernel, lag = FALSE) # GWR tanpa lag (AICc sebanding)
k_ols <- ncol(x) + 1
perbandingan <- data.frame(
Model = c("OLS", "GWR", "GWR-SAR"),
R2 = c(summary(OLS)$r.squared, gwr0$R2, fit$R2),
R2adj = c(summary(OLS)$adj.r.squared, gwr0$R2adj, fit$R2adj),
AICc = c(aicc.fun(sum(residuals(OLS)^2), n - k_ols, k_ols, n), gwr0$AICc, fit$AICc))
print(perbandingan, digits = 5)
## Model R2 R2adj AICc
## 1 OLS 0.41863 0.38803 -310.797
## 2 GWR 0.94375 0.73446 -62.279
## 3 GWR-SAR 0.92806 0.72290 -125.588