Syed Nawaz - S4239096
Last updated: 16 October, 2026
For insurers, policymakers and individuals, medical costs becomes one of the major concerns. Analysing and understanding what drivers expenditure of healthcare that supports with pricing, risk assessment and preventive health strategies. This analysis uses the medical cost personal dataset to analyse and investigate different factors associated with individual medical charges.
Focused key question for this analysis includes,
1. Do smokers have a different mean medical charge than non-smokers?
2. How well do smoking status, age and BMI together explain charges?
The term medical charges focuses on individual medical cost which as billed by the health insurance. BMI (Body Mass Index) is a measure of body weight that is relative to height. Smoking status represents whether the beneficiary is non-smoker or smoker. The rationale is to quantify the financial impact of smoking, risk factor and assess on how well simple linear model in charges.
The selected dataset is collected from Kaggle which is an open dataset “Medical Cost Personal Datasets”. The dataset was compiled for the Machine Learning with R by Brett Lantz. The data has 1338 observations and 7 variables(Choi, 2026).
Used two sample t-test which supports to compare mean charges, though used multiple linear regression model using log transformed charges. This evaluates integrated relationship between medical cost and explanatory variables.
# insurance dataset
insurance_csv_dt <- read.csv("insurance.csv", stringsAsFactors = TRUE)
dim(insurance_csv_dt)## [1] 1338 7
## age sex bmi children smoker region charges
## 0 0 0 0 0 0 0
## age bmi children charges
## Min. :18.00 Min. :15.96 Min. :0.000 Min. : 1122
## 1st Qu.:27.00 1st Qu.:26.29 1st Qu.:0.000 1st Qu.: 4746
## Median :39.00 Median :30.40 Median :1.000 Median : 9386
## Mean :39.22 Mean :30.66 Mean :1.096 Mean :13279
## 3rd Qu.:51.00 3rd Qu.:34.70 3rd Qu.:2.000 3rd Qu.:16658
## Max. :64.00 Max. :53.13 Max. :5.000 Max. :63770
# Medical charges basedon smoker
ggplot(insurance_csv_dt, aes(x = charges)) +
geom_histogram(bins = 30, fill = "steelblue", colour = "white") +
facet_wrap(~ smoker, labeller = label_both, scales = "free_y") +
labs(x = "Medical charges", y = "Count") +
theme_minimal()ggplot(insurance_csv_dt, aes(x = smoker, y = charges, fill = smoker)) +
geom_boxplot(show.legend = FALSE) +
labs(x = "Smoker", y = "Medical charges") +
theme_minimal()# charges based on ages
ggplot(insurance_csv_dt, aes(age, charges, colour = smoker)) +
geom_point(alpha = .5) + theme_minimal() + labs(x = "Age", y = "Charges")# charges based on BMI
ggplot(insurance_csv_dt, aes(bmi, charges, colour = smoker)) +
geom_point(alpha = .5) + theme_minimal() + labs(x = "BMI", y = "Charges")# descriptive statistics
insurance_csv_dt %>%
group_by(smoker) %>%
summarise(n = n(),Min = min(charges),Q1 = quantile(charges, .25),
Median = median(charges),
Q3 = quantile(charges, .75),
Max = max(charges),
Mean = mean(charges),
SD = sd(charges)) -> table1
kable(table1, digits = 0)| smoker | n | Min | Q1 | Median | Q3 | Max | Mean | SD |
|---|---|---|---|---|---|---|---|---|
| no | 1063 | 1122 | 3989 | 7346 | 11363 | 36911 | 8441 | 5993 |
| yes | 274 | 12829 | 20826 | 34456 | 41019 | 63770 | 32050 | 11542 |
# mean charges based on regions
insurance_csv_dt %>%
group_by(region, smoker) %>%
summarise(mean_charges = mean(charges), .groups = "drop") %>%
ggplot(aes(x = region, y = mean_charges, fill = smoker)) +
geom_col(position = "dodge") +
labs(x = "Region", y = "Mean charges") +
theme_minimal()# charges by BMI category and smoking status
insurance_csv_dt %>%
mutate(bmi_group = cut(bmi, breaks = c(0, 18.5, 25, 30, Inf),
labels = c("Underweight", "Normal", "Overweight", "Obese"),
right = FALSE)) %>%
ggplot(aes(x = bmi_group, y = charges, fill = smoker)) +
geom_boxplot() +
labs(x = "BMI category", y = "Charges") +
theme_minimal()par(mfrow = c(1, 2))
for (g in c("no", "yes")) {
x <- insurance_csv_dt$charges[insurance_csv_dt$smoker == g]
qqnorm(x, main = paste("Smoker:", g)); qqline(x)
}smk <- insurance_csv_dt$charges[insurance_csv_dt$smoker == "yes"]
non_smk <- insurance_csv_dt$charges[insurance_csv_dt$smoker == "no"]
tt_results <- t.test(smk, non_smk, alternative = "two.sided", conf.level = 0.95)
tt_results##
## Welch Two Sample t-test
##
## data: smk and non_smk
## t = 32.742, df = 311.88, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 22190.79 25028.35
## sample estimates:
## mean of x mean of y
## 32050.23 8440.66
## [1] 6.784987e-234
The log transformation has been used where fitted plot vs residual represents roughly constant variance, and Q-Q plot shows normality and scale location plot has no strong pattern. All three predictors significant statistically. The model obtained 74.4% of variations. The charge per unit increase age increases by about 3.6, BMI increase by 1.1 and smokeryes increase charge by 368.9(Datanovia, 2026).
##
## Call:
## lm(formula = log(charges) ~ age + bmi + smoker, data = insurance_csv_dt)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.22166 -0.21732 -0.03983 0.10344 2.07125
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.0761244 0.0715858 98.85 < 2e-16 ***
## age 0.0350930 0.0009117 38.49 < 2e-16 ***
## bmi 0.0107853 0.0020982 5.14 3.15e-07 ***
## smokeryes 1.5451927 0.0315190 49.02 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.465 on 1333 degrees of freedom
## Multiple R-squared: 0.7443, Adjusted R-squared: 0.7438
## F-statistic: 1294 on 3 and 1333 DF, p-value: < 2.2e-16
## age bmi smokeryes
## 3.6 1.1 368.9
The strength of dataset is reproducible and open, the analysis uses required transformation and assumptions and the sample size is large.
There is a unknown sampling method so generalisation is limited. Missing variables includes exercise, diet and pre-existing conditions.
Future direction may focus in additional variables like lifestyle and health and use of more advanced models and better interaction.
Smoking is connected with intensely higher medical charges. The take home message is that smoking is most significant predictor of high medical charges, there is a increasing cost around 370% compared to non-smokers.