Pendahuluan

Di modul ini, kami membuat program simulasi untuk menentukan golongan Uang Kuliah Tunggal (UKT) menggunakan R. Program akan membaca data mahasiswa dari Excel, menghitung skor berdasarkan beberapa indikator ekonomi, menentukan golongan UKT, menampilkan ringkasan dan grafik, lalu menyimpan hasilnya ke file Excel.

Perlu diingat, program yang kami buat ini hanya untuk simulasi pembelajaran. Aturan skor dan nominal UKT di dalamnya kami tentukan sendiri, jadi hasilnya bukan keputusan resmi dari universitas.

Tujuan Praktikum

Setelah mengikuti modul ini, kami berharap pembaca bisa:

  1. Membaca data Excel ke R.
  2. Menggunakan mutate(), case_when(), coalesce(), dan operasi aritmetika untuk mengolah data.
  3. Menghitung skor dari beberapa indikator.
  4. Menentukan golongan UKT berdasarkan aturan simulasi.
  5. Membuat ringkasan dan grafik sederhana.
  6. Mengekspor hasil pengolahan ke file Excel.

1. Persiapan

Data 5 Mahasiswa yang Kami Gunakan

Kami menggunakan data contoh dari 5 mahasiswa dalam file Excel (.xlsx). File datanya bisa diunduh melalui tautan Google Drive ini.

Paket yang Kami Gunakan

Di program ini, kami menggunakan tiga paket R:

  • dplyr: memanipulasi dan meringkas data.
  • readxl: membaca file Excel.
  • writexl: menulis hasil ke file Excel.

Jika paket belum terpasang, jalankan kode berikut satu kali di Console RStudio:

install.packages(c("dplyr", "readxl", "writexl"))

Kami menambahkan eval=FALSE supaya kode instalasi ini tidak dijalankan setiap kali dokumen di-knit. Paket cukup diinstal satu kali jika memang belum ada di laptop.

library(dplyr)
library(readxl)
library(writexl)

Fungsi library() digunakan untuk memanggil paket supaya fungsi di dalamnya bisa kami pakai. Contohnya, read_excel() berasal dari paket readxl, sedangkan mutate(), case_when(), coalesce(), count(), arrange(), dan left_join() berasal dari dplyr.

Menyiapkan File Excel

Supaya kode bisa membaca data, kami menyiapkan file Excel bernama data_ukt_5_mahasiswa.xlsx dengan nama sheet Data. Simpan file itu di folder yang sama dengan file R Markdown ini.

Kalau file Excel masih ada di folder lain, pindahkan atau salin dulu ke folder proyek RStudio. Pilihan lainnya, ubah nilai file_input di kode menjadi alamat file yang sesuai. Di Windows, kami bisa menggunakan garis miring / atau garis miring terbalik ganda \\, misalnya:

file_input <- "C:/Users/Nama/Documents/data_ukt_5_mahasiswa.xlsx"

Jangan menulis alamat Windows dengan satu garis miring terbalik saja, karena karakter seperti \U bisa dibaca R sebagai kode khusus dan memunculkan error.

Struktur Kolom Excel

Nama kolom di Excel perlu sama dengan nama yang dipakai di kode. Berikut kolom-kolom yang digunakan program kami:

Nama kolom Isi
aset Nilai aset dalam rupiah
penghasilan_ayah Penghasilan ayah dalam rupiah
penghasilan_ibu Penghasilan ibu dalam rupiah
penghasilan_wali Penghasilan wali dalam rupiah
pbb Nilai PBB dalam rupiah sesuai periode yang dipakai dalam data
kendaraan_roda2 Pajak kendaraan roda dua dalam rupiah
kendaraan_roda4 Pajak kendaraan roda empat dalam rupiah
listrik Tagihan listrik dalam rupiah
air Tagihan air dalam rupiah
rekening_bulan1 Nilai rekening bulan pertama
rekening_bulan2 Nilai rekening bulan kedua
rekening_bulan3 Nilai rekening bulan ketiga
tanggungan Jumlah orang yang menjadi tanggungan

Kami juga bisa menambahkan kolom identitas seperti nama atau id_mahasiswa. Namun, kolom indikator di atas harus ada karena akan dipanggil oleh kode. Untuk data yang kosong, perlakuannya berbeda-beda tergantung bagian perhitungan, jadi sebaiknya cek lagi datanya sebelum program dijalankan.

2. Membaca data dari Excel

file_input <- "data_ukt_5_mahasiswa.xlsx"
df <- read_excel(file_input, sheet = "Data")

str(df)
## tibble [5 × 14] (S3: tbl_df/tbl/data.frame)
##  $ id_mahasiswa    : chr [1:5] "MHS001" "MHS002" "MHS003" "MHS004" ...
##  $ aset            : num [1:5] 5.0e+07 1.5e+08 3.5e+08 8.0e+08 2.0e+09
##  $ penghasilan_ibu : num [1:5] 1500000 2500000 3000000 5000000 8000000
##  $ penghasilan_ayah: num [1:5] 2.5e+06 4.5e+06 7.0e+06 1.2e+07 2.0e+07
##  $ penghasilan_wali: num [1:5] 0 0 0 0 0
##  $ pbb             : num [1:5] 300000 750000 1500000 3000000 6000000
##  $ kendaraan_roda2 : num [1:5] 1 2 2 3 2
##  $ kendaraan_roda4 : num [1:5] 0 0 1 1 2
##  $ tanggungan      : num [1:5] 5 4 3 2 2
##  $ listrik         : num [1:5] 150000 250000 400000 650000 1200000
##  $ air             : num [1:5] 50000 100000 150000 250000 400000
##  $ rekening_bulan1 : num [1:5] 8.0e+05 2.5e+06 6.0e+06 1.2e+07 3.0e+07
##  $ rekening_bulan2 : num [1:5] 1.0e+06 3.0e+06 5.5e+06 1.5e+07 3.5e+07
##  $ rekening_bulan3 : num [1:5] 9.0e+05 2.8e+06 6.5e+06 1.4e+07 3.2e+07
names(df)
##  [1] "id_mahasiswa"     "aset"             "penghasilan_ibu"  "penghasilan_ayah"
##  [5] "penghasilan_wali" "pbb"              "kendaraan_roda2"  "kendaraan_roda4" 
##  [9] "tanggungan"       "listrik"          "air"              "rekening_bulan1" 
## [13] "rekening_bulan2"  "rekening_bulan3"

Penjelasan kode:

Dua pemeriksaan terakhir ini berguna untuk memastikan data sudah terbaca dengan benar. Kalau nama kolom di Excel tidak sama dengan yang ada di kode, R bisa menampilkan error seperti object not found. Kami juga perlu memastikan angka uang terbaca sebagai angka, bukan teks.

3. Menghitung skor dan menentukan golongan UKT

Di bagian ini, kami mulai menghitung skor untuk setiap indikator. Fungsi mutate() dipakai untuk menambahkan kolom baru ke data, sedangkan %>% (pipe) meneruskan hasil dari satu proses ke proses berikutnya.

Kami menggunakan case_when() untuk menentukan skor berdasarkan kondisi tertentu. R akan memeriksa kondisi dari atas ke bawah dan memakai kondisi pertama yang cocok. Karena itu, urutan kondisi dan batas nilainya perlu diperhatikan.

df_hasil <- df %>%
  mutate(
    # A. Skor aset
    skor_aset = case_when(
      is.na(aset)       ~ NA_real_,
      aset >= 1500000000 ~ 11,
      aset <= 50000000  ~ 1,
      aset <= 100000000 ~ 2,
      aset <= 200000000 ~ 3,
      aset <= 350000000 ~ 4,
      TRUE              ~ 5
    ),

    # B. Skor penghasilan ayah, ibu, dan wali
    penghasilan_ayah_0 = coalesce(penghasilan_ayah, 0),
    penghasilan_ibu_0  = coalesce(penghasilan_ibu, 0),
    penghasilan_wali_0 = coalesce(penghasilan_wali, 0),

    total_penghasilan =
      penghasilan_ayah_0 +
      penghasilan_ibu_0 +
      penghasilan_wali_0,

    skor_penghasilan = case_when(
      total_penghasilan <= 2000000  ~ 1,
      total_penghasilan <= 3500000  ~ 2,
      total_penghasilan <= 5000000  ~ 3,
      total_penghasilan <= 7000000  ~ 4,
      total_penghasilan <= 9000000  ~ 5,
      total_penghasilan <= 12000000 ~ 6,
      total_penghasilan <= 15000000 ~ 7,
      total_penghasilan <= 20000000 ~ 8,
      total_penghasilan <= 25000000 ~ 9,
      TRUE                          ~ 10
    ),

    # C. Skor PBB
    skor_pbb = case_when(
      is.na(pbb)     ~ NA_real_,
      pbb <= 100000  ~ 1,
      pbb <= 250000  ~ 2,
      pbb <= 500000  ~ 3,
      pbb <= 1000000 ~ 4,
      pbb <= 1500000 ~ 5,
      pbb <= 2000000 ~ 6,
      pbb <= 3000000 ~ 7,
      pbb <= 4000000 ~ 8,
      pbb <= 5000000 ~ 9,
      TRUE           ~ 10
    ),

    # D. Skor pajak kendaraan
    r2_0 = coalesce(kendaraan_roda2, 0),
    r4_0 = coalesce(kendaraan_roda4, 0),
    total_pajak = r2_0 + r4_0,

    skor_kendaraan = case_when(
      is.na(kendaraan_roda2) & is.na(kendaraan_roda4) ~ 5,
      total_pajak < 1        ~ 1,
      total_pajak < 100000   ~ 2,
      total_pajak < 200000   ~ 3,
      total_pajak < 300000   ~ 4,
      total_pajak < 500000   ~ 5,
      total_pajak < 750000   ~ 6,
      total_pajak < 1000000  ~ 7,
      total_pajak < 1500000  ~ 8,
      total_pajak < 3000000  ~ 9,
      TRUE                   ~ 10
    ),

    # E. Skor listrik
    skor_listrik = case_when(
      is.na(listrik)    ~ NA_real_,
      listrik < 50000   ~ 1,
      listrik < 100000  ~ 2,
      listrik < 150000  ~ 3,
      listrik < 200000  ~ 4,
      listrik < 300000  ~ 5,
      listrik < 400000  ~ 6,
      listrik < 500000  ~ 7,
      listrik < 750000  ~ 8,
      listrik < 1000000 ~ 9,
      TRUE              ~ 10
    ),

    # F. Skor air
    skor_air = case_when(
      is.na(air)   ~ NA_real_,
      air == 0     ~ 3,
      air < 35000  ~ 1,
      air < 45000  ~ 2,
      air < 55000  ~ 3,
      air < 65000  ~ 4,
      air < 75000  ~ 5,
      air < 90000  ~ 6,
      air < 105000 ~ 7,
      air < 130000 ~ 8,
      air < 170000 ~ 9,
      TRUE         ~ 10
    ),

    # G. Rata-rata rekening tiga bulan dan skornya
    rata_rekening = if_else(
      is.na(rekening_bulan1) |
        is.na(rekening_bulan2) |
        is.na(rekening_bulan3),
      NA_real_,
      (rekening_bulan1 + rekening_bulan2 + rekening_bulan3) / 3
    ),

    skor_rekening = case_when(
      is.na(rata_rekening)      ~ NA_real_,
      rata_rekening <= 500000   ~ 1,
      rata_rekening <= 1000000  ~ 2,
      rata_rekening <= 2000000  ~ 3,
      rata_rekening <= 3500000  ~ 4,
      rata_rekening <= 5000000  ~ 5,
      rata_rekening <= 7500000  ~ 6,
      rata_rekening <= 10000000 ~ 7,
      rata_rekening <= 15000000 ~ 8,
      rata_rekening <= 25000000 ~ 9,
      TRUE                      ~ 10
    ),

    # H. Total skor mentah
    total_skor_mentah =
      pmin(skor_aset, 5) +
      skor_penghasilan +
      skor_pbb +
      skor_kendaraan +
      skor_listrik +
      skor_air +
      skor_rekening,

    # I. Pengurang tanggungan
    pengurang_tanggungan = coalesce(tanggungan, 0) * 2,
    skor_bersih = pmax(
      total_skor_mentah - pengurang_tanggungan,
      1
    ),

    # J. Penentuan golongan UKT
    golongan_ukt = case_when(
      is.na(aset)              ~ NA_real_,
      aset >= 1500000000       ~ 11,
      is.na(total_skor_mentah) ~ NA_real_,
      skor_bersih <= 12        ~ 1,
      skor_bersih <= 18        ~ 2,
      skor_bersih <= 24        ~ 3,
      skor_bersih <= 30        ~ 4,
      skor_bersih <= 36        ~ 5,
      skor_bersih <= 42        ~ 6,
      skor_bersih <= 48        ~ 7,
      skor_bersih <= 54        ~ 8,
      skor_bersih <= 60        ~ 9,
      TRUE                     ~ 10
    )
  )

A. Skor Aset

Di bagian ini, kami membagi nilai aset ke beberapa rentang menggunakan case_when(). Sebagai contoh, aset sampai Rp50.000.000 mendapat skor 1, sedangkan nilai aset yang lebih tinggi masuk ke rentang skor berikutnya.

Beberapa bagian yang perlu kami pahami:

  • is.na(aset) mengecek apakah nilai aset kosong.
  • NA_real_ digunakan untuk menandai nilai kosong yang bertipe numerik.
  • TRUE ~ 5 menjadi kondisi terakhir jika tidak ada kondisi sebelumnya yang cocok.
  • pmin(skor_aset, 5) membatasi skor aset yang ikut dijumlahkan, sehingga nilainya maksimal 5.

Catatan: dalam aturan simulasi yang kami gunakan, mahasiswa dengan aset sebesar Rp1.500.000.000 atau lebih langsung masuk golongan UKT 11. Karena itu, batas aset pada perhitungan skor dan penentuan golongan sudah dibuat konsisten.

B. Skor Penghasilan

Kami memakai coalesce(nilai, 0) untuk mengganti nilai penghasilan yang kosong (NA) menjadi nol. Setelah itu, penghasilan ayah, ibu, dan wali dijumlahkan menjadi total_penghasilan.

Skor penghasilan ditentukan dari total tersebut. Misalnya, total sampai Rp2.000.000 mendapat skor 1, sedangkan total di atas Rp25.000.000 mendapat skor 10.

Ada catatan penting: nilai kosong yang diganti menjadi nol tidak otomatis berarti penghasilan sebenarnya nol. Ini adalah asumsi yang kami pakai dalam simulasi, jadi data yang kosong tetap sebaiknya diperiksa.

C. Skor PBB

Pada bagian ini, kami memberi skor berdasarkan nilai PBB. Semakin tinggi rentang PBB, semakin tinggi skor yang diberikan dalam simulasi.

Berbeda dari data penghasilan, PBB yang kosong tidak kami ubah menjadi nol. Baris is.na(pbb) ~ NA_real_ membuat nilai kosong tetap kosong. Akibatnya, data yang belum lengkap bisa memengaruhi hasil perhitungan.

D. Skor Pajak Kendaraan

Variabel r2_0 dan r4_0 menyimpan nilai pajak kendaraan roda dua dan roda empat setelah nilai kosong diganti nol. Lalu, total_pajak menjumlahkan kedua nilai tersebut.

Kami juga membuat aturan khusus: jika kedua kolom kendaraan kosong, skornya langsung ditetapkan 5. Namun, jika hanya salah satu yang kosong, nilai kosong itu dihitung sebagai nol, lalu total pajak digunakan untuk menentukan skor.

E. Skor Listrik

Di sini, kami membagi tagihan listrik menjadi sepuluh tingkat skor. Operator < artinya “kurang dari”. Jadi, kalau nilainya tepat sama dengan batas tertentu, kondisi itu tidak terpenuhi dan R akan mengecek kondisi berikutnya. Contohnya, tagihan tepat Rp100.000 tidak masuk ke kondisi listrik < 100000.

Kalau nilai listrik kosong, skornya tetap NA.

F. Skor Air

Cara menghitung skor air mirip dengan skor listrik. Bedanya, kami menambahkan kondisi khusus air == 0 ~ 3, yang berarti tagihan air sebesar nol mendapat skor 3. Kondisi ini diletakkan lebih awal supaya diperiksa sebelum rentang nilai yang lain.

Kalau datanya kosong, skornya tetap NA, bukan otomatis menjadi nol.

G. Rata-rata Rekening Tiga Bulan

Kami menghitung rata_rekening dengan rumus:

Rata-rata = (Bulan 1 + Bulan 2 + Bulan 3) / 3

Sebelum menghitung, if_else() mengecek apakah ada nilai dari ketiga bulan yang kosong. Kalau minimal satu bulan kosong, rata-ratanya dibuat NA_real_. Kalau semua bulan terisi, R menghitung rata-ratanya, lalu nilai tersebut dipakai untuk menentukan skor_rekening.

H. Total Skor Mentah

Variabel total_skor_mentah menjumlahkan tujuh komponen berikut:

  1. Skor aset, dengan batas maksimum 5 pada penjumlahan.
  2. Skor penghasilan.
  3. Skor PBB.
  4. Skor kendaraan.
  5. Skor listrik.
  6. Skor air.
  7. Skor rekening.

Fungsi pmin(skor_aset, 5) mengambil nilai yang lebih kecil antara skor aset dan 5. Dengan cara ini, skor aset yang bernilai 11 tidak ikut membuat total skor menjadi terlalu besar. Jika salah satu komponen masih NA, total skor juga bisa menjadi NA.

I. Pengurang Tanggungan

Kami menggunakan coalesce(tanggungan, 0) untuk mengganti data tanggungan yang kosong menjadi nol, lalu mengalikannya dengan 2. Dalam aturan simulasi ini, setiap satu tanggungan mengurangi skor sebanyak dua poin.

Selanjutnya, pmax(total_skor_mentah - pengurang_tanggungan, 1) memastikan skor bersih tidak kurang dari 1, meskipun hasil pengurangannya lebih kecil dari itu.

J. Menentukan Golongan UKT

Bagian ini menentukan golongan akhir mahasiswa berdasarkan kondisi yang kami tulis di case_when():

  1. Kalau data aset kosong, golongan tidak ditentukan.
  2. Kalau aset sebesar Rp1.500.000.000 atau lebih, mahasiswa langsung masuk golongan 11.
  3. Kalau total skor mentah kosong, golongan juga tidak ditentukan.
  4. Selain kondisi tersebut, skor bersih digunakan untuk menentukan golongan 1–10.

Contohnya, skor bersih maksimal 12 masuk golongan 1, sedangkan skor 13–18 masuk golongan 2. Pola ini berlanjut sampai skor di atas 60 masuk golongan 10.

Urutan kondisi ini penting karena aturan aset sebesar Rp1.500.000.000 atau lebih diperiksa lebih dulu. Jadi, jika syarat itu terpenuhi, aturan golongan 11 langsung digunakan.

4. Membuat tabel nominal UKT

tabel_ukt <- data.frame(
  golongan_ukt = 1:11,
  nominal_ukt = c(
    500000,
    1000000,
    2000000,
    4000000,
    6000000,
    7500000,
    10000000,
    12500000,
    15000000,
    17500000,
    20000000
  )
)

tabel_ukt
##    golongan_ukt nominal_ukt
## 1             1      500000
## 2             2     1000000
## 3             3     2000000
## 4             4     4000000
## 5             5     6000000
## 6             6     7500000
## 7             7    10000000
## 8             8    12500000
## 9             9    15000000
## 10           10    17500000
## 11           11    20000000

Dengan data.frame(), kami membuat tabel yang berisi dua kolom:

Nominal UKT ini bisa kami ubah sesuai kebutuhan simulasi. Angka yang digunakan di modul ini bukan tarif resmi dari universitas mana pun.

5. Menggabungkan golongan dengan nominal UKT

df_hasil <- df_hasil %>%
  left_join(tabel_ukt, by = "golongan_ukt") %>%
  mutate(
    nominal_rupiah = if_else(
      is.na(nominal_ukt),
      NA_character_,
      paste0(
        "Rp",
        format(
          nominal_ukt,
          big.mark = ".",
          decimal.mark = ",",
          scientific = FALSE,
          trim = TRUE
        )
      )
    )
  )

Kami memakai left_join() untuk menggabungkan df_hasil dengan tabel_ukt berdasarkan kolom golongan_ukt. Hasilnya, setiap mahasiswa akan mendapat nominal UKT sesuai golongannya.

Setelah itu, kami membuat kolom nominal_rupiah supaya angka UKT lebih mudah dibaca:

Kolom nominal_ukt tetap berupa angka sehingga dapat digunakan untuk perhitungan; nominal_rupiah adalah versi teks untuk tampilan.

6. Menampilkan hasil dan ringkasan

print(df_hasil)
## # A tibble: 5 × 35
##   id_mahasiswa      aset penghasilan_ibu penghasilan_ayah penghasilan_wali   pbb
##   <chr>            <dbl>           <dbl>            <dbl>            <dbl> <dbl>
## 1 MHS001           5  e7         1500000          2500000                0 3  e5
## 2 MHS002           1.5e8         2500000          4500000                0 7.5e5
## 3 MHS003           3.5e8         3000000          7000000                0 1.5e6
## 4 MHS004           8  e8         5000000         12000000                0 3  e6
## 5 MHS005           2  e9         8000000         20000000                0 6  e6
## # ℹ 29 more variables: kendaraan_roda2 <dbl>, kendaraan_roda4 <dbl>,
## #   tanggungan <dbl>, listrik <dbl>, air <dbl>, rekening_bulan1 <dbl>,
## #   rekening_bulan2 <dbl>, rekening_bulan3 <dbl>, skor_aset <dbl>,
## #   penghasilan_ayah_0 <dbl>, penghasilan_ibu_0 <dbl>,
## #   penghasilan_wali_0 <dbl>, total_penghasilan <dbl>, skor_penghasilan <dbl>,
## #   skor_pbb <dbl>, r2_0 <dbl>, r4_0 <dbl>, total_pajak <dbl>,
## #   skor_kendaraan <dbl>, skor_listrik <dbl>, skor_air <dbl>, …
ringkasan_ukt <- df_hasil %>%
  count(golongan_ukt, name = "jumlah_mahasiswa") %>%
  arrange(golongan_ukt)

print(ringkasan_ukt)
## # A tibble: 5 × 2
##   golongan_ukt jumlah_mahasiswa
##          <dbl>            <int>
## 1            1                1
## 2            3                1
## 3            5                1
## 4            7                1
## 5           11                1

Di bagian ini, kami menampilkan hasil dan membuat ringkasannya:

Kalau ada golongan yang kosong (NA), nilainya juga bisa muncul di ringkasan. Ini membantu kami melihat apakah ada data yang belum bisa ditentukan golongannya.

7. Membuat grafik

ringkasan_valid <- ringkasan_ukt %>%
  filter(!is.na(golongan_ukt))

barplot(
  height = ringkasan_valid$jumlah_mahasiswa,
  names.arg = ringkasan_valid$golongan_ukt,
  col = "steelblue",
  xlab = "Golongan UKT",
  ylab = "Jumlah mahasiswa",
  main = "Sebaran Mahasiswa per Golongan UKT"
)

Sebelum membuat grafik, kami memakai filter(!is.na(golongan_ukt)) untuk mengeluarkan data yang golongannya kosong. Tanda ! berarti “bukan”, jadi !is.na(golongan_ukt) artinya golongan tersebut tidak kosong.

Pada fungsi barplot():

Grafik ini memudahkan kami melihat jumlah mahasiswa di tiap golongan. Karena data contoh hanya berisi lima mahasiswa, grafiknya tetap bisa dibuat, tetapi datanya belum cukup untuk mewakili kondisi mahasiswa secara umum.

8. Mengekspor hasil ke Excel

file_output <- "hasil_akhir_ukt.xlsx"

write_xlsx(
  list(
    Hasil_UKT = df_hasil,
    Ringkasan = ringkasan_ukt
  ),
  path = file_output
)

cat(
  "\nData berhasil diproses!\n",
  "File hasil: ",
  normalizePath(file_output, mustWork = FALSE),
  "\n"
)

Kami memberi opsi eval=FALSE pada kode ini supaya file Excel hasil tidak otomatis dibuat setiap kali modul di-knit. Kalau ingin menghasilkan file Excel, jalankan kode ini di script R biasa atau ubah opsi chunk menjadi eval=TRUE.

Kesimpulan

Dari program ini, kami menggabungkan beberapa langkah pengolahan data dalam satu alur, mulai dari membaca file Excel, menghitung skor setiap indikator, menentukan golongan UKT, menambahkan nominal UKT, membuat ringkasan dan grafik, sampai menyimpan hasil ke Excel.

Dengan membagi program menjadi beberapa bagian, kami jadi lebih mudah memahami alur kodenya dan mencari bagian yang perlu diperbaiki jika muncul error. Sekali lagi, hasil program ini hanya simulasi berdasarkan aturan yang kami tentukan, bukan penetapan UKT resmi dari universitas.