Email:
RPubs: https://rpubs.com/elvriana_e/


1 Regresi Linear Berganda

Dalam proyek ini saya memberikan anda dataset insurance.csv, informasi lanjut mengenai data ini dapat anda baca di Kaggle.

Tugas kalian adalah sebagai berikut:

  1. Meringkas informasi penting yang terkandung data insurance.csv tersebut.
  2. Memahami faktor-faktor apa yang mempengaruhi premi asuransi konsumen.
  3. Menemukan model terbaik yang dapat memprediksi premi asuransi konsumen.

1.1 Informasi Penting yang Terkandung Data insurance.csv

1.1.1 Persiapan Data

1.1.1.1 Library

Beberapa library yang akan digunakan yaitu :

library(dplyr)
library(ggcorrplot)
library(ggplot2)
library(corrplot)
library(GGally)
library(DT)
library(Metrics)
library(hrbrthemes)
library(plotly)

1.1.1.2 Impor Data

Berikut data dalam dataset insurance:

insurance <- read.csv("insurance.csv")
datatable(insurance)

Dataset ini terdiri dari 1338 data dengan 7 variabel.

data.frame("total.data" = dim(insurance)[1],
           "total.variabel" = dim(insurance)[2])
##   total.data total.variabel
## 1       1338              7

1.1.1.3 Deskripsi Variabel

Berikut deskripsi dari setiap variabel dalam dataset insurance:

Variabel Deskripsi
age Usia penerima manfaat utama
sex Jenis kelamin kontraktor asuransi, yaitu perempuan dan laki-laki
bmi Indeks massa tubuh, memberikan pemahaman tentang tubuh, bobot yang relatif tinggi atau rendah relatif terhadap tinggi badan, indeks objektif berat badan (kg/^2) menggunakan rasio tinggi terhadap berat, idealnya 18.5 menjadi 24.9.
children Jumlah anak-anak yang dilindungi oleh asuransi kesehatan/jumlah tanggungan
smoker Perokok/Tidak perokok
region Wilayah pemukiman penerima di AS, Timur laut, Tenggara, Barat daya, Barat laut
charges Biaya medis individu yang ditagih oleh asuransi kesehatan

1.1.2 Pembersihan Data

1.1.2.1 Periksa Struktur Data

Berikut adalah struktur dari dataset tersebut.

glimpse(insurance)
## Rows: 1,338
## Columns: 7
## $ age      <int> 19, 18, 28, 33, 32, 31, 46, 37, 37, 60, 25, 62, 23, 56, 27...
## $ sex      <chr> "female", "male", "male", "male", "male", "female", "femal...
## $ bmi      <dbl> 27.900, 33.770, 33.000, 22.705, 28.880, 25.740, 33.440, 27...
## $ children <int> 0, 1, 3, 0, 0, 0, 1, 3, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0...
## $ smoker   <chr> "yes", "no", "no", "no", "no", "no", "no", "no", "no", "no...
## $ region   <chr> "southwest", "southeast", "southeast", "northwest", "north...
## $ charges  <dbl> 16884.924, 1725.552, 4449.462, 21984.471, 3866.855, 3756.6...

Bisa dilihat bahwa dalam dataset tersebut terdapat 1,338 data dengan 7 variabel. Variabel age dan children bertipe integer, variabel sex, smoker dan region bertipe character, variabel bmi dan charges bertipe numerik. Karena struktur datanya masih ada yang belum sesuai, maka dilakukan sedikit perubahan seperti berikut agar data dapat diolah dengan baik.

insurance <- insurance %>%
  mutate(
    sex = as.factor(sex),
    smoker = as.factor(smoker),
    region = as.factor(region))

Setelah diubah maka struktur datanya akan menjadi seperti berikut.

glimpse(insurance)
## Rows: 1,338
## Columns: 7
## $ age      <int> 19, 18, 28, 33, 32, 31, 46, 37, 37, 60, 25, 62, 23, 56, 27...
## $ sex      <fct> female, male, male, male, male, female, female, female, ma...
## $ bmi      <dbl> 27.900, 33.770, 33.000, 22.705, 28.880, 25.740, 33.440, 27...
## $ children <int> 0, 1, 3, 0, 0, 0, 1, 3, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0...
## $ smoker   <fct> yes, no, no, no, no, no, no, no, no, no, no, yes, no, no, ...
## $ region   <fct> southwest, southeast, southeast, northwest, northwest, sou...
## $ charges  <dbl> 16884.924, 1725.552, 4449.462, 21984.471, 3866.855, 3756.6...

1.1.2.2 Periksa Data Hilang

Dalam setiap proses pengolahan data kita dapat melakukan pemeriksaan data yang hilang (missing values) sebelum melakukan proses analisa dengan cara sebagai berikut:

colSums(is.na(insurance))
##      age      sex      bmi children   smoker   region  charges 
##        0        0        0        0        0        0        0

Hasilnya tidak terdapat missing value pada dataset ini.

1.1.2.3 Periksa Data Duplikat

kita dapat melakukan pemeriksaan data yang duplikat dengan cara sebagai berikut:

data.frame("jumlah.seluruh.data"=nrow(insurance),
           "jumlah.data.unik" = nrow(distinct(insurance))
           )
##   jumlah.seluruh.data jumlah.data.unik
## 1                1338             1337

Dikarenakan ada data yang duplikat, maka langkah selanjutnya adalah menghapus atau menghilangkan data duplikat tersebut dengan cara berikut:

insurance = distinct(insurance)
data.frame("jumlah.seluruh.data"=nrow(insurance),
           "jumlah.data.unik" = nrow(distinct(insurance))
           )
##   jumlah.seluruh.data jumlah.data.unik
## 1                1337             1337

Hasilnya sudah tidak ada data duplikat lagi, karena sudah tidak ada lagi data yang bermasalah maka kita lanjutkan ke proses selanjutnya.

1.1.2.4 Ringkasan Data

summary(insurance)  
##       age            sex           bmi           children     smoker    
##  Min.   :18.00   female:662   Min.   :15.96   Min.   :0.000   no :1063  
##  1st Qu.:27.00   male  :675   1st Qu.:26.29   1st Qu.:0.000   yes: 274  
##  Median :39.00                Median :30.40   Median :1.000             
##  Mean   :39.22                Mean   :30.66   Mean   :1.096             
##  3rd Qu.:51.00                3rd Qu.:34.70   3rd Qu.:2.000             
##  Max.   :64.00                Max.   :53.13   Max.   :5.000             
##        region       charges     
##  northeast:324   Min.   : 1122  
##  northwest:324   1st Qu.: 4746  
##  southeast:364   Median : 9386  
##  southwest:325   Mean   :13279  
##                  3rd Qu.:16658  
##                  Max.   :63770

1.1.3 Visualisasi Data

Berikut visualisasi data berdasarkan Perilaku Anggota Asuransi.

1.1.3.1 Usia Anggota Asuransi

age_group <- insurance %>%
                group_by(age) %>%
                summarise(total = n())

Agecut <- cut(age_group$age, c(seq(15, 65, by = 5), Inf), include.lowest = TRUE)

agegroup <- aggregate(total ~ Agecut, age_group, sum)

ggplot(insurance, aes(age)) +
geom_freqpoly(binwidth = 1, color = 'blue') + 
geom_histogram(binwidth = 1, fill = 'red', alpha = .5) +
theme_linedraw() + #tema
theme(panel.background = element_rect(fill = "gainsboro", colour = "white", size = 0.5, linetype = "solid"), #pengaturan tema panel 
      plot.background = element_rect(fill = "gainsboro"), #pengaturan tema panel 
      panel.grid.major = element_line(size = 0.5, linetype = 'solid', colour = "white"), #pengaturan tema panel 
      panel.grid.minor = element_line(size = 0.25, linetype = 'solid', colour = "white"), #pengaturan tema panel 
      plot.title = element_text(hjust = 0, face = 'bold',color = 'black'), #pengaturan judul
      plot.subtitle = element_text(face = "italic"), #pengaturan subtitle
      plot.caption = element_text(size = 6, vjust = -1, face = "italic")) + #pengaturan caption/credit
labs(x = 'Age', y = 'Frequency', title = "Member of Medical Cost Insurance", #nama judul dan nama axis
     subtitle = "Medical insurance's member aggregated by age") + 
guides(fill=FALSE) + #menghapus legenda warna
scale_y_continuous(limits = c(0,80), breaks = c(0,20,40,60,80)) #mengatur batas sumbu

Distribusi usia anggota asuransi relatif sama, kecuali anggota usia 18 dan 19 tahun yang memiliki populasi lebih tinggi (di atas 60). Selanjutnya saya juga membuat kelompok usia anggota pada tabel di bawah ini.

agegroup
##     Agecut total
## 1  [15,20]   165
## 2  (20,25]   140
## 3  (25,30]   138
## 4  (30,35]   130
## 5  (35,40]   127
## 6  (40,45]   137
## 7  (45,50]   144
## 8  (50,55]   140
## 9  (55,60]   125
## 10 (60,65]    91

Berdasarkan tabel tersebut maka diketahui bahwa grup usia 15 hingga 20 tahun totalnya 165, grup usia 20 hingga 25 totalnya 140 dan seterusnya. Kita juga bisa melihat bahwa grup usia yang lebih muda totalnya lebih banyak dibandingkan dengan usia yang lebih tua.

1.1.3.2 Jenis Kelamin Anggota Asuransi

sex <- insurance %>%
        group_by(sex) %>%
        summarise(total = n()) %>%
        mutate(percentage = paste0(round(100*total/sum(total),1), "%"))

plot_ly(sex, labels = ~sex, values = ~total, type = 'pie', #plotly package
        textposition = 'inside', 
        textinfo = 'label+percent',
        insidetextfont = list(color = '#FFFFFF'),
        hoverinfo = 'text',
        text = ~paste(total, 'people'),
        marker = list(colors = colors,
        line = list(color = '#FFFFFF', width = 1)), showlegend = FALSE) %>%
        layout(title = 'Gender of Medical Insurance Member', titlefont = list(size = 18, color = 'black'),
               xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
               yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))

Jenis kelamin anggota asuransi hampir sama yaitu terdiri dari 676 orang laki-laki dan 662 orang perempuan.

1.1.3.3 Wilayah Anggota Asuransi

reg <- insurance %>%
        group_by(region) %>%
        summarise(total = n()) %>%
        mutate(percentage = paste0(round(100*total/sum(total),1), "%"))

plot_ly(reg, labels = ~region, values = ~total, type = 'pie', #plotly package
        textposition = 'inside', 
        textinfo = 'label+percent',
        insidetextfont = list(color = '#FFFFFF'),
        hoverinfo = 'text',
        text = ~paste(total, 'people'),
        marker = list(colors = colors,
        line = list(color = '#FFFFFF', width = 1)), showlegend = FALSE) %>%
        layout(title = 'Region of Medical Insurance Member', titlefont = list(size = 18, color = 'black'),
               xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
               yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))

Wilayah tempat tinggal anggota asuransi hampir tersebar merata.

1.1.3.4 Anggota Asuransi yang Merokok

insurance %>%
group_by(smoker) %>%
summarise(total = n()) %>%
mutate(percentage = paste0(round(100*total/sum(total),1), "%"),
      annot = c("Non-Smoker","Smoker")) %>%
ggplot(aes(x=annot, y=total, label = percentage, fill = annot)) + 
geom_bar(stat="identity") +
geom_text(hjust = 0.5, vjust = -1, color = "black", fontface = "italic", size = 5) + #label type 
theme_linedraw() + #make a theme
theme(panel.background = element_rect(fill = "gainsboro", colour = "white", size = 0.5, linetype = "solid"), #theme panel settings
      plot.background = element_rect(fill = "gainsboro"), #theme panel settings
      legend.position = "none", #legend position
      legend.title = element_blank(), #remove legend title
      legend.background = element_rect(fill = "gainsboro", colour = "gainsboro", size = 0.5, linetype = "solid"), #change legend box color
      panel.grid.major = element_line(size = 0.5, linetype = 'solid', colour = "white"), #theme panel settings
      panel.grid.minor = element_line(size = 0.25, linetype = 'solid', colour = "white"), #theme panel settings
      plot.title = element_text(hjust = 0, face = 'bold',color = 'black'), #title settings
      plot.subtitle = element_text(face = "italic")) + #subtitle settings
      labs(x = '', y = '', title = "Member of Medical Insurance", #name title and axis
           subtitle = 'How many smokers registered as insurance member?') + #name subtitle
scale_y_continuous(limits = c(0,1500), breaks = c(0,300,600,900,1200,1500)) #set axis limits and break

Banyak anggota yang bukan perokok sebanyak 79,5% atau 1064 orang dan sisanya adalah anggota yang perokok.

1.1.3.5 Jumlah Tanggungan

child <- insurance %>%
            group_by(children) %>%
            summarise(total = n()) %>%
            mutate(percentage = paste0(round(100*total/sum(total),1), "%"),
                  annot = c("Zero", "1 Child", "2 Children", "3 Children", "4 Children", "5 Children"))

plot_ly(child, labels = ~annot, values = ~total, type = 'pie', #plotly package
        textposition = 'outside', 
        textinfo = 'label+percent',
        insidetextfont = list(color = '#FFFFFF'),
        hoverinfo = 'text',
        text = ~paste(total, 'member'),
        marker = list(colors = colors,
        line = list(color = '#FFFFFF', width = 1)), showlegend = FALSE) %>%
        layout(title = 'Number of Dependents From Medical Insurance Member', titlefont = list(size = 18, color = 'black'),
               xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
               yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))

Banyak anggota asuransi yang tidak memiliki jumlah tanggungan yaitu sebesar 42,9% atau 573 orang.

1.1.3.6 Indeks Massa Tubuh Anggota Asuransi

ggplot(insurance, aes(bmi)) +
geom_histogram(binwidth = 1, fill = 'red', alpha = .5) +
theme_linedraw() + #make a theme
theme(panel.background = element_rect(fill = "gainsboro", colour = "white", size = 0.5, linetype = "solid"), #theme panel settings
      plot.background = element_rect(fill = "gainsboro"), #theme panel settings
      panel.grid.major = element_line(size = 0.5, linetype = 'solid', colour = "white"), #theme panel settings
      panel.grid.minor = element_line(size = 0.25, linetype = 'solid', colour = "white"), #theme panel settings
      plot.title = element_text(hjust = 0, face = 'bold',color = 'black'), #title settings
      plot.subtitle = element_text(face = "italic"), #subtitle settings
      plot.caption = element_text(size = 6, vjust = -1, face = "italic")) + #caption/credit settings
labs(x = 'Body Mass Index', y = 'Frequency', title = "Member of Medical Cost Insurance", #name title and axis
     subtitle = "Body mass index of medical insurance's member") + 
guides(fill=FALSE) + #remove color legend
scale_y_continuous(limits = c(0,120), breaks = c(0,20,40,60,80,100,120)) #set axis limits and break

Indeks massa tubuh anggota terdistribusi normal.

1.1.3.7 Biaya Anggota Asuransi

ggplot(insurance, aes(charges)) +
geom_histogram(binwidth = 2000, fill = 'red', alpha = .5) +
theme_linedraw() + #make a theme
theme(panel.background = element_rect(fill = "gainsboro", colour = "white", size = 0.5, linetype = "solid"), #theme panel settings
      plot.background = element_rect(fill = "gainsboro"), #theme panel settings
      panel.grid.major = element_line(size = 0.5, linetype = 'solid', colour = "white"), #theme panel settings
      panel.grid.minor = element_line(size = 0.25, linetype = 'solid', colour = "white"), #theme panel settings
      plot.title = element_text(hjust = 0, face = 'bold',color = 'black'), #title settings
      plot.subtitle = element_text(face = "italic"), #subtitle settings
      plot.caption = element_text(size = 6, vjust = -1, face = "italic")) + #caption/credit settings
labs(x = 'Charges', y = 'Frequency', title = "Medical Cost Insurance", #name title and axis
     subtitle = "Individual medical costs billed by health insurance") + 
guides(fill=FALSE) + #remove color legend
scale_y_continuous(limits = c(0,250), breaks = c(0,50,100,150,200,250)) #set axis limits and break

Distribusi biaya medis individu yang ditagih oleh asuransi kesehatan memiliki kecenderungan positif.

1.2 Faktor-faktor yang Mempengaruhi Premi Asuransi Konsumen

Analisis density ini untuk menemukan variabel-variabel yang mempengaruhi biaya medis. Dari analisis ini terdapat beberapa wawasan seperti berikut:

  • Jenis kelamin tidak berdampak pada asuransi biaya pengobatan karena laki-laki dan perempuan memiliki distribusi / density yang sama terhadap pungutan (Grafik 1).

  • Daerah tidak terlalu berpengaruh terhadap asuransi biaya kesehatan karena 4 daerah hampir memiliki distribusi / density yang sama terhadap retribusi (Grafik 2).

  • Perokok dan bukan perokok mempengaruhi asuransi biaya pengobatan karena distribusi / densitynya sangat berbeda (Grafik 3).

  • Jumlah anak / tanggungan memiliki density yang sama terhadap pungutan, kecuali jumlah anak nol. Jadi, jika Anda tidak memiliki anak maka akan berdampak pada asuransi biaya kesehatan (Grafik 4).

Berdasarkan wawasan tersebut dapat disimpulkan bahwa perokok, total tanggungan, umur, dan BMI merupakan variabel yang digunakan untuk memprediksi asuransi biaya pengobatan.

1.2.1 Density Biaya vs Jenis Kelamin

ggplot(insurance, aes(x = charges, fill = sex)) + geom_density(alpha = 0.5)

1.2.2 Density Biaya vs Wilayah

ggplot(insurance, aes(x = charges, fill = region)) + geom_density(alpha = 0.5)

1.2.3 Density Biaya vs Perokok

ggplot(insurance, aes(x = charges, fill = smoker)) + geom_density(alpha = 0.5)

1.2.4 Density Biaya vs Anak-anak

ggplot(insurance, aes(x = charges, fill = as.factor(children))) + geom_density(alpha = 0.5)

1.3 Model Terbaik yang Dapat Memprediksi Premi Asuransi Konsumen

1.3.1 Pengelompokan Persamaan

Karena perokok, total tanggungan, dan BMI berpengaruh terhadap asuransi biaya kesehatan, saya mengelompokkan faktor-faktor tersebut ke dalam 8 kategori yang ditunjukkan seperti di bawah ini. Akhirnya, saya hanya memiliki usia atau dan BMI sebagai variabel input untuk persamaan prediksi saya. Persamaan akan ditampilkan seperti berikut.

G-1 : Perokok, tidak memiliki tanggungan, BMI di bawah 30.

G-2 : Perokok, tidak memiliki tanggungan, BMI di atas 30.

G-3 : Perokok, memiliki tanggungan, BMI di bawah 30.

G-4 : Perokok, memiliki tanggungan, BMI di atas 30.

G-5 : Bukan perokok, tidak memiliki tanggungan, BMI di bawah 30.

G-6 : Bukan perokok, tidak memiliki tanggungan, BMI di atas 30.

G-7 : Bukan perokok, memiliki tanggungan, BMI di bawah 30.

G-8 : Bukan perokok, memiliki tanggungan, BMI di atas 30.

1.3.1.1 Grafik Ke - 1

Perokok, tidak memiliki tanggungan, BMI di bawah 30

ins_smoker_nochild_under30 <- insurance %>%
                                filter(smoker == "yes" & children == 0 & bmi < 30)
ggplot(ins_smoker_nochild_under30, aes(x = age, y = charges)) + geom_point()

Tampilan grafik Age vs Charges dapat didekati dengan menggunakan regresi linier.

ggplot(ins_smoker_nochild_under30, aes(x = bmi, y = charges)) + geom_point()

BMI vs Charges terlihat memiliki korelasi yang tidak teratur.

## 
## Call:
## lm(formula = charges ~ age, data = ins_smoker_nochild_under30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -5740.7 -2372.9  -776.5   612.0 17119.6 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 11970.56    1454.78   8.228 5.55e-11 ***
## age           252.39      36.25   6.962 5.70e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4276 on 52 degrees of freedom
## Multiple R-squared:  0.4824, Adjusted R-squared:  0.4725 
## F-statistic: 48.46 on 1 and 52 DF,  p-value: 5.696e-09
## 
## Call:
## lm(formula = charges ~ age + bmi, data = ins_smoker_nochild_under30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2539.3 -1754.2 -1059.9  -203.1 15678.0 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -956.74    5104.29  -0.187   0.8521    
## age           251.20      34.35   7.312 1.75e-09 ***
## bmi           505.18     192.06   2.630   0.0112 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4051 on 51 degrees of freedom
## Multiple R-squared:  0.5442, Adjusted R-squared:  0.5264 
## F-statistic: 30.45 on 2 and 51 DF,  p-value: 1.985e-09

Dari kedua ringkasan tersebut, saya memutuskan untuk menggunakan regresi linier dengan 2 variabel (Age dan BMI) karena memiliki nilai R-Squared yang lebih baik.

Jadi persamaannya akan seperti ini:

-956.74 + (251.20 * AGE) + (505.18 * BMI)

1.3.1.2 Grafik Ke - 2

Perokok, tidak memiliki tanggungan, BMI di atas 30

ins_smoker_nochild_over30 <- insurance %>%
            filter(smoker == "yes" & children == 0 & bmi >= 30)
ggplot(ins_smoker_nochild_over30, aes(x = age, y = charges)) + geom_point()

Tampilan grafik Age vs Charges dapat didekati dengan menggunakan regresi linier.

BMI vs Charges terlihat memiliki korelasi yang tidak teratur.

## 
## Call:
## lm(formula = charges ~ age, data = ins_smoker_nochild_over30)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -19722  -2239  -1235    786  19807 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 28983.17    1737.81  16.678  < 2e-16 ***
## age           306.74      43.38   7.071 2.05e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 5361 on 59 degrees of freedom
## Multiple R-squared:  0.4587, Adjusted R-squared:  0.4495 
## F-statistic:    50 on 1 and 59 DF,  p-value: 2.05e-09
## 
## Call:
## lm(formula = charges ~ age + bmi, data = ins_smoker_nochild_over30)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -16667.0  -1505.1   -737.2     47.9  22684.4 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  8120.10    5338.78   1.521 0.133702    
## age           292.16      38.73   7.544 3.57e-10 ***
## bmi           614.01     150.40   4.082 0.000138 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4766 on 58 degrees of freedom
## Multiple R-squared:  0.5795, Adjusted R-squared:  0.565 
## F-statistic: 39.97 on 2 and 58 DF,  p-value: 1.225e-11

Dari kedua ringkasan tersebut, saya memutuskan untuk menggunakan regresi linier dengan 2 variabel (Age dan BMI) karena memiliki nilai R-Squared yang lebih baik.

Jadi persamaannya akan seperti ini:

8120.10 + (292.16 * AGE) + (614.01 * BMI)

1.3.1.3 Grafik Ke - 3

Perokok, memiliki tanggungan, BMI di bawah 30

ins_smoker_child_under30 <- insurance %>%
            filter(smoker == "yes" & children > 0 & bmi < 30)
ggplot(ins_smoker_child_under30, aes(x = age, y = charges)) + geom_point()

Tampilan grafik Age vs Charges dapat didekati dengan menggunakan regresi linier.

ggplot(ins_smoker_child_under30, aes(x = bmi, y = charges)) + geom_point()

BMI vs Charges terlihat memiliki korelasi yang tidak teratur.

summary(lm(charges ~ age, data = ins_smoker_child_under30))
## 
## Call:
## lm(formula = charges ~ age, data = ins_smoker_child_under30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4651.4 -1487.2  -352.5   637.6 15865.3 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 10842.61    1332.43   8.137 7.77e-12 ***
## age           274.71      33.18   8.280 4.19e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3199 on 73 degrees of freedom
## Multiple R-squared:  0.4843, Adjusted R-squared:  0.4772 
## F-statistic: 68.56 on 1 and 73 DF,  p-value: 4.194e-12
summary(lm(charges ~ age + bmi, data = ins_smoker_child_under30))
## 
## Call:
## lm(formula = charges ~ age + bmi, data = ins_smoker_child_under30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2741.8 -1070.1  -608.8    -5.2 15619.8 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2428.48    2769.81   0.877   0.3835    
## age           259.48      31.33   8.282 4.56e-12 ***
## bmi           359.27     105.64   3.401   0.0011 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2989 on 72 degrees of freedom
## Multiple R-squared:  0.5557, Adjusted R-squared:  0.5433 
## F-statistic: 45.02 on 2 and 72 DF,  p-value: 2.075e-13

Dari kedua ringkasan tersebut, saya memutuskan untuk menggunakan regresi linier dengan 2 variabel (Age dan BMI) karena memiliki nilai R-Squared yang lebih baik.

Jadi persamaannya akan seperti ini:

2428.48 + (259.48 * AGE) + (359.27 * BMI)

1.3.1.4 Grafik Ke - 4

Perokok, memiliki tanggungan, BMI di atas 30

ins_smoker_child_over30 <- insurance %>%
            filter(smoker == "yes" & children > 0 & bmi >= 30)
ggplot(ins_smoker_child_over30, aes(x = age, y = charges)) + geom_point()

Tampilan grafik Age vs Charges dapat didekati dengan menggunakan regresi linier.

BMI vs Charges terlihat memiliki korelasi yang tidak teratur.

## 
## Call:
## lm(formula = charges ~ age, data = ins_smoker_child_over30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4354.3 -2271.4  -859.3  1174.1 18445.4 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 32648.20    1361.98  23.971  < 2e-16 ***
## age           241.21      31.86   7.572 4.89e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3723 on 82 degrees of freedom
## Multiple R-squared:  0.4115, Adjusted R-squared:  0.4043 
## F-statistic: 57.34 on 1 and 82 DF,  p-value: 4.889e-11
## 
## Call:
## lm(formula = charges ~ age + bmi, data = ins_smoker_child_over30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2212.2 -1334.7  -653.6    40.7 17621.6 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 16021.03    3341.64   4.794 7.30e-06 ***
## age           253.72      27.69   9.162 3.81e-14 ***
## bmi           447.91      84.22   5.318 9.08e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3225 on 81 degrees of freedom
## Multiple R-squared:  0.5638, Adjusted R-squared:  0.553 
## F-statistic: 52.35 on 2 and 81 DF,  p-value: 2.553e-15

Dari kedua ringkasan tersebut, saya memutuskan untuk menggunakan regresi linier dengan 2 variabel (umur dan BMI) karena memiliki nilai R-Squared yang lebih baik.

Jadi persamaannya akan seperti ini:

16021.03 + (253.72 * AGE) + (447.91 * BMI)

1.3.1.5 Grafik Ke - 5

Bukan perokok, tidak memiliki tanggungan, BMI di bawah 30

ins_nonsmoker_nochild_under30 <- insurance %>%
            filter(smoker == "no" & children == 0 & bmi < 30)
ggplot(ins_nonsmoker_nochild_under30, aes(x = age, y = charges)) + geom_point()

Tampilan grafik Age vs Charges dapat didekati dengan menggunakan regresi linier.

BMI vs Charges terlihat memiliki korelasi yang tidak teratur.

## 
## Call:
## lm(formula = charges ~ age, data = ins_nonsmoker_nochild_under30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2428.1 -1440.0  -886.5  -391.6 21672.8 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -3239.15     687.81  -4.709 4.43e-06 ***
## age           277.00      16.79  16.495  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3950 on 217 degrees of freedom
## Multiple R-squared:  0.5563, Adjusted R-squared:  0.5543 
## F-statistic: 272.1 on 1 and 217 DF,  p-value: < 2.2e-16
## 
## Call:
## lm(formula = charges ~ age + bmi, data = ins_nonsmoker_nochild_under30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2457.4 -1453.0  -852.6  -391.1 21715.4 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -3791.02    2191.60  -1.730   0.0851 .  
## age           276.56      16.91  16.354   <2e-16 ***
## bmi            22.40      84.44   0.265   0.7911    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3958 on 216 degrees of freedom
## Multiple R-squared:  0.5565, Adjusted R-squared:  0.5524 
## F-statistic: 135.5 on 2 and 216 DF,  p-value: < 2.2e-16

Dari kedua ringkasan tersebut, saya memutuskan untuk menggunakan regresi linier dengan 1 variabel (umur) karena memiliki nilai R-Squared yang lebih baik.

Jadi persamaannya akan seperti ini:

-3239.15 + (277.00 * AGE)

1.3.1.6 Grafik Ke - 6

Bukan perokok, tidak memiliki tanggungan, BMI di atas 30

ins_nonsmoker_nochild_over30 <- insurance %>%
            filter(smoker == "no" & children == 0 & bmi >= 30)
ggplot(ins_nonsmoker_nochild_over30, aes(x = age, y = charges)) + geom_point()

Tampilan grafik Age vs Charges dapat didekati dengan menggunakan regresi linier.

BMI vs Charges terlihat memiliki korelasi yang tidak teratur.

## 
## Call:
## lm(formula = charges ~ age, data = ins_nonsmoker_nochild_over30)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
##  -2601  -1680  -1101   -365  20402 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -2138.96     639.67  -3.344  0.00096 ***
## age           253.69      14.73  17.219  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3868 on 237 degrees of freedom
## Multiple R-squared:  0.5558, Adjusted R-squared:  0.5539 
## F-statistic: 296.5 on 1 and 237 DF,  p-value: < 2.2e-16
## 
## Call:
## lm(formula = charges ~ age + bmi, data = ins_nonsmoker_nochild_over30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2825.0 -1641.6 -1087.4  -382.4 20308.3 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -392.10    2335.28  -0.168    0.867    
## age           254.50      14.78  17.217   <2e-16 ***
## bmi           -50.42      64.82  -0.778    0.437    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3872 on 236 degrees of freedom
## Multiple R-squared:  0.5569, Adjusted R-squared:  0.5532 
## F-statistic: 148.3 on 2 and 236 DF,  p-value: < 2.2e-16

Dari kedua ringkasan tersebut, saya memutuskan untuk menggunakan regresi linier dengan 1 variabel (Age) karena memiliki nilai R-Squared yang lebih baik.

Jadi persamaannya akan seperti ini:

-2155.79 + (254.01 * AGE)

1.3.1.7 Grafik Ke - 7

Bukan perokok, memiliki tanggungan, BMI di bawah 30

ins_nonsmoker_child_under30 <- insurance %>%
            filter(smoker == "no" & children > 0 & bmi < 30)
ggplot(ins_nonsmoker_child_under30, aes(x = age, y = charges)) + geom_point()

Tampilan grafik Age vs Charges dapat didekati dengan menggunakan regresi linier.

BMI vs Charges terlihat memiliki korelasi yang tidak teratur.

## 
## Call:
## lm(formula = charges ~ age, data = ins_nonsmoker_child_under30)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
##  -3050  -2080  -1578   -808  22413 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -884.08    1029.59  -0.859    0.391    
## age           247.85      25.87   9.581   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4975 on 281 degrees of freedom
## Multiple R-squared:  0.2462, Adjusted R-squared:  0.2436 
## F-statistic:  91.8 on 1 and 281 DF,  p-value: < 2.2e-16
## 
## Call:
## lm(formula = charges ~ age + bmi, data = ins_nonsmoker_child_under30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3255.8 -2178.9 -1528.4  -664.9 22367.6 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -2835.49    2564.04  -1.106    0.270    
## age           245.27      26.07   9.408   <2e-16 ***
## bmi            79.79      96.01   0.831    0.407    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4978 on 280 degrees of freedom
## Multiple R-squared:  0.2481, Adjusted R-squared:  0.2427 
## F-statistic: 46.19 on 2 and 280 DF,  p-value: < 2.2e-16

Dari kedua ringkasan tersebut, saya memutuskan untuk menggunakan regresi linier dengan 1 variabel (Age) karena memiliki nilai R-Squared yang lebih baik.

Jadi persamaannya akan seperti ini:

-884.08 + (247.85 * AGE)

1.3.1.8 Grafik Ke - 8

Bukan perokok, memiliki tanggungan, BMI di atas 30

ins_nonsmoker_child_over30 <- insurance %>%
            filter(smoker == "no" & children > 0 & bmi >= 30)
ggplot(ins_nonsmoker_child_over30, aes(x = age, y = charges)) + geom_point()

Tampilan grafik Age vs Charges dapat didekati dengan menggunakan regresi linier.

BMI vs Charges terlihat memiliki korelasi yang tidak teratur.

## 
## Call:
## lm(formula = charges ~ age, data = ins_nonsmoker_child_over30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3138.6 -2283.0 -1647.7  -746.8 24235.0 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -2161.36    1041.35  -2.076   0.0387 *  
## age           282.54      24.23  11.660   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 5250 on 320 degrees of freedom
## Multiple R-squared:  0.2982, Adjusted R-squared:  0.296 
## F-statistic:   136 on 1 and 320 DF,  p-value: < 2.2e-16
## 
## Call:
## lm(formula = charges ~ age + bmi, data = ins_nonsmoker_child_over30)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3320.7 -2278.4 -1636.0  -711.3 24252.0 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -923.87    2648.40  -0.349    0.727    
## age           283.07      24.28  11.658   <2e-16 ***
## bmi           -35.83      70.50  -0.508    0.612    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 5256 on 319 degrees of freedom
## Multiple R-squared:  0.2988, Adjusted R-squared:  0.2944 
## F-statistic: 67.95 on 2 and 319 DF,  p-value: < 2.2e-16

Dari kedua ringkasan tersebut, saya memutuskan untuk menggunakan regresi linier dengan 1 variabel (Age) karena memiliki nilai R-Squared yang lebih baik.

Jadi persamaannya akan seperti ini:

-2161.36 + (282.54 * AGE)

Kita dapat melihat korelasi dari beberapa variabel seperti berikut.

1.3.2 Matriks Korelasi

ggcorr(insurance,label = T, size=3, label_size = 3, hjust=0.95)+
  labs(
    title="Matriks Korelasi"
  )+
  theme_minimal()+
  theme(
    plot.title = element_text(hjust = 0.5),
    axis.title=element_text(size=8,face="bold"), 
    axis.text.y=element_blank()
  )

Berdasarkan matriks korelasi diatas, variabel bmi, children dan age mempunyai pengaruh terhadap charges. Lalu variabel yang memiliki korelasi paling tinggi dengan charges adalah age. Kita juga melihat terdapat korelasi sebesar 0.1 antara age dengan bmi, lalu antara bmi dengan charges sebesar 0.2, dan antara variabel children dengan charges sebesar 0.1.

1.3.3 Model Terbaik

lm_insurance_ <- lm(charges~.,data=insurance)
summary(lm_insurance_)
## 
## Call:
## lm(formula = charges ~ ., data = insurance)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -11305.1  -2850.3   -979.9   1395.0  29992.8 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     -11936.56     988.23 -12.079  < 2e-16 ***
## age                256.76      11.91  21.555  < 2e-16 ***
## sexmale           -129.48     333.20  -0.389 0.697630    
## bmi                339.25      28.61  11.857  < 2e-16 ***
## children           474.82     137.90   3.443 0.000593 ***
## smokeryes        23847.33     413.35  57.693  < 2e-16 ***
## regionnorthwest   -349.23     476.82  -0.732 0.464053    
## regionsoutheast  -1035.27     478.87  -2.162 0.030804 *  
## regionsouthwest   -960.08     478.11  -2.008 0.044836 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 6064 on 1328 degrees of freedom
## Multiple R-squared:  0.7507, Adjusted R-squared:  0.7492 
## F-statistic:   500 on 8 and 1328 DF,  p-value: < 2.2e-16

terlihat nilai Adjusted R-squared:0.7492 , hal ini menandakan bahwa model lm_insurance_ dapat memprediksi 74.9%. Dan ini sudah termasuk model terbaik yang bisa kita dapatkan untuk melakukan prediksi premi asuransi konsumen.

Model Regresinya adalah expenses = -11938.5 + 256.9(age) + 339.2(bmi) + 475.5(children) + 23848.5(smokeryes) - 1035(regionsoutheast) - 960(regionsouthwest)

1.3.4 Prediksi Biaya

Kita dapat melakukan prediksi dengan fungsi dibawah ini:

predict <- function(x){
               for(i in 1:nrow(x)){
               if(x[i,"smoker"] == "yes" && x[i,"children"] == 0 && x[i,"bmi"] < 30){
               x[i,"result"] = -956.74 + (251.20*x[i,"age"]) + (505.18*x[i,"bmi"])
               } else if(x[i,"smoker"] == "yes" && x[i,"children"] == 0 && x[i,"bmi"] >= 30) {
               x[i,"result"] = 8120.10 + (292.16*x[i,"age"]) + (614.01*x[i,"bmi"])
               } else if(x[i,"smoker"] == "yes" && x[i,"children"] > 0 && x[i,"bmi"] < 30){
               x[i,"result"] = 2428.48 + (259.48*x[i,"age"]) + (359.27*x[i,"bmi"])
               } else if(x[i,"smoker"] == "yes" && x[i,"children"] > 0 && x[i,"bmi"] >= 30){
               x[i,"result"] = 16021.03 + (253.72*x[i,"age"]) + (447.91*x[i,"bmi"])
               } else if(x[i,"smoker"] == "no" && x[i,"children"] == 0 && x[i,"bmi"] < 30){
               x[i,"result"] = -3239.15 + (277.00*x[i,"age"])
               } else if(x[i,"smoker"] == "no" && x[i,"children"] == 0 && x[i,"bmi"] >= 30){
               x[i,"result"] = -2155.79 + (254.01*x[i,"age"])
               } else if(x[i,"smoker"] == "no" && x[i,"children"] > 0 && x[i,"bmi"] < 30){
               x[i,"result"] = -884.08 + (247.85*x[i,"age"])
               } else {
               x[i,"result"] = -2161.36 + (282.54*x[i,"age"])
               }    
               }
          return(x)
          }

Sehingga hasil yang diperoleh akan seperti ini:

predcharges <- predict(insurance)

datatable(predcharges, colnames = c('Age', 'Sex', 'BMI', 'Children', 'Smoker', 'Region', 'Charges', 'Charges Prediction'))

Root Mean Square Error dari hasil prediksi

rmse(predcharges$charges, predcharges$result)
## [1] 4439.137

Nilai kesalahan rata-rata dari prediksi saya adalah plus minus 4437.56.

Kesalahan Persen Absolut Rata-rata dari hasil prediksi

mape(predcharges$charges, predcharges$result)
## [1] 0.2669668

Rata-rata persentase kesalahan prediksi adalah 26.7%.

1.3.5 Studi Kasus

Berapa biaya asuransi untuk orang-orang ini?

  1. Ben, 47 tahun, 28.215 BMI, 4 jumlah tanggungan, bukan perokok, dan tinggal di timur laut.

  2. Gaby, 18 tahun, 36.850 BMI, tidak ada jumlah tanggungan, perokok, dan tinggal di tenggara.

Kita bisa menjawab pertanyaan tersebut dengan fungsi ini:

predict_charge <- function(age, bmi, children, smoker){
    if(smoker == "yes" && children == 0 && bmi < 30){
        result = -956.74 + (251.20*age) + (505.18*bmi)
    } else if(smoker == "yes" && children == 0 && bmi >= 30) {
        result = 8120.10 + (292.16*age) + (614.01*bmi)
    } else if(smoker == "yes" && children > 0 && bmi < 30){
        result = 2428.48 + (259.48*age) + (359.27*bmi)
    } else if(smoker == "yes" && children > 0 && bmi >= 30){
        result = 16021.03 + (253.72*age) + (447.91*bmi)
    } else if(smoker == "no" && children == 0 && bmi < 30){
        result = -3239.15 + (277.00*age)
    } else if(smoker == "no" && children == 0 && bmi >= 30){
        result = -2155.79 + (254.01*age)
    } else if(smoker == "no" && children > 0 && bmi < 30){
        result = -884.08 + (247.85*age)
    } else {
        result = -2161.36 + (282.54*age)
    }
    return(result)
    }

Biaya Asuransi Pengobatan untuk Ben:

predict_charge(47, 28.215, 4, "no")
## [1] 10764.87

Biaya Asuransi Pengobatan untuk Gaby:

predict_charge(18, 36.850, 0, "yes")
## [1] 36005.25

2 ANOVA/MANOVA

Suatu perusahaan di Amerika Serikat ingin mempekerjakan seseorang dari luar Amerika Serikat untuk posisi teknis, mereka perlu mengajukan aplikasi ke pemerintah Amerika Serikat untuk mendapatkan kartu hijau atau visa bagi pelamar asing. Untuk menunjukkan ekuitas bagi karyawan AS dan non-AS, perusahaan perlu menyatakan seberapa banyak mereka bersedia membayar karyawan ketika mereka mengajukan permohonan visa atau kartu hijau. Sementara itu, mereka perlu memberikan jumlah rata-rata, yang disebut “prevailing wage” seorang karyawan dengan keterampilan dan latar belakang serupa biasanya dibayar untuk posisi yang sama.

Perbedaan antara upah yang dibayar dan upah yang berlaku dapat menunjukkan apakah perusahaan AS bersedia membayar lebih banyak gaji kepada karyawan non-AS. Gaji lebih banyak untuk calon karyawan asing akan menarik. Selain itu, perlu diperhatikan bahwa untuk area dan pekerjaan yang berbeda, gaji dapat menunjukkan perbedaan. Oleh karena itu perlu untuk mencari tahu hubungan antara gaji, area dan posisi dapat membantu karyawan non-AS untuk memilih pekerjaan di AS.

Berdasarkan klasifikasi VISA yang mereka miliki disimpulkan bahwa ada lima jenis yang berbeda: “green card”, “H-1B”, “H-1B1 Chile”, “H- 1B1 Singapore” dan “E-3 Australia”. Untuk projek ini, silahkan anda memilih kelas VISA “H-1B” untuk melakukan data mentah pelamar yang berpenduduk tetap tahun 2018 atau 2019. Kalian dapat mendwonload Data asli yang dikumpulkan oleh Kantor Sertifikasi Tenaga Kerja Asing Departemen Tenaga Kerja AS

2.1 Impor Data

Saya hanya mengambil 1,000 Data teratas.

library(readxl)

visa2018 <- read_excel("H-1B_Disclosure_Data_FY2018_EOY.xlsx")
head(visa2018, 10)
## # A tibble: 10 x 52
##    CASE_NUMBER CASE_STATUS CASE_SUBMITTED      DECISION_DATE       VISA_CLASS
##    <chr>       <chr>       <dttm>              <dttm>              <chr>     
##  1 I-200-1802~ CERTIFIED   2018-01-29 00:00:00 2018-02-02 00:00:00 H-1B      
##  2 I-200-1729~ CERTIFIED   2017-10-23 00:00:00 2017-10-27 00:00:00 H-1B      
##  3 I-200-1824~ CERTIFIED   2018-08-30 00:00:00 2018-09-06 00:00:00 H-1B      
##  4 I-200-1807~ CERTIFIED   NA                  2018-03-30 00:00:00 H-1B      
##  5 I-200-1824~ CERTIFIED   2018-08-31 00:00:00 2018-09-07 00:00:00 H-1B      
##  6 I-200-1814~ CERTIFIED   2018-05-22 00:00:00 2018-05-29 00:00:00 H-1B      
##  7 I-200-1812~ CERTIFIED   2018-05-01 00:00:00 2018-05-07 00:00:00 H-1B      
##  8 I-200-1821~ CERTIFIED   2018-08-03 00:00:00 2018-08-09 00:00:00 H-1B      
##  9 I-201-1733~ CERTIFIED   2017-12-08 00:00:00 2017-12-14 00:00:00 H-1B1 Chi~
## 10 I-200-1823~ CERTIFIED   2018-08-21 00:00:00 2018-08-27 00:00:00 H-1B      
## # ... with 47 more variables: EMPLOYMENT_START_DATE <dttm>,
## #   EMPLOYMENT_END_DATE <dttm>, EMPLOYER_NAME <chr>,
## #   EMPLOYER_BUSINESS_DBA <chr>, EMPLOYER_ADDRESS <chr>, EMPLOYER_CITY <chr>,
## #   EMPLOYER_STATE <chr>, EMPLOYER_POSTAL_CODE <chr>, EMPLOYER_COUNTRY <chr>,
## #   EMPLOYER_PROVINCE <chr>, EMPLOYER_PHONE <chr>, EMPLOYER_PHONE_EXT <chr>,
## #   AGENT_REPRESENTING_EMPLOYER <chr>, AGENT_ATTORNEY_NAME <chr>,
## #   AGENT_ATTORNEY_CITY <chr>, AGENT_ATTORNEY_STATE <chr>, JOB_TITLE <chr>,
## #   SOC_CODE <chr>, SOC_NAME <chr>, NAICS_CODE <chr>, TOTAL_WORKERS <dbl>,
## #   NEW_EMPLOYMENT <dbl>, CONTINUED_EMPLOYMENT <dbl>,
## #   CHANGE_PREVIOUS_EMPLOYMENT <dbl>, NEW_CONCURRENT_EMP <dbl>,
## #   CHANGE_EMPLOYER <dbl>, AMENDED_PETITION <dbl>, FULL_TIME_POSITION <chr>,
## #   PREVAILING_WAGE <dbl>, PW_UNIT_OF_PAY <chr>, PW_WAGE_LEVEL <chr>,
## #   PW_SOURCE <chr>, PW_SOURCE_YEAR <chr>, PW_SOURCE_OTHER <chr>,
## #   WAGE_RATE_OF_PAY_FROM <dbl>, WAGE_RATE_OF_PAY_TO <dbl>,
## #   WAGE_UNIT_OF_PAY <chr>, H1B_DEPENDENT <chr>, WILLFUL_VIOLATOR <chr>,
## #   SUPPORT_H1B <chr>, LABOR_CON_AGREE <chr>, PUBLIC_DISCLOSURE_LOCATION <lgl>,
## #   WORKSITE_CITY <chr>, WORKSITE_COUNTY <chr>, WORKSITE_STATE <chr>,
## #   WORKSITE_POSTAL_CODE <chr>, ORIGINAL_CERT_DATE <dttm>

Dataset ini terdiri dari 1000 data dengan 52 variabel.

data.frame("total.data" = dim(visa2018)[1],
           "total.variabel" = dim(visa2018)[2])
##   total.data total.variabel
## 1       1000             52

2.2 Periksa Struktur Data

Berikut adalah struktur dari dataset tersebut.

glimpse(visa2018)
## Rows: 1,000
## Columns: 52
## $ CASE_NUMBER                 <chr> "I-200-18026-338377", "I-200-17296-3534...
## $ CASE_STATUS                 <chr> "CERTIFIED", "CERTIFIED", "CERTIFIED", ...
## $ CASE_SUBMITTED              <dttm> 2018-01-29, 2017-10-23, 2018-08-30, NA...
## $ DECISION_DATE               <dttm> 2018-02-02, 2017-10-27, 2018-09-06, 20...
## $ VISA_CLASS                  <chr> "H-1B", "H-1B", "H-1B", "H-1B", "H-1B",...
## $ EMPLOYMENT_START_DATE       <dttm> 2018-07-28, 2017-11-06, 2018-09-10, 20...
## $ EMPLOYMENT_END_DATE         <dttm> 2021-07-27, 2020-11-06, 2021-09-09, 20...
## $ EMPLOYER_NAME               <chr> "MICROSOFT CORPORATION", "ERNST & YOUNG...
## $ EMPLOYER_BUSINESS_DBA       <chr> NA, NA, NA, "N/A", NA, NA, NA, NA, NA, ...
## $ EMPLOYER_ADDRESS            <chr> "1 MICROSOFT WAY", "200 PLAZA DRIVE", "...
## $ EMPLOYER_CITY               <chr> "REDMOND", "SECAUCUS", "IRVING", "ISELI...
## $ EMPLOYER_STATE              <chr> "WA", "NJ", "TX", "NJ", "NJ", "TX", "MA...
## $ EMPLOYER_POSTAL_CODE        <chr> "98052", "07094", "75062", "08830", "08...
## $ EMPLOYER_COUNTRY            <chr> "UNITED STATES OF AMERICA", "UNITED STA...
## $ EMPLOYER_PROVINCE           <chr> NA, NA, NA, "N/A", NA, NA, NA, NA, NA, ...
## $ EMPLOYER_PHONE              <chr> "4258828080", "2018723003", "2145419305...
## $ EMPLOYER_PHONE_EXT          <chr> NA, NA, NA, NA, NA, NA, "1", NA, NA, NA...
## $ AGENT_REPRESENTING_EMPLOYER <chr> "N", "Y", "N", "Y", "Y", "Y", "N", "N",...
## $ AGENT_ATTORNEY_NAME         <chr> ",", "BRADSHAW, MELANIE", ",", "DUTOT, ...
## $ AGENT_ATTORNEY_CITY         <chr> NA, "TORONTO", NA, "TROY", "EDISON", "R...
## $ AGENT_ATTORNEY_STATE        <chr> NA, NA, NA, "MI", "NJ", "TX", NA, NA, N...
## $ JOB_TITLE                   <chr> "SOFTWARE ENGINEER", "TAX SENIOR", "DAT...
## $ SOC_CODE                    <chr> "15-1132", "13-2011", "15-1141", "15-11...
## $ SOC_NAME                    <chr> "SOFTWARE DEVELOPERS, APPLICATIONS", "A...
## $ NAICS_CODE                  <chr> "51121", "541211", "541511", "541511", ...
## $ TOTAL_WORKERS               <dbl> 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
## $ NEW_EMPLOYMENT              <dbl> 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ CONTINUED_EMPLOYMENT        <dbl> 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, ...
## $ CHANGE_PREVIOUS_EMPLOYMENT  <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, ...
## $ NEW_CONCURRENT_EMP          <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ CHANGE_EMPLOYER             <dbl> 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, ...
## $ AMENDED_PETITION            <dbl> 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, ...
## $ FULL_TIME_POSITION          <chr> "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y",...
## $ PREVAILING_WAGE             <dbl> 112549.00, 79976.00, 77792.00, 84406.00...
## $ PW_UNIT_OF_PAY              <chr> "Year", "Year", "Year", "Year", "Year",...
## $ PW_WAGE_LEVEL               <chr> "Level II", "Level II", "Level II", "Le...
## $ PW_SOURCE                   <chr> "OES", "OES", "OES", "OES", "OES", "Oth...
## $ PW_SOURCE_YEAR              <chr> "2017", "2017", "2018", "2017", "2018",...
## $ PW_SOURCE_OTHER             <chr> "OFLC ONLINE DATA CENTER", "OFLC ONLINE...
## $ WAGE_RATE_OF_PAY_FROM       <dbl> 143915.0, 100000.0, 78240.0, 84406.0, 9...
## $ WAGE_RATE_OF_PAY_TO         <dbl> 0, 0, 0, 85000, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ WAGE_UNIT_OF_PAY            <chr> "Year", "Year", "Year", "Year", "Year",...
## $ H1B_DEPENDENT               <chr> "N", "N", "N", "Y", "Y", "Y", "Y", "Y",...
## $ WILLFUL_VIOLATOR            <chr> "N", "N", "N", "N", "N", "N", "N", "N",...
## $ SUPPORT_H1B                 <chr> "NA", "NA", "NA", "Y", "Y", "Y", "Y", "...
## $ LABOR_CON_AGREE             <chr> NA, NA, NA, NA, "Y", NA, NA, NA, NA, "Y...
## $ PUBLIC_DISCLOSURE_LOCATION  <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,...
## $ WORKSITE_CITY               <chr> "REDMOND", "SANTA CLARA", "IRVING", "NE...
## $ WORKSITE_COUNTY             <chr> "KING", "SAN JOSE", "DALLAS", "NEW CAST...
## $ WORKSITE_STATE              <chr> "WA", "CA", "TX", "DE", "AL", "FL", "FL...
## $ WORKSITE_POSTAL_CODE        <chr> "98052", "95110", "75062", "19720", "35...
## $ ORIGINAL_CERT_DATE          <dttm> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA...

2.3 Periksa Data Hilang

colSums(is.na(visa2018))
##                 CASE_NUMBER                 CASE_STATUS 
##                           0                           0 
##              CASE_SUBMITTED               DECISION_DATE 
##                           1                           0 
##                  VISA_CLASS       EMPLOYMENT_START_DATE 
##                           0                           0 
##         EMPLOYMENT_END_DATE               EMPLOYER_NAME 
##                           0                           0 
##       EMPLOYER_BUSINESS_DBA            EMPLOYER_ADDRESS 
##                         620                           0 
##               EMPLOYER_CITY              EMPLOYER_STATE 
##                           0                           0 
##        EMPLOYER_POSTAL_CODE            EMPLOYER_COUNTRY 
##                           0                           0 
##           EMPLOYER_PROVINCE              EMPLOYER_PHONE 
##                         775                           0 
##          EMPLOYER_PHONE_EXT AGENT_REPRESENTING_EMPLOYER 
##                         931                           0 
##         AGENT_ATTORNEY_NAME         AGENT_ATTORNEY_CITY 
##                           0                         181 
##        AGENT_ATTORNEY_STATE                   JOB_TITLE 
##                         196                           0 
##                    SOC_CODE                    SOC_NAME 
##                           0                           0 
##                  NAICS_CODE               TOTAL_WORKERS 
##                           0                           0 
##              NEW_EMPLOYMENT        CONTINUED_EMPLOYMENT 
##                           0                           0 
##  CHANGE_PREVIOUS_EMPLOYMENT          NEW_CONCURRENT_EMP 
##                           0                           0 
##             CHANGE_EMPLOYER            AMENDED_PETITION 
##                           0                           0 
##          FULL_TIME_POSITION             PREVAILING_WAGE 
##                           0                           0 
##              PW_UNIT_OF_PAY               PW_WAGE_LEVEL 
##                           0                           0 
##                   PW_SOURCE              PW_SOURCE_YEAR 
##                           0                           1 
##             PW_SOURCE_OTHER       WAGE_RATE_OF_PAY_FROM 
##                          37                           0 
##         WAGE_RATE_OF_PAY_TO            WAGE_UNIT_OF_PAY 
##                           1                           1 
##               H1B_DEPENDENT            WILLFUL_VIOLATOR 
##                          27                          27 
##                 SUPPORT_H1B             LABOR_CON_AGREE 
##                          97                         635 
##  PUBLIC_DISCLOSURE_LOCATION               WORKSITE_CITY 
##                        1000                           0 
##             WORKSITE_COUNTY              WORKSITE_STATE 
##                           0                           0 
##        WORKSITE_POSTAL_CODE          ORIGINAL_CERT_DATE 
##                           0                         899

Hasilnya terdapat missing value pada dataset ini.

2.4 Data H-1B 2018

library(dplyr)
visa. <- dplyr::select(visa2018, CASE_STATUS, VISA_CLASS, JOB_TITLE, PREVAILING_WAGE, WORKSITE_CITY) 
visa_ <- dplyr::filter(visa., VISA_CLASS == "H-1B")
         
visa_
## # A tibble: 969 x 5
##    CASE_STATUS VISA_CLASS JOB_TITLE                PREVAILING_WAGE WORKSITE_CITY
##    <chr>       <chr>      <chr>                              <dbl> <chr>        
##  1 CERTIFIED   H-1B       SOFTWARE ENGINEER                 112549 REDMOND      
##  2 CERTIFIED   H-1B       TAX SENIOR                         79976 SANTA CLARA  
##  3 CERTIFIED   H-1B       DATABASE ADMINISTRATOR             77792 IRVING       
##  4 CERTIFIED   H-1B       SOFTWARE ENGINEER                  84406 NEW CASTLE   
##  5 CERTIFIED   H-1B       MICROSOFT DYNAMICS CRM ~           87714 BIRMINGHAM   
##  6 CERTIFIED   H-1B       SENIOR SYSTEM ARCHITECT            71864 SUNRISE      
##  7 CERTIFIED   H-1B       SENIOR ORACLE ADF DEVEL~           92331 JACKSONVILLE 
##  8 CERTIFIED   H-1B       SENIOR SYSTEMS ANALYST ~           80579 OWINGS MILLS 
##  9 CERTIFIED   H-1B       SENIOR JAVA DEVELOPER             104790 ALPHARETTA   
## 10 CERTIFIED   H-1B       SOFTWARE DEVELOPER                109325 PLEASANTON   
## # ... with 959 more rows