library(tidyverse)
# Setup: Load, Structure, Viewing, Summary Statistics, Missing Values Check, Cleaning Column Names
happiness <- read_csv("data.csv")
dim(happiness)
## [1] 143 11
glimpse(happiness)
## Rows: 143
## Columns: 11
## $ `Country name` <chr> "Finland", "Denmark", "Iceland", "Swede…
## $ `Ladder score` <dbl> 7.741, 7.583, 7.525, 7.344, 7.341, 7.31…
## $ upperwhisker <dbl> 7.815, 7.665, 7.618, 7.422, 7.405, 7.38…
## $ lowerwhisker <dbl> 7.667, 7.500, 7.433, 7.267, 7.277, 7.25…
## $ `Log GDP per capita` <dbl> 1.844, 1.908, 1.881, 1.878, 1.803, 1.90…
## $ `Social support` <dbl> 1.572, 1.520, 1.617, 1.501, 1.513, 1.46…
## $ `Healthy life expectancy` <dbl> 0.695, 0.699, 0.718, 0.724, 0.740, 0.70…
## $ `Freedom to make life choices` <dbl> 0.859, 0.823, 0.819, 0.838, 0.641, 0.72…
## $ Generosity <dbl> 0.142, 0.204, 0.258, 0.221, 0.153, 0.24…
## $ `Perceptions of corruption` <dbl> 0.546, 0.548, 0.182, 0.524, 0.193, 0.37…
## $ `Dystopia + residual` <dbl> 2.082, 1.881, 2.050, 1.658, 2.298, 1.90…
head(happiness)
## # A tibble: 6 × 11
## `Country name` `Ladder score` upperwhisker lowerwhisker `Log GDP per capita`
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Finland 7.74 7.82 7.67 1.84
## 2 Denmark 7.58 7.66 7.5 1.91
## 3 Iceland 7.52 7.62 7.43 1.88
## 4 Sweden 7.34 7.42 7.27 1.88
## 5 Israel 7.34 7.40 7.28 1.80
## 6 Netherlands 7.32 7.38 7.26 1.90
## # ℹ 6 more variables: `Social support` <dbl>, `Healthy life expectancy` <dbl>,
## # `Freedom to make life choices` <dbl>, Generosity <dbl>,
## # `Perceptions of corruption` <dbl>, `Dystopia + residual` <dbl>
summary(happiness)
## Country name Ladder score upperwhisker lowerwhisker
## Length:143 Min. :1.721 Min. :1.775 Min. :1.667
## Class :character 1st Qu.:4.726 1st Qu.:4.846 1st Qu.:4.606
## Mode :character Median :5.785 Median :5.895 Median :5.674
## Mean :5.528 Mean :5.641 Mean :5.414
## 3rd Qu.:6.416 3rd Qu.:6.508 3rd Qu.:6.319
## Max. :7.741 Max. :7.815 Max. :7.667
##
## Log GDP per capita Social support Healthy life expectancy
## Min. :0.000 Min. :0.0000 Min. :0.0000
## 1st Qu.:1.078 1st Qu.:0.9217 1st Qu.:0.3980
## Median :1.431 Median :1.2375 Median :0.5495
## Mean :1.379 Mean :1.1343 Mean :0.5209
## 3rd Qu.:1.742 3rd Qu.:1.3833 3rd Qu.:0.6485
## Max. :2.141 Max. :1.6170 Max. :0.8570
## NA's :3 NA's :3 NA's :3
## Freedom to make life choices Generosity Perceptions of corruption
## Min. :0.0000 Min. :0.0000 Min. :0.00000
## 1st Qu.:0.5275 1st Qu.:0.0910 1st Qu.:0.06875
## Median :0.6410 Median :0.1365 Median :0.12050
## Mean :0.6206 Mean :0.1463 Mean :0.15412
## 3rd Qu.:0.7360 3rd Qu.:0.1925 3rd Qu.:0.19375
## Max. :0.8630 Max. :0.4010 Max. :0.57500
## NA's :3 NA's :3 NA's :3
## Dystopia + residual
## Min. :-0.073
## 1st Qu.: 1.308
## Median : 1.645
## Mean : 1.576
## 3rd Qu.: 1.882
## Max. : 2.998
## NA's :3
colSums(is.na(happiness))
## Country name Ladder score
## 0 0
## upperwhisker lowerwhisker
## 0 0
## Log GDP per capita Social support
## 3 3
## Healthy life expectancy Freedom to make life choices
## 3 3
## Generosity Perceptions of corruption
## 3 3
## Dystopia + residual
## 3
happiness <- happiness %>%
rename(
country = `Country name`,
ladder_score = `Ladder score`,
upper_whisker = upperwhisker,
lower_whisker = lowerwhisker,
gdp = `Log GDP per capita`,
social_support = `Social support`,
life_expectancy = `Healthy life expectancy`,
freedom = `Freedom to make life choices`,
generosity = Generosity,
corruption = `Perceptions of corruption`,
dystopia_residual = `Dystopia + residual`
)
glimpse(happiness)
## Rows: 143
## Columns: 11
## $ country <chr> "Finland", "Denmark", "Iceland", "Sweden", "Israel",…
## $ ladder_score <dbl> 7.741, 7.583, 7.525, 7.344, 7.341, 7.319, 7.302, 7.1…
## $ upper_whisker <dbl> 7.815, 7.665, 7.618, 7.422, 7.405, 7.383, 7.389, 7.2…
## $ lower_whisker <dbl> 7.667, 7.500, 7.433, 7.267, 7.277, 7.256, 7.215, 7.0…
## $ gdp <dbl> 1.844, 1.908, 1.881, 1.878, 1.803, 1.901, 1.952, 2.1…
## $ social_support <dbl> 1.572, 1.520, 1.617, 1.501, 1.513, 1.462, 1.517, 1.3…
## $ life_expectancy <dbl> 0.695, 0.699, 0.718, 0.724, 0.740, 0.706, 0.704, 0.7…
## $ freedom <dbl> 0.859, 0.823, 0.819, 0.838, 0.641, 0.725, 0.835, 0.8…
## $ generosity <dbl> 0.142, 0.204, 0.258, 0.221, 0.153, 0.247, 0.224, 0.1…
## $ corruption <dbl> 0.546, 0.548, 0.182, 0.524, 0.193, 0.372, 0.484, 0.4…
## $ dystopia_residual <dbl> 2.082, 1.881, 2.050, 1.658, 2.298, 1.906, 1.586, 1.5…
# Variable Descriptions
variable_descriptions <- tibble(
Variable = colnames(happiness),
Description = c(
"Country name",
"Overall happiness score",
"Upper confidence interval",
"Lower confidence interval",
"Log GDP per capita",
"Social support score",
"Healthy life expectancy score",
"Freedom to make life choices",
"Generosity score",
"Perceived corruption",
"Dystopia + residual component"
)
)
variable_descriptions
## # A tibble: 11 × 2
## Variable Description
## <chr> <chr>
## 1 country Country name
## 2 ladder_score Overall happiness score
## 3 upper_whisker Upper confidence interval
## 4 lower_whisker Lower confidence interval
## 5 gdp Log GDP per capita
## 6 social_support Social support score
## 7 life_expectancy Healthy life expectancy score
## 8 freedom Freedom to make life choices
## 9 generosity Generosity score
## 10 corruption Perceived corruption
## 11 dystopia_residual Dystopia + residual component
# Distribution of Key Variables
happiness %>%
select(ladder_score, gdp, life_expectancy, freedom, generosity, corruption) %>%
pivot_longer(everything()) %>%
ggplot(aes(value)) +
facet_wrap(~name, scales = "free") +
geom_histogram(bins = 25, fill = "steelblue", color = "white") +
labs(
title = "Distributions of Key World Happiness Variables",
x = "Value",
y = "Count"
) +
theme_minimal()

# Outlier Detection Using Boxplots
happiness %>%
select(ladder_score, gdp, life_expectancy, freedom, generosity, corruption) %>%
pivot_longer(everything()) %>%
ggplot(aes(x = name, y = value)) +
geom_boxplot(fill = "tomato", alpha = 0.7) +
coord_flip() +
labs(
title = "Outlier Detection Across Key Variables",
x = "Variable",
y = "Value"
) +
theme_minimal()

# Correlation Heatmap
happiness %>%
select(ladder_score, gdp, life_expectancy, freedom, generosity, corruption) %>%
cor() %>%
as.data.frame() %>%
rownames_to_column("Variable1") %>%
pivot_longer(-Variable1, names_to = "Variable2", values_to = "Correlation") %>%
ggplot(aes(Variable1, Variable2, fill = Correlation)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0) +
labs(
title = "Correlation Heatmap of World Happiness Drivers",
x = "",
y = ""
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Key Insights from Exploratory Data Analysis
cat(" - Happiness (ladder score) follows an approximately normal distribution.
- GDP per capita and healthy life expectancy are the strongest drivers of national happiness.
- Perceived corruption shows a clear negative relationship with happiness.
- Generosity exhibits near-zero correlation with happiness and most other drivers.
- Economic and health factors dominate subjective well-being at the country level.")
## - Happiness (ladder score) follows an approximately normal distribution.
## - GDP per capita and healthy life expectancy are the strongest drivers of national happiness.
## - Perceived corruption shows a clear negative relationship with happiness.
## - Generosity exhibits near-zero correlation with happiness and most other drivers.
## - Economic and health factors dominate subjective well-being at the country level.