Line Chart (Mantap Jalan 2015-2025)

data <- data.frame(
  Tahun = 2015:2025,
  Persen_Mantap = c(89.36, 89.37, 90.35, 91.9, 92.81, 91.26, 91.81, 92.2, 94.18, 95.22, 93.65
))
data
##    Tahun Persen_Mantap
## 1   2015         89.36
## 2   2016         89.37
## 3   2017         90.35
## 4   2018         91.90
## 5   2019         92.81
## 6   2020         91.26
## 7   2021         91.81
## 8   2022         92.20
## 9   2023         94.18
## 10  2024         95.22
## 11  2025         93.65
library(ggplot2)

ggplot(data, aes(x = Tahun, y = Persen_Mantap)) +
  geom_line(size = 1.2, color = "red") +
  geom_point(size = 3, color = "steelblue") +
  geom_text(aes(label = sprintf("%.2f", Persen_Mantap)),
            vjust = -1, size = 3, color = "black") +
  labs(
    title = "Tren Persentase Kemantapan Jalan Nasional (2015–2025)",
    x = "Tahun",
    y = "Persentase Jalan Mantap (%)"
  ) +
  scale_x_continuous(breaks = 2015:2025) +
  scale_y_continuous(limits = c(80, 100)) +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Presentase kemantapan jalan nasional sejak tahun 2015 sampai 2025 menunjukkan tren peningkatan, yaitu dari 89.36% hingga mencapai puncak sebesar 95.22% pada tahun 2024. Meskipun sempat terjadi penurunan di tahun 2020 dan 2025, namun secara umum presentase kondisi jalan mantap secara nasional masih berada di sekitar 90%, angka ini menunjukkan infrastruktur nasional yang cukup baik dan relatif stabil untuk mendukung aktifitas logistik. Setelah 2020 data DKI Jakarta tidak tersedia dan dihitung sebagai nol, serta terdapat penambahan beberapa provinsi baru. Perubahan ini dapat memengaruhi perbandingan data antar tahun, sehinggaterdapat kemungkinan perbedaan komposisi dalam perhitungan agregat nasional.

Meskipun terjadi penurunan kecil dibandingkan 2024, kondisi jalan nasional pada 2025 tetap berada pada level kemantapan yang tinggi, sehingga masih mendukung kelancaran distribusi dan aktivitas logistik

Peta

Load Data

library(readxl)
library(sf)
## Linking to GEOS 3.13.1, GDAL 3.11.4, PROJ 9.7.0; sf_use_s2() is TRUE
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.6
## ✔ forcats   1.0.1     ✔ stringr   1.5.1
## ✔ lubridate 1.9.4     ✔ tibble    3.3.1
## ✔ purrr     1.1.0     ✔ tidyr     1.3.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(biscale)
library(cowplot)
## 
## Attaching package: 'cowplot'
## 
## The following object is masked from 'package:lubridate':
## 
##     stamp
library(ggrepel)

file_path <- "C:/Users/Hype AMD/OneDrive - apps.ipb.ac.id/A UP MY HARD SKILL/IPB/Matakuliaih/Semester 4/Visualisasi Data/Pertemuan 4/Data Projek Visdat_Kelompok 7.xlsx"
df <- read_excel(file_path, sheet = "Data Project 1")
map <- st_read ("C:/Users/Hype AMD/Downloads/38 Provinsi Indonesia - Provinsi.json")
## Reading layer `38 Provinsi Indonesia - Provinsi' from data source 
##   `C:\Users\Hype AMD\Downloads\38 Provinsi Indonesia - Provinsi.json' 
##   using driver `GeoJSON'
## Simple feature collection with 38 features and 3 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 95.037 ymin: -11.00724 xmax: 141.02 ymax: 5.907129
## Geodetic CRS:  WGS 84
# Load GeoJSON (Pastikan path ke provinsi.json benar)
head(df)
## # A tibble: 6 × 4
##      No `Nama Provinsi` `Mantap (%)` `PDRB  Tahunan %`
##   <dbl> <chr>                  <dbl>             <dbl>
## 1     1 Aceh                    94.9              2.97
## 2     2 Sumatera Utara          95.0              4.53
## 3     3 Sumatera Barat          90.6              3.37
## 4     4 Riau                    92.9              4.79
## 5     5 Kepulauan Riau         100                6.94
## 6     6 Jambi                   92.2              4.93
df <- df %>%
  rename(
    mantap = `Mantap (%)`,
    pdrb = `PDRB  Tahunan %`
  )

Samain Nama Provinsi

# Cek nama provinsi di map
unique(map$PROVINSI)
##  [1] "Sulawesi Tengah"            "Sulawesi Barat"            
##  [3] "Sulawesi Selatan"           "Papua Tengah"              
##  [5] "Papua Barat"                "Gorontalo"                 
##  [7] "Riau"                       "Papua Selatan"             
##  [9] "Daerah Istimewa Yogyakarta" "Sumatera Barat"            
## [11] "DKI Jakarta"                "Maluku"                    
## [13] "Bengkulu"                   "Lampung"                   
## [15] "Papua"                      "Kepulauan Riau"            
## [17] "Nusa Tenggara Barat"        "Jambi"                     
## [19] "Bali"                       "Jawa Timur"                
## [21] "Papua Barat Daya"           "Sumatera Utara"            
## [23] "Sulawesi Tenggara"          "Nusa Tenggara Timur"       
## [25] "Kalimantan Selatan"         "Aceh"                      
## [27] "Kalimantan Tengah"          "Papua Pegunungan"          
## [29] "Kepulauan Bangka Belitung"  "Sumatera Selatan"          
## [31] "Banten"                     "Sulawesi Utara"            
## [33] "Kalimantan Utara"           "Kalimantan Timur"          
## [35] "Jawa Tengah"                "Maluku Utara"              
## [37] "Kalimantan Barat"           "Jawa Barat"

Merge Data

# Pastikan nama provinsi di df dan map sama untuk merge yang sukses
# Hruf besar kecil harus sama, dan pastikan tidak ada spasi tambahan
map_final <- map %>%
  full_join(df, by = c("PROVINSI" = "Nama Provinsi")) # Sesuaikan nama kolom jika berbeda
view(map_final)

Visualisasi Peta

data_ready <- map_final %>%
  filter(!is.na(mantap) & !is.na(pdrb)) %>%
  bi_class(x = mantap, y = pdrb, style = "quantile", dim = 3)

# 5. Plot Peta Utama
map_plot <- ggplot(data_ready) +
  geom_sf(aes(fill = bi_class), color = "gray20", size = 0.2, show.legend = FALSE) +
  bi_scale_fill(pal = "BlueGold", dim = 3) +
  
  # Label angka persentase dari kolom 'Mantap (%)'
  stat_sf_coordinates(geom = "text_repel", 
                      aes(label = paste0(round(`mantap`, 0), "%")),
                      size = 2.8, 
                      fontface = "bold", 
                      color = "black",
                      bg.color = "white", 
                      bg.r = 0.12,
                      force = 15) +
  
  labs(title = "Sinergi Kemantapan Jalan & Pertumbuhan Ekonomi",
       subtitle = "Warna gelap menunjukkan angka tinggi pada kedua indikator",
       caption = "Sumber: Data Tugas Kelompok 7 (2025)") +
  theme_void() +
  theme(plot.title = element_text(face="bold", size = 16, hjust = 0.5),
        plot.subtitle = element_text(size = 11, hjust = 0.5),
        plot.margin = margin(10, 10, 10, 10))

# 6. Membuat Legenda Bivariate
legend <- bi_legend(pal = "BlueGold",
                    dim = 3,
                    xlab = "Jalan Mantap (%)", 
                    ylab = "PDRB Growth (%)", 
                    size = 6)

# 7. Menggabungkan Peta dan Legenda
final_plot <- ggdraw() +
  draw_plot(map_plot, 0, 0, 1, 1) +
  draw_plot(legend, 0.05, 0.05, 0.25, 0.25)
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may not
## give correct results for longitude/latitude data
# Tampilkan Hasil
print(final_plot)

Scaterplot

Load Data

file_path <- "C:/Users/Hype AMD/OneDrive - apps.ipb.ac.id/A UP MY HARD SKILL/IPB/Matakuliaih/Semester 4/Visualisasi Data/Pertemuan 4/Data Projek Visdat_Kelompok 7.xlsx"
df <- read_excel(file_path, sheet = "Data Project")
head(df)
## # A tibble: 6 × 20
##      No `NO PROV` `Nama Provinsi` `Panjang (KM)` `Baik (KM)` `Baik (%)`
##   <dbl> <chr>     <chr>                    <dbl>       <dbl>      <dbl>
## 1     1 1.0       Aceh                     2112.        691.       32.7
## 2     2 3.0       Sumatera Utara           2620.        940.       35.9
## 3     3 6.0       Sumatera Barat           1423.        485.       34.0
## 4     4 9.0       Riau                     1254.        544.       43.3
## 5     5 10.0      Kepulauan Riau            430.        322.       74.9
## 6     6 11.0      Jambi                    1319.        592.       44.9
## # ℹ 14 more variables: `Sedang (KM)` <dbl>, `Sedang (%)` <dbl>,
## #   `Rusak Ringan (KM)` <dbl>, `Rusak Ringan (%)` <dbl>,
## #   `Rusak Berat (KM)` <dbl>, `Rusak Berat (%)` <dbl>, `Mantap (KM)` <dbl>,
## #   `Mantap (%)` <dbl>, `Tidak Mantap (KM)` <dbl>, `Tidak Mantap (%)` <dbl>,
## #   `PDRB Tahunan (Miliyar)` <dbl>, `PDRB  Tahunan %` <dbl>,
## #   `Jumlah Penduduk (Ribu)` <dbl>, `Jawa/Luar Jawa` <dbl>

Visualisasi Scatterplot Kemantapan Jalan vs PDRB

# 2. Scatter Plot: Panjang Jalan vs PDRB %
Model <- lm(`PDRB  Tahunan %` ~ `Panjang (KM)`, data = df)
ggplot(df, aes(x = `Panjang (KM)`, y = `PDRB  Tahunan %`)) +
  geom_point(color = "steelblue", size = 3) +
  geom_smooth(method = "lm", se = FALSE, color = "red") +
  labs(
    title = "Hubungan Panjang Jalan dengan Pertumbuhan PDRB",
    x = "Panjang Jalan (KM)",
    y = "Pertumbuhan PDRB Tahunan (%)"
  ) +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

# 3. Scatter Plot: Kemantapan Jalan vs PDRB %
Model <- lm(`PDRB  Tahunan %` ~ `Mantap (%)`, data = df)
ggplot(df, aes(x = `Mantap (%)`, y = `PDRB  Tahunan %`)) +
  geom_point(color = "steelblue", size = 3) +
  geom_smooth(method = "lm", se = FALSE, color = "red") +
  labs(
    title = "Hubungan Kemantapan Jalan dengan Pertumbuhan PDRB",
    x = "Kemantapan Jalan (%)",
    y = "Pertumbuhan PDRB Tahunan (%)"
  ) +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

## siapa pencilan itu?

# Cek residuals untuk deteksi pencilan
model <- lm(`PDRB  Tahunan %` ~ `Panjang (KM)`, data = df)
plot(model)

model <- lm(`PDRB  Tahunan %` ~ `Mantap (%)`, data = df)
plot(model)

Regresi Linear

Data Cleaning

# 1. Load Library
library(readxl)
library(dplyr)
library(ggplot2)

# 2. Load Data
file_path <- "C:/Users/Hype AMD/OneDrive - apps.ipb.ac.id/A UP MY HARD SKILL/IPB/Matakuliaih/Semester 4/Visualisasi Data/Pertemuan 4/Data Projek Visdat_Kelompok 7.xlsx"
df <- read_excel(file_path, sheet = "Data Project")

# 3. Rename & Clean (Biar manggil kolomnya nggak pusing sama spasi)
df_final <- df %>%
  select(
    pdrb_growth = `PDRB  Tahunan %`,
    panjang = `Panjang (KM)`,
    mantap = `Mantap (%)`,
    penduduk = `Jumlah Penduduk (Ribu)`,
    jawa = `Jawa/Luar Jawa`
  ) %>%
  mutate(across(everything(), as.numeric)) %>%
  filter(!is.na(pdrb_growth))

Cek data yang sudah dibersihkan

df_final
## # A tibble: 37 × 5
##    pdrb_growth panjang mantap penduduk  jawa
##          <dbl>   <dbl>  <dbl>    <dbl> <dbl>
##  1        2.97   2112.   94.9    5626      0
##  2        4.53   2620.   95.0   15786.     0
##  3        3.37   1423.   90.6    5914.     0
##  4        4.79   1254.   92.9    6811.     0
##  5        6.94    430.  100      2214.     0
##  6        4.93   1319.   92.2    3768.     0
##  7        4.8     782.   91.6    2138      0
##  8        5.35   1581.   89.0    8928.     0
##  9        4.09    599.   99.8    1551.     0
## 10        5.28   1298.   92.0    9523.     0
## # ℹ 27 more rows
plot(model)

4. Run Regresi

# 4. Run Regresi
# Kita kontrol variabel Penduduk dan Dummy Jawa
model <- lm(pdrb_growth ~ log(panjang) + mantap + log(penduduk) + jawa, data = df_final)

5. Visualisasi Koefisien

# Cek hasil di console
summary(model)
## 
## Call:
## lm(formula = pdrb_growth ~ log(panjang) + mantap + log(penduduk) + 
##     jawa, data = df_final)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -26.0956  -0.9403  -0.3723   0.9961  27.6004 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)
## (Intercept)   -19.7793    22.6597  -0.873    0.389
## log(panjang)    2.2224     2.4474   0.908    0.371
## mantap          0.2075     0.2141   0.969    0.340
## log(penduduk)  -1.2497     1.6306  -0.766    0.449
## jawa            2.1329     5.6519   0.377    0.708
## 
## Residual standard error: 6.911 on 32 degrees of freedom
## Multiple R-squared:  0.04978,    Adjusted R-squared:  -0.069 
## F-statistic: 0.4191 on 4 and 32 DF,  p-value: 0.7936
visual_data <- data.frame(
  Variabel = c("Panjang Jalan", "Kemantapan Jalan"),
  Koefisien = c(
    as.numeric(coef(model)["log(panjang)"]), 
    as.numeric(coef(model)["mantap"])
  )
)

ggplot(visual_data, aes(x = Variabel, y = Koefisien, fill = Variabel)) +
  geom_col(width = 0.5) +
  geom_text(aes(label = round(Koefisien, 5)), vjust = -0.5, fontface = "bold") +
  scale_fill_manual(values = c("#E63946", "#1D3557")) +
  labs(
    title = "Perbandingan Dampak: Panjang vs Kemantapan Jalan",
    subtitle = "Koefisien Regresi setelah mengontrol Penduduk & Wilayah",
    y = "Besar Pengaruh (Beta)",
    x = ""
  ) +
  theme_minimal()