#Packages untuk pengolahan dataframe
library(dplyr)
library(tidyr)
library(lubridate)

#Packages untuk membuat visualisasi
library(ggcorrplot)
library(gplots)
library(ggplot2)
library(plotly)
library(foreign)

#Packages untuk melakukan analisis
library(plm)
library(lfe)
library(lmtest)
library(car)
library(tseries)
library(MLmetrics)

1 Data Preparation

1.1 Import & select Dataset

df <- read.csv("data_input/World_Happiness_Report.csv")

# 2. mengambil data wilayah asia tenggara dan membuang kolom regional indikator
df_used <- df %>% 
  filter(Regional.Indicator == "Commonwealth of Independent States") %>% 
  select(-Regional.Indicator)


head(df_used)

1.2 Pemeriksaan Balancing Data

table(df_used$Country.Name)
#> 
#>      Armenia   Azerbaijan      Belarus      Georgia   Kazakhstan   Kyrgyzstan 
#>           16           14           14           17           17           17 
#>      Moldova       Russia   Tajikistan Turkmenistan      Ukraine   Uzbekistan 
#>           17           17           16           10           17           16
is.pbalanced(df_used,index = c("Country.Name","Year"))
#> [1] FALSE

Dari hasil pemeriksaan frekuensi dan balancing data diatas terlihat bahwa:

  • data belum seimbang
  • negara yang memiliki informasi waktu Tidak lengkap adalah negara Armenia, Azerbaijan, Belarus, Tajikistan, Turkmenistan, dan Uzbekistan
  • negara dengan informasi waktu paling banyak adalah negara Georgia, Kazakhstan, Kyrgyzstan, Moldova, Russia, Ukraine dengan 17 waktu dan Armenia, Tajikistan, Uzbekistan dengan 16 waktu

untuk selanjutnya negara Azerbaijan, Belarus, Turkmenistan tidak akan disertakan dalam pemodelan

df_used <- df_used %>% filter(Country.Name %in% c("Georgia", "Kazakhstan", "Kyrgyzstan", "Moldova", "Russia", "Ukraine", "Armenia", "Tajikistan", "Uzbekistan")) 

1.2.1 Penyesuaian Struktur Data

1. Membuat Panel Data Frame

#membuat pdata.frame
df_used <- df_used %>% pdata.frame(index = c("Country.Name","Year"))

#memeriksa struktur data
glimpse(df_used)
#> Rows: 150
#> Columns: 12
#> $ Country.Name                      <fct> Armenia, Armenia, Armenia, Armenia, …
#> $ Year                              <fct> 2006, 2007, 2008, 2009, 2010, 2011, …
#> $ Life.Ladder                       <pseries> 4.289311, 4.881516, 4.651972, 4.…
#> $ Log.GDP.Per.Capita                <pseries> 9.020847, 9.156568, 9.230296, 9.…
#> $ Social.Support                    <pseries> 0.6818768, 0.7596443, 0.7094855,…
#> $ Healthy.Life.Expectancy.At.Birth  <pseries> 63.840, 64.080, 64.320, 64.560, …
#> $ Freedom.To.Make.Life.Choices      <pseries> 0.5201978, 0.6054108, 0.4621566,…
#> $ Generosity                        <pseries> -0.2322031, -0.2523521, -0.21645…
#> $ Perceptions.Of.Corruption         <pseries> 0.8495131, 0.8174449, 0.8760992,…
#> $ Positive.Affect                   <pseries> 0.4534175, 0.4537516, 0.4862302,…
#> $ Negative.Affect                   <pseries> 0.4694188, 0.4117174, 0.3848918,…
#> $ Confidence.In.National.Government <pseries> 0.3443375, 0.3876202, 0.4644471,…

2. Mememeriksa Dimensi Data

pdim(df_used)
#> Unbalanced Panel: n = 9, T = 16-17, N = 150

dari pemeriksaan dimensi data panel diatas dapat kita ketahui bahwa:

  • data masih belum seimbang
  • jumlah individu ada sebanyak 9 negara
  • jumlah index waktu ada minimal 16 dan maksimal 17
  • jumlah data keseluruhan ada sebanyak 150 observasi

1.2.2 Balancing Data

kita menggunakan metode balancing fill untuk mendapatkan informasi paling optimal yang akan tersimpan pada objek bernama balance1.

# Your Code Here
balance1 <- df_used %>% make.pbalanced(balance.type = "fill")

table(balance1$Country.Name)
#> 
#>    Armenia    Georgia Kazakhstan Kyrgyzstan    Moldova     Russia Tajikistan 
#>         17         17         17         17         17         17         17 
#>    Ukraine Uzbekistan 
#>         17         17
unique(balance1$Year)
#>  [1] 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020
#> [16] 2021 2022
#> 17 Levels: 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 ... 2022
# Periksa kembali keseimbangan data
is.pbalanced(balance1)
#> [1] TRUE
# pengecekan kembali dimensi data
pdim(balance1)
#> Balanced Panel: n = 9, T = 17, N = 153

1.3 Pemeriksaan Missing Value

sebelum kita periksa kelengkapan data kita perlu mengetahui berapa banyak informasi waktu yang ditambahkan dari tahapan sebelumnya

# jml missing data balance  - jml missing data unbalance
colSums(is.na(balance1)) - colSums(is.na(df_used))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 3                                 3 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 3                                 3 
#>      Freedom.To.Make.Life.Choices                        Generosity 
#>                                 3                                 3 
#>         Perceptions.Of.Corruption                   Positive.Affect 
#>                                 3                                 3 
#>                   Negative.Affect Confidence.In.National.Government 
#>                                 3                                 3

berdasarkan pemeriksaan diatas dapat diketahui bahwa dari data df_used ketika dilakukan balancing terjadi penambahan 3 baris nilai NA untuk setiap kolom.

Tahap selanjutnya adalah memeriksa kelengkapan data hasil balancing

colSums(is.na(balance1))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 3                                 3 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 3                                 3 
#>      Freedom.To.Make.Life.Choices                        Generosity 
#>                                 9                                 3 
#>         Perceptions.Of.Corruption                   Positive.Affect 
#>                                 5                                 3 
#>                   Negative.Affect Confidence.In.National.Government 
#>                                 3                                22

Berdasarkan hasil pemeriksaan diatas kita melihat secara keseluruhan terdapat cukup banyak kolom yang memiliki nilai missing

  • Semua kolom kecuali nama negara memiliki 3 data yang hilang dan kolom Freedom.To.Make.Life.Choices memiliki 9 dari total data yang hilang
  • maka Freedom.To.Make.Life.Choices tidak akan disertakan dalam pembuatan model
# drop kolom yang tidak digunakan
balance1 <- balance1 %>% select(-Freedom.To.Make.Life.Choices)

Untuk pemeriksaan dan melakukan pengisian nilai yang hilang maka akan dilakukan dengan cara interpolasi secara terpisah untuk setiap negara.

1. Armenia

# periksa nilai missing per negara
arm <- balance1 %>% filter(Country.Name == "Armenia")

colSums(is.na(arm))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 1                                 1 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 1                                 1 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 1                                 1 
#>                   Positive.Affect                   Negative.Affect 
#>                                 1                                 1 
#> Confidence.In.National.Government 
#>                                 2

insight: terdapat missing untuk kolom

  • Social.Support
  • Positive.Affect
  • Healthy.Life.Expectancy.At.Birth
  • Life.Ladder
  • Generosity
  • Log.GDP.Per.Capita
  • Perceptions.Of.Corruption
  • Negative.Affect

untuk mengisi nilai yang hilang dengan nilai rata-rata dari nilai yang dekat dengan nilai missing menggunakan fungsi na.fill() dengan fill = "extend"

# mengisi nilai missing 
arm <- arm %>% mutate(
  Social.Support = na.fill(Social.Support, fill = "extend"),
  Healthy.Life.Expectancy.At.Birth = na.fill(Healthy.Life.Expectancy.At.Birth, fill = "extend"),
  Positive.Affect = na.fill(Positive.Affect, fill = "extend"),
  Life.Ladder = na.fill(Life.Ladder, fill = "extend"),
  Generosity = na.fill(Generosity, fill = "extend"),
  Log.GDP.Per.Capita = na.fill(Log.GDP.Per.Capita, fill = "extend"),
  Perceptions.Of.Corruption = na.fill(Perceptions.Of.Corruption, fill = "extend"),
  Negative.Affect = na.fill(Negative.Affect, fill = "extend")
  )
  
anyNA(arm)
#> [1] TRUE

2. Georgia

# periksa nilai missing per negara
geo <- balance1 %>% filter(Country.Name == "Georgia")

colSums(is.na(geo))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 0                                 0 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 0                                 0 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 0                                 0 
#>                   Positive.Affect                   Negative.Affect 
#>                                 0                                 0 
#> Confidence.In.National.Government 
#>                                 1

insight: negara Georgia tidak terdapat nilai yang missing

3. Kazakhstan

# periksa nilai missing per negara
kaz <- balance1 %>% filter(Country.Name == "Kazakhstan")

colSums(is.na(kaz))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 0                                 0 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 0                                 0 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 0                                 0 
#>                   Positive.Affect                   Negative.Affect 
#>                                 0                                 0 
#> Confidence.In.National.Government 
#>                                 1

insight: negara Kazakhstan tidak terdapat nilai yang missing

4. Kyrgyzstan

# periksa nilai missing per negara
kyr <- balance1 %>% filter(Country.Name == "Kyrgyzstan")

colSums(is.na(kyr))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 0                                 0 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 0                                 0 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 0                                 0 
#>                   Positive.Affect                   Negative.Affect 
#>                                 0                                 0 
#> Confidence.In.National.Government 
#>                                 1

insight: negara Kyrgyzstan tidak terdapat nilai yang missing

5. Moldova

# periksa nilai missing per negara
mol <- balance1 %>% filter(Country.Name == "Moldova")

colSums(is.na(mol))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 0                                 0 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 0                                 0 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 0                                 0 
#>                   Positive.Affect                   Negative.Affect 
#>                                 0                                 0 
#> Confidence.In.National.Government 
#>                                 1

insight: negara Moldova tidak terdapat nilai yang missing

6. Russia

# periksa nilai missing per negara
rus <- balance1 %>% filter(Country.Name == "Russia")

colSums(is.na(rus))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 0                                 0 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 0                                 0 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 0                                 0 
#>                   Positive.Affect                   Negative.Affect 
#>                                 0                                 0 
#> Confidence.In.National.Government 
#>                                 1

insight: negara Rusia tidak terdapat nilai yang missing

7. Tajikistan

# periksa nilai missing per negara
taj <- balance1 %>% filter(Country.Name == "Tajikistan")

colSums(is.na(taj))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 1                                 1 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 1                                 1 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 1                                 1 
#>                   Positive.Affect                   Negative.Affect 
#>                                 1                                 1 
#> Confidence.In.National.Government 
#>                                 5

insight: terdapat missing untuk kolom

  • Social.Support
  • Positive.Affect
  • Healthy.Life.Expectancy.At.Birth
  • Life.Ladder
  • Generosity
  • Log.GDP.Per.Capita
  • Perceptions.Of.Corruption
  • Negative.Affect

untuk mengisi nilai yang hilang dengan nilai rata-rata dari nilai yang dekat dengan nilai missing menggunakan fungsi na.fill() dengan fill = "extend"

# mengisi nilai missing 
taj <- taj %>% mutate(
  Social.Support = na.fill(Social.Support, fill = "extend"),
  Healthy.Life.Expectancy.At.Birth = na.fill(Healthy.Life.Expectancy.At.Birth, fill = "extend"),
  Positive.Affect = na.fill(Positive.Affect, fill = "extend"),
  Life.Ladder = na.fill(Life.Ladder, fill = "extend"),
  Generosity = na.fill(Generosity, fill = "extend"),
  Log.GDP.Per.Capita = na.fill(Log.GDP.Per.Capita, fill = "extend"),
  Perceptions.Of.Corruption = na.fill(Perceptions.Of.Corruption, fill = "extend"),
  Negative.Affect = na.fill(Negative.Affect, fill = "extend")
  )
  
anyNA(taj)
#> [1] TRUE

8. Ukraine

# periksa nilai missing per negara
ukr <- balance1 %>% filter(Country.Name == "Ukraine")

colSums(is.na(ukr))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 0                                 0 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 0                                 0 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 0                                 0 
#>                   Positive.Affect                   Negative.Affect 
#>                                 0                                 0 
#> Confidence.In.National.Government 
#>                                 1

insight: negara Ukraine tidak terdapat nilai yang missing

9. Uzbekistan

# periksa nilai missing per negara
uzb <- balance1 %>% filter(Country.Name == "Uzbekistan")

colSums(is.na(uzb))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 1                                 1 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 1                                 1 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 1                                 3 
#>                   Positive.Affect                   Negative.Affect 
#>                                 1                                 1 
#> Confidence.In.National.Government 
#>                                 9

insight: terdapat missing untuk kolom

  • Social.Support
  • Positive.Affect
  • Healthy.Life.Expectancy.At.Birth
  • Life.Ladder
  • Generosity
  • Log.GDP.Per.Capita
  • Perceptions.Of.Corruption
  • Negative.Affect

untuk mengisi nilai yang hilang dengan nilai rata-rata dari nilai yang dekat dengan nilai missing menggunakan fungsi na.fill() dengan fill = "extend"

# mengisi nilai missing 
uzb <- uzb %>% mutate(
  Social.Support = na.fill(Social.Support, fill = "extend"),
  Healthy.Life.Expectancy.At.Birth = na.fill(Healthy.Life.Expectancy.At.Birth, fill = "extend"),
  Positive.Affect = na.fill(Positive.Affect, fill = "extend"),
  Life.Ladder = na.fill(Life.Ladder, fill = "extend"),
  Generosity = na.fill(Generosity, fill = "extend"),
  Log.GDP.Per.Capita = na.fill(Log.GDP.Per.Capita, fill = "extend"),
  Perceptions.Of.Corruption = na.fill(Perceptions.Of.Corruption, fill = "extend"),
  Negative.Affect = na.fill(Negative.Affect, fill = "extend")
  )
  
anyNA(uzb)
#> [1] TRUE

Setelah semua negara tidak lagi terdapat nilai yang missing, selanjutnya kita akan gabungkan kembali dan akan disimpan pada objek dengan nama balanced2

# Your Code Here
balanced2 <- bind_rows(arm, geo, kaz, kyr, mol, rus, taj, ukr, uzb) 

Pemeriksaan Kembali keseimbangan data

# Your Code Here
pdim(balanced2)
#> Balanced Panel: n = 9, T = 17, N = 153

Pemeriksaan Kembali kelengkapan data

# Your Code Here
colSums(is.na(balanced2))
#>                      Country.Name                              Year 
#>                                 0                                 0 
#>                       Life.Ladder                Log.GDP.Per.Capita 
#>                                 0                                 0 
#>                    Social.Support  Healthy.Life.Expectancy.At.Birth 
#>                                 0                                 0 
#>                        Generosity         Perceptions.Of.Corruption 
#>                                 0                                 0 
#>                   Positive.Affect                   Negative.Affect 
#>                                 0                                 0 
#> Confidence.In.National.Government 
#>                                22

Data telah siap untuk digunakan pada tahapan selanjutnya

1.4 Exploratory Data Analysis

1.4.1 Ringkasan Data

summary(balanced2)
#>      Country.Name      Year     Life.Ladder    Log.GDP.Per.Capita
#>  Armenia   :17    2006   : 9   Min.   :3.675   Min.   : 7.591    
#>  Georgia   :17    2007   : 9   1st Qu.:4.702   1st Qu.: 8.554    
#>  Kazakhstan:17    2008   : 9   Median :5.287   Median : 9.300    
#>  Kyrgyzstan:17    2009   : 9   Mean   :5.207   Mean   : 9.176    
#>  Moldova   :17    2010   : 9   3rd Qu.:5.719   3rd Qu.: 9.569    
#>  Russia    :17    2011   : 9   Max.   :6.421   Max.   :10.239    
#>  (Other)   :51    (Other):99                                     
#>  Social.Support   Healthy.Life.Expectancy.At.Birth   Generosity       
#>  Min.   :0.5029   Min.   :58.00                    Min.   :-0.309966  
#>  1st Qu.:0.7620   1st Qu.:61.58                    1st Qu.:-0.223903  
#>  Median :0.8617   Median :63.40                    Median :-0.095501  
#>  Mean   :0.8233   Mean   :63.16                    Mean   :-0.091610  
#>  3rd Qu.:0.8981   3rd Qu.:64.58                    3rd Qu.:-0.005324  
#>  Max.   :0.9682   Max.   :67.92                    Max.   : 0.427582  
#>                                                                       
#>  Perceptions.Of.Corruption Positive.Affect  Negative.Affect 
#>  Min.   :0.3209            Min.   :0.3510   Min.   :0.1035  
#>  1st Qu.:0.6608            1st Qu.:0.5310   1st Qu.:0.1696  
#>  Median :0.8577            Median :0.5735   Median :0.2077  
#>  Mean   :0.7793            Mean   :0.5767   Mean   :0.2321  
#>  3rd Qu.:0.9241            3rd Qu.:0.6333   3rd Qu.:0.2606  
#>  Max.   :0.9695            Max.   :0.7782   Max.   :0.5495  
#>                                                             
#>  Confidence.In.National.Government
#>  Min.   :0.07879                  
#>  1st Qu.:0.27805                  
#>  Median :0.46254                  
#>  Mean   :0.48905                  
#>  3rd Qu.:0.66642                  
#>  Max.   :0.97805                  
#>  NA's   :22

Berdasarkan ringkasan diatas dapat kita ketahui beberapa hal berikut:

  • tingkat kebahagiaan tertinggi di beberapa negara di Eropa Timur adalah 6.421
  • tingkat kebahagiaan terrendah di beberapa negara di Eropa Timur adalah 3.675

1.4.2 Hubungan Antar Variabel

Untuk mengetahui seberapa besar tingkat hubungan antar variabel prediktor terhadap variabel target, dapat kita gunakan fungsi ggcorrplot.

# Your Code Here
balanced2 %>% select(-Country.Name, -Year) %>% cor() %>% ggcorrplot(type = "lower", lab = TRUE)

Berdasarkan hasil plot heatmap diatas, dapat diketahui bahwa

  • Variabel yang memiliki Hubungan Kuat terhadap Life.Ladder adalah:
    • Social.Support
    • Positive Affect
  • Tidak Terdapat indikasi multikolinieritas antar variabel

1.4.3 Explorasi Socio demografi

Untuk melihat lebih dalam informasi dari data yang kita miliki dapat kita lakukan dengan menggunakan fungsi coplot()

1. Life.ladder

# Your Code Here
coplot(Life.Ladder ~ Year|Country.Name,
       type = "b",
       data = balanced2,
       rows = 1,
       col = "red")

Berdasarkan Line plot diatas dapat kita ketahui bahwa :

  • secara keseluruhan warga negara yang merasa paling bahagia di beberapa negara di eropa timur adalah warga negara uzbekistan
  • secara keseluruhan warga negara yang merasa tingkat kebahagiaan di beberapa negara di eropa timur paling rendah adalah warga negara Georgia

2. Social.Support

# Your Code Here
coplot(Social.Support ~ Year|Country.Name,
       type = "b",
       data = balanced2,
       rows = 1,
       col = "red")

Berdasarkan plot diatas dapat kita ketahui bahwa :

  • secara keseluruhan warga negara di beberapa negara di eropa timur dengan social support paling tinggi adalah warga negara Kazakhstan dan Uzbekistan
  • secara keseluruhan warga negara di beberapa negara di eropa timur dengan social support paling rendah adalah warga negara Georgia

3. Log.GDP.Per.Capita

# Your Code Here
coplot(Positive.Affect ~ Year|Country.Name,
       type = "b",
       data = balanced2,
       rows = 1,
       col = "red")

Berdasarkan plot diatas dapat kita ketahui bahwa :

  • secara keseluruhan warga negara di beberapa negara di eropa timur dengan Positive affect paling tinggi adalah warga negara Uzbekistan
  • secara keseluruhan warga negara di beberapa negara di eropa timur dengan Positive affect paling rendah adalah warga negara Georgia

1.4.4 Heterogenitas Life.Ledder

Untuk melihat heterogenitas antar individu dan waktu kita dapat menggunakan fungsi plotmeans() dari package gplots

1. Heterogenitas antar negara

plotmeans( Life.Ladder ~ Country.Name, data = balanced2, main="Heterogenitas Life.Ladder antar Negara")

Insight : Berdasarkan hasil visual diatas terlihat bahwa data antar negara cukup heterogen

2. Heterogenitas antar Waktu

plotmeans(Life.Ladder ~ Year, data = balanced2, main="Heterogenitas Life.Ladder antar Tahun")

Insight : Berdasarkan hasil visual diatas terlihat bahwa data antar tahun cukup heterogen


1.5 Pemodelan

1.5.1 Cross-Validation

Tahapan cross validation dilakukan sebelum pembuatan model, data akan dibagi menjadi data train dan data test. Dikarenakan data panel memiliki informasi keterangan waktu maka pembagian data tidak boleh diambil secara acak melainkan dibagi dengan cara dipisah secara berurutan.

  • Data Train akan menggunakan data yang terlampau
  • Data Test akan menggunakan data yang terbaru

untuk melakukannya kita bisa menggunakan bantuan fungsi filter()

#membuat data train
ladder_train <- balanced2 %>% filter(Year != 2022) 
  
#membuat data test
ladder_test <- balanced2 %>% filter(Year == 2022)

setelah dilakukan cross validation kita perlu memastikan kembali bahwa data train sudah balance dengan melakukan balancing

ladder_train <- ladder_train %>% 
  droplevels() %>%    # menghapus informasi waktu yang diambil sebagai data test (tahun 2022)
  make.pbalanced()    # melakukan balancing kembali

is.pbalanced(ladder_train)
#> [1] TRUE

1.5.2 Penentuan Model Estimasi

1.5.2.1 Pembuatan Model

Untuk setiap pembuatan model akan digunakan fungsi plm() dari package plm dimana :

  • Variabel target : Life.Ladder
  • Variabel prediktor :
    • Social.Support
    • Positive Affect
    • Negative.Affect
    • Generosity

Model Gabungan (CEM)

membuat Common effect model dan disimpan kedalam objek cem

# membuat Common effect model 
cem <- plm(Life.Ladder ~ Social.Support + Positive.Affect + Negative.Affect + Generosity, 
           data = ladder_train,
           index = c("Country.Name","Year"),
           model = "pooling")

Model Pengaruh Tetap (FEM)

membuat Fixed effect model dan disimpan kedalam objek fem

# membuat fixed effect model 
fem <- plm(Life.Ladder ~  Social.Support + Positive.Affect + Negative.Affect + Generosity, 
           data = ladder_train,
           index = c("Country.Name","Year"),
           model = "within")

Uji Chow

Uji chow dilakukan untuk memilih model terbaik antara model gabungan (cem) dengan model fixed effec (fem). untuk melakukan uji Chow dapat menggunakan fungsi pooltest(model_cem, model_fem)

Hipotesis yang diuji adalah sebagai berikut:

  • H0 : Model gabungan
  • H1 : Model pengaruh tetap

H0 ditolak jika P-value < α. Nilai α yang digunakan sebesar 5%.

# your code here
pooltest(cem,fem)
#> 
#>  F statistic
#> 
#> data:  Life.Ladder ~ Social.Support + Positive.Affect + Negative.Affect +  ...
#> F = 8.419, df1 = 8, df2 = 131, p-value = 0.000000003469
#> alternative hypothesis: unstability

Berdasarkan hasil uji chow diatas, kita peroleh nilai p-value < α. artinya Model terbaik untuk digunakan pada data World Happines dengan region eropa timur adalah fixed effect model.


Model Pengaruh Acak (REM)

membuat random effect model dan disimpan kedalam objek rem

# membuat random effect model 
rem <- plm(Life.Ladder ~ Social.Support + Positive.Affect + Negative.Affect + Generosity,
           data = ladder_train,
           index = c("Country.Name","Year"),
           model = "random")

Uji Hausman

Untuk melakukan uji Hausman di R dapat menggunakan fungsi phtest(model_rem, model_fem), dengan Hipotesis yang diuji adalah sebagai berikut.

  • H0 : Model pengaruh acak
  • H1 : Model pengaruh tetap

Keputusan tolak H0 (model pengaruh tetap terpilih) apabila nilai p-value < α.

phtest(rem,fem)
#> 
#>  Hausman Test
#> 
#> data:  Life.Ladder ~ Social.Support + Positive.Affect + Negative.Affect +  ...
#> chisq = 4.4661, df = 4, p-value = 0.3466
#> alternative hypothesis: one model is inconsistent

Berdasarkan hasil uji hausman diatas, kita peroleh nilai p-value > α. artinya Model terbaik untuk digunakan pada data World Happines adalah random effect model. Dikarenakan model rem adalah model terbaik maka perlu dilakukan uji efek lanjutan.

Lagrange Multiplier

efek individu dan waktu

Hipotesis yang diuji adalah sebagai berikut. H0 : Tidak ada pengaruh individu dan waktu H1 : Ada pengaruh individu dan waktu Tolak H0 jika P-value < α. Nilai α yang digunakan sebesar 5%.

plmtest(rem,type = "bp", effect="twoways" )
#> 
#>  Lagrange Multiplier Test - two-ways effects (Breusch-Pagan)
#> 
#> data:  Life.Ladder ~ Social.Support + Positive.Affect + Negative.Affect +  ...
#> chisq = 65.427, df = 2, p-value = 0.000000000000006204
#> alternative hypothesis: significant effects

efek individu

Hipotesis yang diuji adalah sebagai berikut. H0 : Tidak ada pengaruh individu H1 : Ada pengaruh individu Tolak H0 jika P-value < α. Nilai α yang digunakan sebesar 5%.

plmtest(rem,type = "bp", effect="individual")
#> 
#>  Lagrange Multiplier Test - (Breusch-Pagan)
#> 
#> data:  Life.Ladder ~ Social.Support + Positive.Affect + Negative.Affect +  ...
#> chisq = 65.287, df = 1, p-value = 0.0000000000000006474
#> alternative hypothesis: significant effects

efek waktu

Hipotesis yang diuji adalah sebagai berikut. H0 : Tidak ada pengaruh waktu H1 : Ada pengaruh waktu Tolak H0 jika P-value < α. Nilai α yang digunakan sebesar 5%.

plmtest(rem, type = "bp", effect="time" )
#> 
#>  Lagrange Multiplier Test - time effects (Breusch-Pagan)
#> 
#> data:  Life.Ladder ~ Social.Support + Positive.Affect + Negative.Affect +  ...
#> chisq = 0.13978, df = 1, p-value = 0.7085
#> alternative hypothesis: significant effects

Berdasarkan hasil uji pengaruh di atas, model memiliki pengaruh waktu, maka model yang paling tepat digunakan adalah model pengaruh acak: pengaruh waktu pada taraf nyata 5%.


1.5.2.2 Pengujian Asumsi

Normalitas

Hipotesis yang diuji adalah sebagai berikut.

  • H0 : Sisaan menyebar normal
  • H1 : Sisaan tidak menyebar normal

H0 ditolak jika P-value < α. Nilai α yang digunakan sebesar 5%.

# your code here
rem$residuals %>% shapiro.test()
#> 
#>  Shapiro-Wilk normality test
#> 
#> data:  .
#> W = 0.99354, p-value = 0.7654

Berdasarkan hasil pengujian normalitas sisaan diperoleh nilai p-value > 0.05, artinya sisaan menyebar secara normal.

Homogenitas

Hipotesis yang diuji adalah sebagai berikut.

  • H0 : Sisaan memiliki ragam homogen
  • H1 : Sisaan tidak memiliki ragam homogen

H0 ditolak jika P-value < α. Nilai α yang digunakan sebesar 5%.

# your code here
rem %>% bptest()
#> 
#>  studentized Breusch-Pagan test
#> 
#> data:  .
#> BP = 7.7704, df = 4, p-value = 0.1004

Berdasarkan hasil pengujian homogenitas diperoleh nilai p-value > 0.05, artinya sisaan memiliki ragam yang homogen.

Autokorelasi

Hipotesis yang diuji adalah sebagai berikut.

  • H0 : tidak terjadi autokorelasi pada sisaan
  • H1 : terjadi autokorelasi pada sisaan

H0 ditolak jika P-value < α. Nilai α yang digunakan sebesar 5%.

# your code here
rem$residuals %>% Box.test(type = "Ljung-Box")
#> 
#>  Box-Ljung test
#> 
#> data:  .
#> X-squared = 28.971, df = 1, p-value = 0.00000007348

Berdasarkan hasil pengujian autokorelasi diperoleh nilai p-value < 0.05, artinya terjadi permasalahan autokorelasi antar sisaan.


1.5.3 Interpretasi Model

1. Koefisien

# your code here
summary(rem)
#> Oneway (individual) effect Random Effect Model 
#>    (Swamy-Arora's transformation)
#> 
#> Call:
#> plm(formula = Life.Ladder ~ Social.Support + Positive.Affect + 
#>     Negative.Affect + Generosity, data = ladder_train, model = "random", 
#>     index = c("Country.Name", "Year"))
#> 
#> Balanced Panel: n = 9, T = 16, N = 144
#> 
#> Effects:
#>                   var std.dev share
#> idiosyncratic 0.10656 0.32644 0.632
#> individual    0.06199 0.24899 0.368
#> theta: 0.6885
#> 
#> Residuals:
#>      Min.   1st Qu.    Median   3rd Qu.      Max. 
#> -0.957060 -0.217006  0.032725  0.234680  0.951192 
#> 
#> Coefficients:
#>                  Estimate Std. Error z-value      Pr(>|z|)    
#> (Intercept)     1.2661150  0.5281518  2.3973      0.016518 *  
#> Social.Support  1.7009762  0.6311196  2.6952      0.007035 ** 
#> Positive.Affect 4.0725349  0.7295360  5.5824 0.00000002373 ***
#> Negative.Affect 0.7917788  0.6832640  1.1588      0.246530    
#> Generosity      0.0069323  0.2879220  0.0241      0.980791    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Total Sum of Squares:    25.09
#> Residual Sum of Squares: 14.844
#> R-Squared:      0.4084
#> Adj. R-Squared: 0.39137
#> Chisq: 95.9543 on 4 DF, p-value: < 0.000000000000000222
  • variabel yang signifikan mempengaruhi tingkat kebahagiaan masyarakat di suatu negara adalah :
    • Positive.Affect
    • Social.Support
  • dari kedua variabel yang signifikan, Positive.Affect memberikan pengaruh yang lebih besar dibandingkan dengan Social.Support
  • tingkat kebahagian masyarakat di suatu negara akan bertambah sebesar 4.0725349 untuk setiap kenaikan 1 satuan Positive.Affect, dengan catatan variabel lainnya bernilai tetap
  • tingkat kebahagian masyarakat di suatu negara akan bertambah sebesar 1.7009762 untuk setiap kenaikan 1 satuan Social.Support, dengan catatan variabel lainnya bernilai tetap
  • tingkat kebahagian masyarakat di suatu negara akan bertambah sebesar 0.7917788 untuk setiap kenaikan 1 satuan Negative.Affect, dengan catatan variabel lainnya bernilai tetap
  • tingkat kebahagian masyarakat di suatu negara akan bertambah sebesar 0.0069323 untuk setiap kenaikan 1 satuan Generosity, dengan catatan variabel lainnya bernilai tetap

2. Mengekstrak informasi Efek dari model

Untuk mengekstrak informasi efek dari model REM kita dapat menggunakan fungsi ranef(model rem),

# your code here
ranef(rem)
#>     Armenia     Georgia  Kazakhstan  Kyrgyzstan     Moldova      Russia 
#> -0.23424229  0.04894519  0.27853969 -0.14746188  0.34844102  0.17207771 
#>  Tajikistan     Ukraine  Uzbekistan 
#> -0.13194008 -0.32096564 -0.01339373

Interpretasi:

  • tingkat kebahagiaan masyarakat di negara Armenia adalah sebesar -0.23424229 apabila tidak terdapat informasi lainnya
  • tingkat kebahagiaan masyarakat di negara Georgia adalah sebesar 0.04894519 apabila tidak terdapat informasi lainnya
  • tingkat kebahagiaan masyarakat di negara Kazakhstan adalah sebesar 0.27853969 apabila tidak terdapat informasi lainnya
  • tingkat kebahagiaan masyarakat di negara Kyrgyzstan adalah sebesar -0.14746188 apabila tidak terdapat informasi lainnya
  • tingkat kebahagiaan masyarakat di negara Moldova adalah sebesar 0.34844102 apabila tidak terdapat informasi lainnya
  • tingkat kebahagiaan masyarakat di negara Russia adalah sebesar 0.17207771 apabila tidak terdapat informasi lainnya
  • tingkat kebahagiaan masyarakat di negara Tajikistan adalah sebesar -0.13194008 apabila tidak terdapat informasi lainnya
  • tingkat kebahagiaan masyarakat di negara Ukraine adalah sebesar -0.32096564 apabila tidak terdapat informasi lainnya
  • tingkat kebahagiaan masyarakat di negara Uzbekistan adalah sebesar -0.01339373 apabila tidak terdapat informasi lainnya

1.5.4 Prediksi & Evaluasi

Untuk melakukan prediksi akan kita gunakan fungsi predict() dengan parameter:

  • object = nama model yang kita gunakan
  • newdata = data baru yang akan kita prediksi
# your code here
pred <- predict(rem, ladder_test, na.fill = F)

Untuk menguji apakah model yang kita miliki sudah baik dalam memprediksi data baru maka kita akan evaluasi dengan menggunakan nilai error, salah satu metric eror yang biasa digunakan adalah MAPE. Kita dapat melakukannya menggunakan fungsi MAPE() dengan parameter:

  • y_pred = nilai hasil prediksi
  • y_true = nilai target asli
# your code here
MAPE(y_pred = pred,
     y_true = ladder_test$Life.Ladder)
#> [1] 0.0642779

Insight: tingkat kesalahan prediski model fem dalam memprediksi nilai baru adalah sebesra 6,42%, artinya model sudah cukup baik untuk digunakan dalam memprediksi data yang baru.


2 Kesimpulan & Saran

Dari serangkaian proses analisis yang telah dilakukan, dapat kita peroleh kesimpulan sebagai berikut:

  • tingkat kebahagiaan masyarakat tertinggi di Eropa Timur adalah di negara Uzbekistan
  • tingkat kebahagiaan masyarakat terrendah di Eropa Timur adalah di negara Georgia
  • Tidak terdapat multikolineritas variabel dalam data yang digunakan
  • variabel yang signifikan mempengaruhi tingkat kebahagiaan masyarakan di suatu negara adalah Positive.Affect dan social.support
  • dari kedua variabel yang signifikan tersebut, Positive.Affect memberikan pengaruh yang lebih besar terhadap tingkat kebahagaiaan masyarakat di suatu negara
  • dari model final, kita ketahui bahwa index individu memberikan pengaruh terhadap tingkat kebahagiaan masyarakat. yang artinya setiap negara memiliki karakteristik yang berbeda mengenai tingkat kebahagiaan masyarakatnya
  • terdapat efek waktu terhadap tingkat kebahagiaan masyarakat di suatu negara di wilayah Eropa Timur

Saran:

  • Untuk meningkatkan tingkat kebahagiaan, negara perlu meningkatkan social.support dan Positive.Affect-nya
  • Masih terjadi permasalahan autokorelasi antar sisaan, untuk menanganinya dapat dilakukan transformasi Logaritma natural atau transformasi Box-cox