Analisis data iklim: manipulasi data kosong

Pada sesi ini akan diperlihatkan bagaimana analisis data iklim dilakukan jika terdapat data kosong atau NA (not available). Sebagai contoh akan digunakan data pengamatan dari Stasiun Meteorologi Siantan Pontianak untuk tahun 2014 saja. Data contoh tersebut dapat diunduh pada tautan berikut:siantan2014

Pertama, data dibaca dengan perintah dasar dengan fungsi read_excel dari package readxldan menyimpan data tersebut menjadi sebuahdataframe dengan nama siantan.

rm(list=ls())
library(readxl)
siantan=read_excel("siantan2014.xlsx")

header=TRUE digunakan untuk membaca judul pada tabel tersebut. Obyek siantan terdiri dari 361 observasi dengan 9 variables.

Gunakan fungsi summary untuk melihat koleksi data secara umum atau eksplorasi data termasuk keberadaan data kosong (NA). Selanjutnya fungsi str akan memberikan gambaran tipe data yang tersedia apakah tipe numeric, factor (string), ataukah integer. Format data tersebut harus dicek terlebih dahulu untuk kemudahan analisis lanjutan.

summary(siantan)
##      sta                 date                         Tmin          
##  Length:361         Min.   :2014-01-01 00:00:00   Length:361        
##  Class :character   1st Qu.:2014-04-01 00:00:00   Class :character  
##  Mode  :character   Median :2014-07-02 00:00:00   Mode  :character  
##                     Mean   :2014-07-01 10:22:16                     
##                     3rd Qu.:2014-09-30 00:00:00                     
##                     Max.   :2014-12-31 00:00:00                     
##      Tmax               Tav                 RH           
##  Length:361         Length:361         Length:361        
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
##                                                          
##      Rain           sunshine (hr)            yr      
##  Length:361         Length:361         Min.   :2014  
##  Class :character   Class :character   1st Qu.:2014  
##  Mode  :character   Mode  :character   Median :2014  
##                                        Mean   :2014  
##                                        3rd Qu.:2014  
##                                        Max.   :2014
siantan$Tav=as.numeric(siantan$Tav)
## Warning: NAs introduced by coercion
siantan$Tmin=as.numeric(siantan$Tmin)
## Warning: NAs introduced by coercion

Ternyata sebagian besar data pada obyek siantan masih dikenali sebagai character string. Oleh sebab itu perlu diubah ke format tipenumeric dengan fungsi as.numeric.

siantan$Tav=as.numeric(siantan$Tav)
siantan$Tmin=as.numeric(siantan$Tmin)
siantan$Tmax=as.numeric(siantan$Tmax)
## Warning: NAs introduced by coercion
siantan$RH=as.numeric(siantan$RH)
## Warning: NAs introduced by coercion
siantan$Rain=as.numeric(siantan$Rain)
## Warning: NAs introduced by coercion
siantan$`sunshine (hr)`=as.numeric(siantan$`sunshine (hr)`)
## Warning: NAs introduced by coercion
colnames(siantan)[8]="sunshine" #mengganti judul kolom ke-8
summary(siantan)
##      sta                 date                          Tmin      
##  Length:361         Min.   :2014-01-01 00:00:00   Min.   :19.90  
##  Class :character   1st Qu.:2014-04-01 00:00:00   1st Qu.:23.62  
##  Mode  :character   Median :2014-07-02 00:00:00   Median :24.20  
##                     Mean   :2014-07-01 10:22:16   Mean   :24.16  
##                     3rd Qu.:2014-09-30 00:00:00   3rd Qu.:24.80  
##                     Max.   :2014-12-31 00:00:00   Max.   :26.40  
##                                                   NA's   :11     
##       Tmax            Tav              RH             Rain       
##  Min.   :27.00   Min.   :24.20   Min.   :73.00   Min.   :   0.0  
##  1st Qu.:30.80   1st Qu.:26.50   1st Qu.:82.00   1st Qu.:   0.0  
##  Median :31.70   Median :27.10   Median :84.00   Median :   2.9  
##  Mean   :31.55   Mean   :27.13   Mean   :84.78   Mean   :1277.1  
##  3rd Qu.:32.40   3rd Qu.:27.80   3rd Qu.:87.00   3rd Qu.:  20.0  
##  Max.   :34.30   Max.   :29.30   Max.   :96.00   Max.   :8888.0  
##  NA's   :20      NA's   :5       NA's   :5       NA's   :95      
##     sunshine            yr      
##  Min.   : 0.000   Min.   :2014  
##  1st Qu.: 2.400   1st Qu.:2014  
##  Median : 5.200   Median :2014  
##  Mean   : 5.083   Mean   :2014  
##  3rd Qu.: 7.900   3rd Qu.:2014  
##  Max.   :10.300   Max.   :2014  
##  NA's   :23

Terdapat data yang hilang dari data tersebut yang diindikasikan dari jumlah NA. Jumlah NA bervariasi dari 11 (Tmin), 20 (Tmax), dan hingga 95 buah (Rain). Data yang hilang tersebut merupakan obyek yang akan kita bahas dan kelola dalam sesi ini. Obyek siantan tersebut juga kurang jika dilihat dari jumlah hari dalam tahun 2014 seharusnya 365, akan tetapi jumlah observasi yang ada hanya sebanyak 361 buah saja. Kedua masalah tersebut akan diselesaikan satu-persatu dalam uraian di bawah.

Pengecekan standar lanjutan yaitu cek tipe data dengan menggunakan fungsi str.

str(siantan)
## Classes 'tbl_df', 'tbl' and 'data.frame':    361 obs. of  9 variables:
##  $ sta     : chr  "SIANTAN" "SIANTAN" "SIANTAN" "SIANTAN" ...
##  $ date    : POSIXct, format: "2014-01-01" "2014-02-12" ...
##  $ Tmin    : num  24.1 24.5 23 25.2 24.7 24.2 22.5 NA 23.2 23.4 ...
##  $ Tmax    : num  31.2 31.8 32.1 31.6 31.5 31.2 31.7 31.2 31.6 32 ...
##  $ Tav     : num  26.3 27.3 26.6 27.5 26.3 27 26.4 26.7 26.7 27.1 ...
##  $ RH      : num  89 84 83 84 86 85 82 84 85 84 ...
##  $ Rain    : num  1.5 0 8888 NA NA ...
##  $ sunshine: num  1.2 9.3 1.3 8.3 NA 8 NA 9.2 0 8.7 ...
##  $ yr      : num  2014 2014 2014 2014 2014 ...

Data terlihat dalam format yang diinginkan, seperti Tmin dalam tipe numeric, date dalam format POSIXct. Data dalam siantan sekarang sudah siap untuk analisis lanjutan yaitu dengan menambahkan data tanggal yang hilang. Pertama, obyek baru dengan nama date1 yang terdiri dari data seri waktu selama tahun 2014 dibuat terlebih dahulu. Selanjutnya setiap variable akan dievaluasi dengan obyek date1 ini. Fungsi yang digunakan yaitu match yang akan mencocokkan data tanggal pada obyek date1 dengan tanggal pada siantan$date. Jika tidak sesuai maka urutan tanggal pada siantan$date akan mengikuti urutan pada date1 tanpa merubah data yang tersedia.

date1=seq(as.Date("2014-01-01"),length=365,by="day")
Tmin=with(siantan, Tmin[match(date1, as.Date(date))]) 
Tmax=with(siantan, Tmax[match(date1, as.Date(date))]) 
Tav=with(siantan, Tav[match(date1, as.Date(date))]) 
RH=with(siantan, RH[match(date1, as.Date(date))]) 
Rain=with(siantan, Rain[match(date1, as.Date(date))]) 
Sunshine=with(siantan, sunshine[match(date1, as.Date(date))]) 

Setelah semua data yang diperlukan berjumlah 365, data tersebut akan dikumpulkan lagi menjadi sebuah obyek baru dengan nama siantanyang akan menghapus obyek sebelumnya. Fungsi yang digunakan yaitu data.frame.

siantan=data.frame(date=date1,Tmin,Tmax,Tav,RH,Rain,Sunshine)
summary(siantan)
##       date                 Tmin            Tmax            Tav       
##  Min.   :2014-01-01   Min.   :19.90   Min.   :27.00   Min.   :24.20  
##  1st Qu.:2014-04-02   1st Qu.:23.62   1st Qu.:30.80   1st Qu.:26.50  
##  Median :2014-07-02   Median :24.20   Median :31.70   Median :27.10  
##  Mean   :2014-07-02   Mean   :24.16   Mean   :31.55   Mean   :27.13  
##  3rd Qu.:2014-10-01   3rd Qu.:24.80   3rd Qu.:32.40   3rd Qu.:27.80  
##  Max.   :2014-12-31   Max.   :26.40   Max.   :34.30   Max.   :29.30  
##                       NA's   :15      NA's   :24      NA's   :9      
##        RH             Rain           Sunshine     
##  Min.   :73.00   Min.   :   0.0   Min.   : 0.000  
##  1st Qu.:82.00   1st Qu.:   0.0   1st Qu.: 2.400  
##  Median :84.00   Median :   2.9   Median : 5.200  
##  Mean   :84.78   Mean   :1277.1   Mean   : 5.083  
##  3rd Qu.:87.00   3rd Qu.:  20.0   3rd Qu.: 7.900  
##  Max.   :96.00   Max.   :8888.0   Max.   :10.300  
##  NA's   :9       NA's   :99       NA's   :27

Sekarang data sudah berjumlah 365 yang urut mulai 1 Jan 2014.Gunakan fungsi summary untuk mengecek keberadaan NA. Untuk sekedar mengecek time-series data bisa menggunakan fungsi plot.

with(siantan,plot(Tmin~date,ylim=c(19,36),main="Stasiun Siantan Pontianak, 2014",type="p"))
with(siantan,points(Tmax~date,col="red"))
with(siantan,points(Tav~date,col="blue",type="l"))

Untuk kasus data suhu udara, kelembaban udara (RH), dan data penyinaran matahari, data kosong dapat diisi dengan menggunakan nilai tengah (median) atau juga dengan nilai rataan (mean), bisa juga dengan nilai terendah (min) tergantung dari pertimbangan yang digunakan. Dalam kasus sekarang ini, akan digunakan nilai median saja. Untuk pengisian data kosong harus mengenali posisi data kosong tersebut, fungsi yang digunakan yaitu is.na.

siantan$Tav[is.na(siantan$Tav)]=median(siantan$Tav,na.rm=TRUE)

Pada kode di atas, na.rm=TRUE digunakan untuk mengeluarkan nilai NA dari perhitungan, jika tidak dilakukan maka nilai mediansama dengan NA. LAngkah yang sama bisa dilakukan untuk Tmin dan Tmax.

siantan$Tmin[is.na(siantan$Tmin)]=median(siantan$Tmin,na.rm=TRUE)
siantan$RH[is.na(siantan$RH)]=median(siantan$RH,na.rm=TRUE)
siantan$Sunshine[is.na(siantan$Sunshine)]=median(siantan$Sunshine,na.rm=TRUE)

Untuk data Tmax yang kosong akan diisi dengan data Tav pada periode tanggal yang sama.

siantan$Tmax[is.na(siantan$Tmax)]=siantan$Tav[is.na(siantan$Tmax)]

Langkah terakhir yaitu untuk data hujan. Dalam laporan BMKG online data tak terukur terkadang ditulis denagn angka 8888. Kita akan mengganti data tsb dengan angka 0, dan data NA juga dengan angka 0 untuk kemudahan analisis. Data rerata atau median lebih cocok jika data yang dianalisis berupa data hujan bulanan atau dengan periode yang lebih panjang.

siantan$Rain[siantan$Rain>400]=0 #data lebih besar dari 400 dikosongkan
siantan$Rain[is.na(siantan$Rain)]=0
summary(siantan)
##       date                 Tmin            Tmax            Tav       
##  Min.   :2014-01-01   Min.   :19.90   Min.   :24.90   Min.   :24.20  
##  1st Qu.:2014-04-02   1st Qu.:23.70   1st Qu.:30.50   1st Qu.:26.50  
##  Median :2014-07-02   Median :24.20   Median :31.60   Median :27.10  
##  Mean   :2014-07-02   Mean   :24.16   Mean   :31.26   Mean   :27.13  
##  3rd Qu.:2014-10-01   3rd Qu.:24.70   3rd Qu.:32.30   3rd Qu.:27.80  
##  Max.   :2014-12-31   Max.   :26.40   Max.   :34.30   Max.   :29.30  
##        RH             Rain            Sunshine     
##  Min.   :73.00   Min.   :  0.000   Min.   : 0.000  
##  1st Qu.:82.00   1st Qu.:  0.000   1st Qu.: 2.600  
##  Median :84.00   Median :  0.000   Median : 5.200  
##  Mean   :84.76   Mean   :  5.398   Mean   : 5.092  
##  3rd Qu.:87.00   3rd Qu.:  3.400   3rd Qu.: 7.700  
##  Max.   :96.00   Max.   :103.400   Max.   :10.300

Sekarang data sudah terisi semua. Selamat mencoba!

Leave a comment