library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.1.1
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.4.2     v purrr   1.0.1
## v tibble  3.2.1     v dplyr   1.1.2
## v tidyr   1.3.0     v stringr 1.5.0
## v readr   2.1.2     v forcats 0.5.1
## Warning: package 'ggplot2' was built under R version 4.1.3
## Warning: package 'tibble' was built under R version 4.1.3
## Warning: package 'tidyr' was built under R version 4.1.3
## Warning: package 'readr' was built under R version 4.1.3
## Warning: package 'purrr' was built under R version 4.1.3
## Warning: package 'dplyr' was built under R version 4.1.3
## Warning: package 'stringr' was built under R version 4.1.3
## Warning: package 'forcats' was built under R version 4.1.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(caret)
## Warning: package 'caret' was built under R version 4.1.2
## Loading required package: lattice
## 
## Attaching package: 'caret'
## The following object is masked from 'package:purrr':
## 
##     lift
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.1.1
library(psych)
## Warning: package 'psych' was built under R version 4.1.2
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(pROC)
## Warning: package 'pROC' was built under R version 4.1.2
## Type 'citation("pROC")' for a citation.
## 
## Attaching package: 'pROC'
## The following objects are masked from 'package:stats':
## 
##     cov, smooth, var
Gender <- sample(c("M","F"), size = 600, replace = T, prob = c(0.45, 0.55))

City <- sample(x = c("Lisbon", "NY", "London", "LA", "Paris"), 
               size = 600, replace = T, prob = c(0.24, 0.34, 0.15, 0.22, 0.05))

Marital <- sample(x = c("Single", "Married", "Divorced", "Widowed"), 
                  replace = T, prob = c(0.3, 0.50, 0.15, 0.05), size = 600)

Happiness <- rnorm(n = 600, mean = 70, sd = 15) %>% floor()

Working <- sample(x = c(0,1), replace = T, prob = c(0.25, 0.75), size = 600)

data <- data.frame(Working, Gender, Marital, Happiness, City)

data %>% head(50) %>% knitr::kable(digits = 3)
Working Gender Marital Happiness City
1 M Single 82 Lisbon
0 M Married 69 LA
1 M Single 108 NY
1 M Married 87 Lisbon
1 F Married 70 London
1 F Married 42 London
0 F Married 87 NY
1 F Divorced 79 LA
0 F Divorced 72 LA
1 M Divorced 86 NY
1 F Married 70 NY
1 F Single 64 LA
1 F Married 81 London
1 M Married 77 LA
1 M Divorced 70 Lisbon
1 M Married 67 NY
0 M Married 61 NY
1 F Married 77 LA
1 F Married 59 Lisbon
1 F Married 68 NY
1 F Single 104 Lisbon
0 F Married 68 LA
1 M Widowed 68 Lisbon
1 F Single 59 Lisbon
1 F Widowed 63 Lisbon
1 M Married 55 LA
1 M Divorced 57 NY
0 F Married 75 NY
1 F Married 62 Lisbon
1 M Widowed 101 Lisbon
1 M Divorced 66 NY
1 M Married 54 London
0 M Married 55 Lisbon
0 F Married 36 Lisbon
1 M Single 40 NY
1 F Married 68 NY
1 M Single 55 NY
1 F Divorced 61 LA
1 M Single 42 LA
1 F Married 65 London
0 F Single 70 Lisbon
1 F Single 51 NY
1 F Single 52 Lisbon
0 M Married 73 NY
1 M Single 64 Lisbon
0 M Single 51 London
0 M Divorced 79 LA
1 F Single 77 LA
1 F Single 79 London
1 F Married 66 Lisbon
### Descriptive Statistics ###

data$working_status <- 
  ifelse(data$Working == 0, "No", "Yes")

ggplot(data, aes(x = working_status)) + 
  geom_bar(fill = c("red", "green"), col = "black", width = 0.4) + 
  stat_count(geom = "text", aes(label = ..count..), vjust = -0.5, hjust = .5) + 
  ggtitle("Distribution of Working Status") + 
  scale_y_continuous(limits = c(0, max(table(data$Working)) + 50))
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## i Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

data %>% group_by(Working) %>% summarise("Count"=n()) %>% knitr::kable()
Working Count
0 146
1 454
ggplot(data, aes(x = working_status, fill = Gender)) + 
  geom_bar(position = "dodge") + 
  ggtitle("Distribution of Gender per working Status")

ggplot(data, aes(x = working_status, fill = Marital)) + 
  geom_bar(position = "dodge") + 
  ggtitle("Distribution of Marital status per working status")

ggplot(data, aes(x = working_status, fill = City)) + 
  geom_bar(position = "dodge") + 
  ggtitle("Distribution of City per working status")

col1 <- colorRampPalette(colors = c("4040555", "7788789", "99669695"))

ggplot(data, aes(x = Happiness)) + 
  geom_histogram(fill = col1(60), col = "black", size = 0.4) + 
  facet_wrap(~working_status) + ggtitle("Distribution of Happiness by Working Status")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## i Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

data %>% group_by(working_status) %>% 
  summarise("Count"=n(), "Mean of Happiness"=mean(Happiness)) %>% 
  knitr::kable(digits = 3)
working_status Count Mean of Happiness
No 146 68.178
Yes 454 68.978
data <- select(data, -working_status)

### End of Descriptive Statistics Part ###
### Logistic Regression Part ###

model <- glm(Working ~ . , data, family = "binomial")
summary(model)
## 
## Call:
## glm(formula = Working ~ ., family = "binomial", data = data)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.0346   0.5309   0.7421   0.7995   0.8658  
## 
## Coefficients:
##                 Estimate Std. Error z value Pr(>|z|)  
## (Intercept)     0.625357   0.547236   1.143   0.2531  
## GenderM        -0.009749   0.194445  -0.050   0.9600  
## MaritalMarried  0.067327   0.288639   0.233   0.8156  
## MaritalSingle   0.087818   0.309341   0.284   0.7765  
## MaritalWidowed  0.305028   0.526415   0.579   0.5623  
## Happiness       0.003319   0.006418   0.517   0.6050  
## CityLisbon      0.705767   0.304105   2.321   0.0203 *
## CityLondon      0.084706   0.312583   0.271   0.7864  
## CityNY          0.093238   0.252353   0.369   0.7118  
## CityParis       0.371800   0.503504   0.738   0.4603  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 665.87  on 599  degrees of freedom
## Residual deviance: 657.75  on 590  degrees of freedom
## AIC: 677.75
## 
## Number of Fisher Scoring iterations: 4
data$prob <- predict(model, type = "response")


describe(data$prob)
##    vars   n mean   sd median trimmed  mad  min  max range skew kurtosis se
## X1    1 600 0.76 0.05   0.74    0.75 0.03 0.69 0.88  0.19 0.86    -0.74  0
## Several options for prediction:
### Prediction based upon 50%

data$result <- ifelse(data$prob <= 0.50, 0, 1)

table(data$Working, data$result)
##    
##       1
##   0 146
##   1 454
confusionMatrix(reference = as.factor(data$Working), as.factor(data$result))
## Warning in confusionMatrix.default(reference = as.factor(data$Working), : Levels
## are not in the same order for reference and data. Refactoring data to match.
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1
##          0   0   0
##          1 146 454
##                                           
##                Accuracy : 0.7567          
##                  95% CI : (0.7203, 0.7905)
##     No Information Rate : 0.7567          
##     P-Value [Acc > NIR] : 0.5222          
##                                           
##                   Kappa : 0               
##                                           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.0000          
##             Specificity : 1.0000          
##          Pos Pred Value :    NaN          
##          Neg Pred Value : 0.7567          
##              Prevalence : 0.2433          
##          Detection Rate : 0.0000          
##    Detection Prevalence : 0.0000          
##       Balanced Accuracy : 0.5000          
##                                           
##        'Positive' Class : 0               
## 
### Prediction based upon mean probability of prediction value

mean_prob <- data$prob %>% mean()

data$result <- ifelse(data$prob <= mean_prob, 0, 1)

table(data$Working, data$result)
##    
##       0   1
##   0 114  32
##   1 298 156
confusionMatrix(reference = as.factor(data$Working), as.factor(data$result))
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1
##          0 114 298
##          1  32 156
##                                           
##                Accuracy : 0.45            
##                  95% CI : (0.4097, 0.4908)
##     No Information Rate : 0.7567          
##     P-Value [Acc > NIR] : 1               
##                                           
##                   Kappa : 0.0769          
##                                           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.7808          
##             Specificity : 0.3436          
##          Pos Pred Value : 0.2767          
##          Neg Pred Value : 0.8298          
##              Prevalence : 0.2433          
##          Detection Rate : 0.1900          
##    Detection Prevalence : 0.6867          
##       Balanced Accuracy : 0.5622          
##                                           
##        'Positive' Class : 0               
## 
### Prediction based upon mean probability of prediction value
#### ROC Curve
plot(roc(data$Working, data$prob), col = "red", main = "ROC Curve")
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases

#### AUC value
auc_val <- roc(data$Working, data$prob) %>% auc()
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
auc_val
## Area under the curve: 0.5598
data$result <- ifelse(data$prob <= auc_val, 0, 1)

table(data$Working, data$result)
##    
##       1
##   0 146
##   1 454
confusionMatrix(reference = as.factor(data$Working), as.factor(data$result))
## Warning in confusionMatrix.default(reference = as.factor(data$Working), : Levels
## are not in the same order for reference and data. Refactoring data to match.
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1
##          0   0   0
##          1 146 454
##                                           
##                Accuracy : 0.7567          
##                  95% CI : (0.7203, 0.7905)
##     No Information Rate : 0.7567          
##     P-Value [Acc > NIR] : 0.5222          
##                                           
##                   Kappa : 0               
##                                           
##  Mcnemar's Test P-Value : <2e-16          
##                                           
##             Sensitivity : 0.0000          
##             Specificity : 1.0000          
##          Pos Pred Value :    NaN          
##          Neg Pred Value : 0.7567          
##              Prevalence : 0.2433          
##          Detection Rate : 0.0000          
##    Detection Prevalence : 0.0000          
##       Balanced Accuracy : 0.5000          
##                                           
##        'Positive' Class : 0               
##