1. loading the dataset

dataset_thyroid_cancer <- read_csv("C:/Users/Local_123/OneDrive/Desktop/project _1 482/dataset thyroid cancer.csv")
## Rows: 212691 Columns: 17
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (11): Gender, Country, Ethnicity, Family_History, Radiation_Exposure, Io...
## dbl  (6): Patient_ID, Age, TSH_Level, T3_Level, T4_Level, Nodule_Size
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
View(dataset_thyroid_cancer)

there are 212691 rows and 17 columns in the dataset

2 Exploratory data Analysis

creating replica of dataset

data=dataset_thyroid_cancer 
View(data)

1. Checking Dataset Structure

str(data)
## spc_tbl_ [212,691 × 17] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ Patient_ID         : num [1:212691] 1 2 3 4 5 6 7 8 9 10 ...
##  $ Age                : num [1:212691] 66 29 86 75 35 89 89 38 17 36 ...
##  $ Gender             : chr [1:212691] "Male" "Male" "Male" "Female" ...
##  $ Country            : chr [1:212691] "Russia" "Germany" "Nigeria" "India" ...
##  $ Ethnicity          : chr [1:212691] "Caucasian" "Hispanic" "Caucasian" "Asian" ...
##  $ Family_History     : chr [1:212691] "No" "No" "No" "No" ...
##  $ Radiation_Exposure : chr [1:212691] "Yes" "Yes" "No" "No" ...
##  $ Iodine_Deficiency  : chr [1:212691] "No" "No" "No" "No" ...
##  $ Smoking            : chr [1:212691] "No" "No" "No" "No" ...
##  $ Obesity            : chr [1:212691] "No" "No" "No" "No" ...
##  $ Diabetes           : chr [1:212691] "No" "No" "No" "No" ...
##  $ TSH_Level          : num [1:212691] 9.37 1.83 6.26 4.1 9.1 4 4.7 5.54 2.3 1.34 ...
##  $ T3_Level           : num [1:212691] 1.67 1.73 2.59 2.62 2.11 0.98 0.62 3.49 2.6 0.56 ...
##  $ T4_Level           : num [1:212691] 6.16 10.54 10.57 11.04 10.71 ...
##  $ Nodule_Size        : num [1:212691] 1.08 4.05 4.61 2.46 2.11 0.02 0.01 4.3 0.81 1.44 ...
##  $ Thyroid_Cancer_Risk: chr [1:212691] "Low" "Low" "Low" "Medium" ...
##  $ Diagnosis          : chr [1:212691] "Benign" "Benign" "Benign" "Benign" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   Patient_ID = col_double(),
##   ..   Age = col_double(),
##   ..   Gender = col_character(),
##   ..   Country = col_character(),
##   ..   Ethnicity = col_character(),
##   ..   Family_History = col_character(),
##   ..   Radiation_Exposure = col_character(),
##   ..   Iodine_Deficiency = col_character(),
##   ..   Smoking = col_character(),
##   ..   Obesity = col_character(),
##   ..   Diabetes = col_character(),
##   ..   TSH_Level = col_double(),
##   ..   T3_Level = col_double(),
##   ..   T4_Level = col_double(),
##   ..   Nodule_Size = col_double(),
##   ..   Thyroid_Cancer_Risk = col_character(),
##   ..   Diagnosis = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>
class(data)
## [1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame"

• The dataset consists of 17 variables, including numeric (num), character (chr), and categorical data. Below is an interpretation of each column:

• Numeric Variables (num): Age, TSH_Level, T3_Level, T4_Level, Nodule_Size.

• Categorical Variables (chr): Gender, Country, Ethnicity, Risk Factors (like Smoking, Obesity), and Diagnosis.

• Several risk factors (e.g., Radiation_Exposure, Iodine_Deficiency, Smoking) are stored as “Yes”/“No”.

2. Checking for Missing Values

sum(is.na(data))
## [1] 0
colSums(is.na(data))
##          Patient_ID                 Age              Gender             Country 
##                   0                   0                   0                   0 
##           Ethnicity      Family_History  Radiation_Exposure   Iodine_Deficiency 
##                   0                   0                   0                   0 
##             Smoking             Obesity            Diabetes           TSH_Level 
##                   0                   0                   0                   0 
##            T3_Level            T4_Level         Nodule_Size Thyroid_Cancer_Risk 
##                   0                   0                   0                   0 
##           Diagnosis 
##                   0

• The result shows 0 missing values for every column in the dataset. • This indicates that there are no missing (NA) values in any column, meaning the dataset is complete and clean in terms of missing data.

3. Basic Discriptive Statics

summary(data)
##    Patient_ID          Age           Gender            Country         
##  Min.   :     1   Min.   :15.00   Length:212691      Length:212691     
##  1st Qu.: 53174   1st Qu.:33.00   Class :character   Class :character  
##  Median :106346   Median :52.00   Mode  :character   Mode  :character  
##  Mean   :106346   Mean   :51.92                                        
##  3rd Qu.:159519   3rd Qu.:71.00                                        
##  Max.   :212691   Max.   :89.00                                        
##   Ethnicity         Family_History     Radiation_Exposure Iodine_Deficiency 
##  Length:212691      Length:212691      Length:212691      Length:212691     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##    Smoking            Obesity            Diabetes           TSH_Level     
##  Length:212691      Length:212691      Length:212691      Min.   : 0.100  
##  Class :character   Class :character   Class :character   1st Qu.: 2.570  
##  Mode  :character   Mode  :character   Mode  :character   Median : 5.040  
##                                                           Mean   : 5.045  
##                                                           3rd Qu.: 7.520  
##                                                           Max.   :10.000  
##     T3_Level        T4_Level       Nodule_Size    Thyroid_Cancer_Risk
##  Min.   :0.500   Min.   : 4.500   Min.   :0.000   Length:212691      
##  1st Qu.:1.250   1st Qu.: 6.370   1st Qu.:1.250   Class :character   
##  Median :2.000   Median : 8.240   Median :2.510   Mode  :character   
##  Mean   :2.002   Mean   : 8.246   Mean   :2.503                      
##  3rd Qu.:2.750   3rd Qu.:10.120   3rd Qu.:3.760                      
##  Max.   :3.500   Max.   :12.000   Max.   :5.000                      
##   Diagnosis        
##  Length:212691     
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

The dataset contains information for 212,691 patients.

Age ranges from 15 to 89 years, with an average age of 51.92 years.

Variables like Gender, Country, Ethnicity, Family History, Radiation Exposure, Iodine Deficiency, Smoking, Obesity, Diabetes, Thyroid Cancer Risk, and Diagnosis are stored as characters (text), meaning they contain categories rather than numerical values.

o The most common category (mode) for each of these is not displayed, but we can assume that some values occur more frequently.

Thyroid-Related Medical Indicators:

TSH Level (Thyroid-Stimulating Hormone):

Ranges from 0.1 to 10.0. The median value (middle value) is 5.04, which suggests that half of the patients have a TSH level below this and half above. The mean (average) is 5.045, which is very close to the median, indicating a relatively balanced distribution.

T3 Level (Triiodothyronine):

Ranges from 0.5 to 3.5. The median value is 2.002, and the mean is 2.002, suggesting a symmetrical distribution.

T4 Level (Thyroxine):

Ranges from 4.5 to 12.0. he median is 8.246, and the mean is also 8.246, again showing balance in distribution.

Nodule Size:

Ranges from 0.0 to 5.0. The median is 2.51, meaning half of the patients have nodules smaller than this, and half have larger.

Level 2: Data Extraction & Filtering

4 .How many patients are older than 50 years?

nrow(filter(data, Age > 50)) 
## [1] 110269
nrow(filter(data, Age > 50 &Family_History =="Yes"))
## [1] 33220
nrow(filter(data, Age > 50 &Family_History =="No"))
## [1] 77049

5. How many patients are younger than 30 and have a family history of thyroid cancer?

nrow(filter(data, Age < 30 & Family_History == "Yes"))
## [1] 12644
nrow(filter(data, Age < 30 & Family_History == "No"))
## [1] 30013

• Thyroid issues increase with age → More cases are seen in patients above 50 than in younger ones.

• Family history plays a role, but not the biggest factor → More older patients (77,049) have no family history, meaning other risk factors contribute more.

• Younger patients mostly have no family history → But a significant portion (12,644) do, meaning genetic risks start early for some individuals.

6. Distribution of Thyroid Cancer Cases by Gender

table(data$Gender)
## 
## Female   Male 
## 127527  85164

• The dataset has significantly more female patients (127,527) than males (85,164).

7.Average Age of Cancer Patients vs. Non-Patients

gender_age <- data %>%
  group_by(Diagnosis, Gender) %>%
  summarise(Average_Age = mean(Age, na.rm = TRUE)) %>%
  arrange(desc(Average_Age))
## `summarise()` has grouped output by 'Diagnosis'. You can override using the
## `.groups` argument.
print("Average Age by Gender for Benign and Malignant Cases:")
## [1] "Average Age by Gender for Benign and Malignant Cases:"
print(gender_age)
## # A tibble: 4 × 3
## # Groups:   Diagnosis [2]
##   Diagnosis Gender Average_Age
##   <chr>     <chr>        <dbl>
## 1 Malignant Male          52.0
## 2 Benign    Female        51.9
## 3 Malignant Female        51.9
## 4 Benign    Male          51.9

• Age Similarity: The average ages across all four groups (Benign Male, Benign Female, Malignant Male, Malignant Female) are remarkably similar, all falling around 51.9 to 52 years old.

8. Finding the Country with the Highest Cases for Each Diagnosis

country_cases <- data %>%
  group_by(Diagnosis, Country) %>%
  summarise(Count = n()) %>%
  arrange(Diagnosis, desc(Count))
## `summarise()` has grouped output by 'Diagnosis'. You can override using the
## `.groups` argument.
print("Country with the Highest Cases for Each Diagnosis:")
## [1] "Country with the Highest Cases for Each Diagnosis:"
print(country_cases)
## # A tibble: 20 × 3
## # Groups:   Diagnosis [2]
##    Diagnosis Country     Count
##    <chr>     <chr>       <int>
##  1 Benign    India       28520
##  2 Benign    China       25280
##  3 Benign    Nigeria     25206
##  4 Benign    Brazil      16934
##  5 Benign    Russia      16790
##  6 Benign    Japan       13388
##  7 Benign    South Korea 11882
##  8 Benign    USA          8439
##  9 Benign    UK           8417
## 10 Benign    Germany      8340
## 11 Malignant India       13976
## 12 Malignant Nigeria      6712
## 13 Malignant China        6698
## 14 Malignant Russia       4507
## 15 Malignant Brazil       4479
## 16 Malignant Japan        3479
## 17 Malignant South Korea  3083
## 18 Malignant UK           2225
## 19 Malignant Germany      2217
## 20 Malignant USA          2119

• India Dominates: India stands out with the highest number of both benign and malignant thyroid cancer cases.

• High Benign Case Counts: The count of benign cases is generally higher than the count of malignant cases across all countries. This is consistent with the understanding that benign thyroid conditions are more common than malignant ones.

• Similar Patterns: The countries with high benign case counts also tend to have high malignant case counts. This suggests that factors influencing benign conditions might also contribute to malignant conditions in these regions.

Level 3: Grouping & Summarization

9 .Average Hormone Levels in Cancer vs. Non-Cancer Patients

factor_comparison <- data %>%
  group_by(Diagnosis) %>%
  summarise(
    Avg_TSH = mean(TSH_Level, na.rm = TRUE),
    Avg_T3 = mean(T3_Level, na.rm = TRUE),
    Avg_T4 = mean(T4_Level, na.rm = TRUE),
    Avg_Nodule_Size = mean(Nodule_Size, na.rm = TRUE)
  )

print("Comparison of Factors (TSH, T3, T4, Nodule Size) for Benign vs Malignant:")
## [1] "Comparison of Factors (TSH, T3, T4, Nodule Size) for Benign vs Malignant:"
print(factor_comparison)
## # A tibble: 2 × 5
##   Diagnosis Avg_TSH Avg_T3 Avg_T4 Avg_Nodule_Size
##   <chr>       <dbl>  <dbl>  <dbl>           <dbl>
## 1 Benign       5.05   2.00   8.24            2.51
## 2 Malignant    5.03   2.00   8.25            2.50

o There is no significant difference in TSH levels,T4 levels ,Avg_nodule size between benign and malignant cases.

10.Percentage of other risk factors in cancerous and non -cancers

risk_factors <- data %>%
  group_by(Diagnosis) %>%
  summarise(
    Radiation_Exposure = sum(Radiation_Exposure == "Yes") / n() * 100,
    Iodine_Deficiency = sum(Iodine_Deficiency == "Yes") / n() * 100,
    Smoking = sum(Smoking == "Yes") / n() * 100,
    Obesity = sum(Obesity == "Yes") / n() * 100
  )

print(risk_factors)
## # A tibble: 2 × 5
##   Diagnosis Radiation_Exposure Iodine_Deficiency Smoking Obesity
##   <chr>                  <dbl>             <dbl>   <dbl>   <dbl>
## 1 Benign                  13.2              22.6    19.9    30.1
## 2 Malignant               20.7              32.7    20.0    29.9

• Radiation Exposure is much higher in malignant cases (20.7% vs. 13.2%)

• Iodine Deficiency is significantly higher in malignant cases (32.7% vs. 22.6%)

• Smoking has no major difference (19.9% vs. 20.0%)

• Obesity is almost equal in both groups (30.1% vs. 29.9%)

11.Compare Gender & Age Distribution for High-Risk Cases

data %>% 
  filter(Thyroid_Cancer_Risk == "High") %>% 
  group_by(Gender, Age) %>% 
  summarise(Count = n()) %>% 
  arrange(desc(Count))
## `summarise()` has grouped output by 'Gender'. You can override using the
## `.groups` argument.
## # A tibble: 150 × 3
## # Groups:   Gender [2]
##    Gender   Age Count
##    <chr>  <dbl> <int>
##  1 Female    75   300
##  2 Female    50   290
##  3 Female    26   281
##  4 Female    42   280
##  5 Female    80   279
##  6 Female    36   278
##  7 Female    43   278
##  8 Female    40   274
##  9 Female    76   274
## 10 Female    33   273
## # ℹ 140 more rows

The highest number of high-risk cases is among females.

The top 10 age groups with the highest cases are all female.

The highest number of cases is seen at age 75 (300 cases).

Thyroid cancer risk is prevalent across multiple age groups in females.

The top affected ages include 75, 50, 26, 42, 80, 36, 43, 40, 76, and 33.

This suggests a widespread risk across both younger and older age groups in females.

12 .See which countries have the highest number of radiation-exposed patients.

radiation_by_country <- data %>%
  filter(Radiation_Exposure == "Yes") %>%
  group_by(Country) %>%
  summarise(Count = n()) %>%
  arrange(desc(Count))

print(radiation_by_country)
## # A tibble: 10 × 2
##    Country     Count
##    <chr>       <int>
##  1 India        6295
##  2 China        4924
##  3 Nigeria      4780
##  4 Brazil       3274
##  5 Russia       3167
##  6 Japan        2483
##  7 South Korea  2259
##  8 UK           1600
##  9 Germany      1539
## 10 USA          1539

• India has the highest number of radiation-exposed patients (6,295), followed by China (4,924) and Nigeria (4,780). • Countries like Brazil (3,274), Russia (3,167), and Japan (2,483) also have a significant number of cases. • Developed nations such as the UK (1,600), Germany (1,539), and the USA (1,539) also appear in the list, though with lower counts.

Level 4: Sorting & Ranking

13 .Ranking Risk Factors by Frequency

# Filter High-Risk patients
high_risk_patients <- data %>% filter(Thyroid_Cancer_Risk == "High")

# Select only risk factors
risk_factors <- high_risk_patients %>% 
  select(Smoking, Obesity, Radiation_Exposure, Iodine_Deficiency, Diabetes)

# Calculate % of "Yes" for each risk factor
risk_factor_summary <- sapply(risk_factors, function(x) mean(x == "Yes") * 100)

# Convert to dataframe and sort descending
risk_factor_rank <- data.frame(Risk_Factor = names(risk_factor_summary),
                               Percentage = risk_factor_summary) %>%
  arrange(desc(Percentage))

print(risk_factor_rank)
##                           Risk_Factor Percentage
## Iodine_Deficiency   Iodine_Deficiency   47.19619
## Radiation_Exposure Radiation_Exposure   30.93753
## Obesity                       Obesity   29.69313
## Diabetes                     Diabetes   20.07962
## Smoking                       Smoking   19.96364

Iodine_Deficiency, 47.19619: Iodine deficiency is the most common risk factor, present in approximately 47.2% of the high-risk patients.

Radiation_Exposure, 30.93753: Radiation exposure is the second most common risk factor, affecting about 30.9% of the high-risk patients.

Level 5 : Feature Engineering

1 . Create Age Buckets and Analyze Diagnosis

data <- data %>%
  mutate(Age_Bucket = case_when(
    Age <= 30 ~ "Young",
    Age <= 60 ~ "Middle",
    TRUE ~ "Senior"
  ))

table(data$Age_Bucket, data$Diagnosis)
##         
##          Benign Malignant
##   Middle  65464     19817
##   Senior  62784     19084
##   Young   34948     10594

Most cases (both benign and malignant) occur in the Middle and Senior groups compared to the Young.

Malignant cases are significant even in the Young group (10,594 cases), though fewer than Middle/Senior.

Benign cases are consistently higher than malignant across all age groups.

2. Create Lifestyle Risk Score (0-5)

data <- data %>%
  mutate(Risk_Score = (Smoking == "Yes") + (Obesity == "Yes") + (Radiation_Exposure == "Yes") + 
                         (Iodine_Deficiency == "Yes") + (Diabetes == "Yes"))

# Check
head(data[, c("Smoking", "Obesity", "Radiation_Exposure", "Iodine_Deficiency", "Diabetes", "Risk_Score")])
## # A tibble: 6 × 6
##   Smoking Obesity Radiation_Exposure Iodine_Deficiency Diabetes Risk_Score
##   <chr>   <chr>   <chr>              <chr>             <chr>         <int>
## 1 No      No      Yes                No                No                1
## 2 No      No      Yes                No                No                1
## 3 No      No      No                 No                No                0
## 4 No      No      No                 No                No                0
## 5 No      No      Yes                No                No                1
## 6 Yes     Yes     No                 No                No                2

analyze if Risk_Score correlates with malignant diagnosis

# Step 1: Summarize malignant and benign counts per Risk_Score
risk_analysis <- data %>%
  group_by(Risk_Score) %>%
  summarise(
    Benign = sum(Diagnosis == "Benign"),
    Malignant = sum(Diagnosis == "Malignant"),
    Total = n()
  ) %>%
  mutate(
    Malignancy_Rate = Malignant / Total
  )

# Step 2: View the summarized table
print(risk_analysis)
## # A tibble: 6 × 5
##   Risk_Score Benign Malignant Total Malignancy_Rate
##        <int>  <int>     <int> <int>           <dbl>
## 1          0  49093     11636 60729           0.192
## 2          1  67414     20192 87606           0.230
## 3          2  35982     12936 48918           0.264
## 4          3   9457      4048 13505           0.300
## 5          4   1186       648  1834           0.353
## 6          5     64        35    99           0.354
# Step 3: Plot Risk_Score vs Malignancy Rate
ggplot(risk_analysis, aes(x = Risk_Score, y = Malignancy_Rate)) +
  geom_line(group = 1, color = "blue", size = 1) +
  geom_point(color = "red", size = 3) +
  labs(
    title = "Malignancy Rate vs Lifestyle Risk Score",
    x = "Risk Score",
    y = "Malignancy Rate"
  ) +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Positive Trend: As Risk Score increases, the Malignancy Rate also increases.

Patients with 0 risk factors have a malignancy rate around 19%.

Patients with 5 risk factors have a malignancy rate around 36%.

Sharp Rise after Score 3:

From Risk Score 3 to 5, the malignancy rate jumps sharply.

This suggests that when multiple risk factors are present, the cancer risk becomes much higher.

Plateau at High Risk Score:

From Risk Score 4 to 5, the line flattens, meaning malignancy risk stops increasing much after a very high risk score.

It might be because very few people have all 5 risk factors, so sample size becomes small.

3.Calculating Percentage of High-Risk Individuals

high_risk_count <- sum(data$Thyroid_Cancer_Risk == "High", na.rm = TRUE)
total_patients <- nrow(data)
high_risk_percentage <- (high_risk_count / total_patients) * 100

print(paste("Percentage of High-Risk Individuals:", round(high_risk_percentage, 2), "%"))
## [1] "Percentage of High-Risk Individuals: 15 %"

• A 15% high-risk rate indicates a significant minority of the population is at serious risk and may require urgent diagnosis, monitoring, or intervention.

6 visualization

1. Visualize the distribution of TSH, T3, and T4 levels using histograms

# TSH_Level
ggplot(data, aes(x = TSH_Level)) + 
  geom_histogram(binwidth = 0.5, fill = "skyblue", color = "black") +
  labs(title = "Distribution of TSH Levels", x = "TSH Level", y = "Count")

# T3_Level
ggplot(data, aes(x = T3_Level)) + 
  geom_histogram(binwidth = 0.1, fill = "lightgreen", color = "black") +
  labs(title = "Distribution of T3 Levels", x = "T3 Level", y = "Count")

# T4_Level
ggplot(data, aes(x = T4_Level)) + 
  geom_histogram(binwidth = 0.5, fill = "orange", color = "black") +
  labs(title = "Distribution of T4 Levels", x = "T4 Level", y = "Count")

he histogram shows a relatively uniform distribution of TSH levels across the majority of the range, from approximately 0.5 to 9.5.

2 Create a barplot showing Gender distribution across Diagnosis

ggplot(data, aes(x = Gender, fill = Diagnosis)) +
  geom_bar(position = "dodge") +
  labs(title = "Gender vs Diagnosis Distribution", x = "Gender", y = "Count")

Females have a much higher number of thyroid cancer cases overall (Benign + Malignant) compared to males.

Among both genders, Benign cases are more common than Malignant cases.

The difference between Benign and Malignant cases is bigger in females than in males.

Males have lower total numbers, but relatively a bit higher proportion of malignancy compared to females.

3 Boxplot of Nodule Size for Benign vs Malignant cases

ggplot(data, aes(x = Diagnosis, y = Nodule_Size, fill = Diagnosis)) +
  geom_boxplot() +
  labs(title = "Nodule Size in Benign vs Malignant Cases", x = "Diagnosis", y = "Nodule Size")

The median (thick line inside the box) for both is almost the same — around 2.5.

Nodule Size alone may not be a strong differentiator between Benign and Malignant nodules in this dataset.

4 Check correlation between Age, TSH, T3, T4, and Nodule Size

library(corrplot)
## Warning: package 'corrplot' was built under R version 4.4.3
## corrplot 0.95 loaded
numeric_data <- data[, c("Age", "TSH_Level", "T3_Level", "T4_Level", "Nodule_Size")]
cor_matrix <- cor(numeric_data, use = "complete.obs")
corrplot(cor_matrix, method = "number", type = "lower")

T3_Level and T4_Level have strong positive correlation

(They move together: when T3 is high, T4 is high. Medically correct.)

all other pairs (like Age, TSH, Nodule Size) show:

–Very weak correlation (r very close to 0).

–No strong linear relationship between them.

5. Perform simple linear regression: Predict TSH level based on Age

model1 <- lm(TSH_Level ~ Age, data = data)
summary(model1)
## 
## Call:
## lm(formula = TSH_Level ~ Age, data = data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -4.9496 -2.4775 -0.0041  2.4794  4.9594 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  5.0514490  0.0161252 313.265   <2e-16 ***
## Age         -0.0001222  0.0002867  -0.426     0.67    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.86 on 212689 degrees of freedom
## Multiple R-squared:  8.549e-07,  Adjusted R-squared:  -3.847e-06 
## F-statistic: 0.1818 on 1 and 212689 DF,  p-value: 0.6698
plot(data$Age, data$TSH_Level, pch=20, main="TSH vs Age")
abline(model1, col="red")

The scatter plot shows that the TSH Level values are very densely packed vertically — almost forming vertical lines at each age value.

The red regression line is almost flat, indicating that TSH Level doesn’t change much with Age.

No strong visible trend — TSH Levels seem almost randomly distributed across different ages.

6 Perform multiple linear regression: Predict Nodule Size based on Age, TSH, T3, T4

model2 <- lm(Nodule_Size ~ Age + TSH_Level + T3_Level + T4_Level, data = data)
summary(model2)
## 
## Call:
## lm(formula = Nodule_Size ~ Age + TSH_Level + T3_Level + T4_Level, 
##     data = data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.51396 -1.25221  0.00957  1.25170  2.50726 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.524e+00  1.712e-02 147.417   <2e-16 ***
## Age         -9.981e-05  1.448e-04  -0.689    0.491    
## TSH_Level    2.088e-04  1.095e-03   0.191    0.849    
## T3_Level    -3.015e-03  3.616e-03  -0.834    0.404    
## T4_Level    -1.248e-03  1.447e-03  -0.863    0.388    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.445 on 212686 degrees of freedom
## Multiple R-squared:  9.128e-06,  Adjusted R-squared:  -9.679e-06 
## F-statistic: 0.4853 on 4 and 212686 DF,  p-value: 0.7465

The predictors (Age, TSH, T3, and T4 levels) do not have a significant relationship with Nodule Size in this dataset.

7 Find top 5 countries with maximum malignant cases and plot them

top_countries <- data %>%
  filter(Diagnosis == "Malignant") %>%
  group_by(Country) %>%
  summarise(Count = n()) %>%
  arrange(desc(Count)) %>%
  head(5)

ggplot(top_countries, aes(x = reorder(Country, -Count), y = Count, fill = Country)) +
  geom_bar(stat = "identity") +
  labs(title = "Top 5 Countries with Malignant Cases", x = "Country", y = "Cases")

The bar chart shows that India reports the highest number of malignant thyroid cancer cases among the top five countries. Nigeria and China follow, each having a comparable number of cases, while Russia and Brazil have lower but still notable malignant case counts.

8 Perform ANOVA: Test if Nodule Size differs significantly among Risk Groups (Low, Medium, High)

anova_result <- aov(Nodule_Size ~ Thyroid_Cancer_Risk, data = data)
summary(anova_result)
##                         Df Sum Sq Mean Sq F value Pr(>F)
## Thyroid_Cancer_Risk      2      0  0.1713   0.082  0.921
## Residuals           212688 443875  2.0870

the p-value is 0.921, which is much greater than 0.05. Therefore, you fail to reject the null hypothesis. This means there is no statistically significant difference in Nodule Size among patients classified as Low, Medium, and High Risk.

9 Compare mean Age across Gender using Boxplot

ggplot(data, aes(x = Gender, y = Age, fill = Gender)) +
  geom_boxplot() +
  labs(title = "Age Distribution by Gender", x = "Gender", y = "Age")

The median age (thick black line inside each box) is almost identical for both genders — slightly above 50 years.

The interquartile range (IQR) (the range of the box from Q1 to Q3) is quite similar for both males and females.

The spread (range from minimum to maximum age) also appears similar between males and females.

No extreme outliers are visible.

There is no major difference in the age distribution between male and female patients in this thyroid cancer dataset.

Both genders have a fairly similar age range and central tendency.

11 Trend of High Risk cases across Age through grouped bar chart

# Step 1: Create Age Groups (binning ages)
data <- data %>%
  mutate(Age_Group = case_when(
    Age <= 30 ~ "15-30",
    Age <= 50 ~ "31-50",
    Age <= 70 ~ "51-70",
    TRUE ~ "71+"
  ))

# Step 2: Filter only High-Risk patients and group by Age Group
high_risk_grouped <- data %>%
  filter(Thyroid_Cancer_Risk == "High") %>%
  group_by(Age_Group) %>%
  summarise(High_Risk_Count = n()) %>%
  arrange(Age_Group)  # Sort Age Groups properly

# Step 3: Plot Grouped Bar Chart
ggplot(high_risk_grouped, aes(x = Age_Group, y = High_Risk_Count, fill = Age_Group)) +
  geom_bar(stat = "identity", width = 0.7) +
  labs(title = "High-Risk Thyroid Cancer Cases Across Age Groups",
       x = "Age Group",
       y = "Number of High-Risk Cases") +
  theme_minimal() +
  theme(legend.position = "none") +
  geom_text(aes(label = High_Risk_Count), vjust = -0.5)  # Add count labels on bars

The grouped bar chart indicates that the maximum number of high-risk thyroid cancer cases is observed in the 31–50 year age group, followed closely by the 51–70 and 71+ age groups. Young adults aged 15–30 years show relatively fewer high-risk cases. These results suggest that thyroid cancer risk intensifies with age, particularly affecting middle-aged and elderly individuals. However, the presence of a notable number of high-risk cases even among young adults highlights the need for early screening and preventive measures across all age groups.

12. Create a pie chart showing proportion of High, Medium, and Low Risk

risk_counts <- table(data$Thyroid_Cancer_Risk)
pie(risk_counts, main = "Thyroid Cancer Risk Distribution", col = rainbow(length(risk_counts)))

The pie chart shows that a majority of the patients in the dataset are categorized as Low Risk for thyroid cancer. Medium Risk patients make up a moderate proportion, while High Risk patients constitute the smallest group. This suggests that although most individuals are at a lower risk, there remains a significant minority requiring close medical monitoring and intervention.

13. Diagnosis Distribution by Iodine Deficiency

ggplot(data, aes(x = Iodine_Deficiency, fill = Diagnosis)) +
  geom_bar(position = "fill") +   
  labs(
    title = "Proportion of Malignant vs Benign by Iodine Deficiency",
    x = "Iodine Deficiency",
    y = "Proportion"
  ) +
  scale_y_continuous(labels = scales::percent) +
  theme_minimal()

Iodine deficiency is associated with a higher risk of having malignant thyroid cancer. Patients who have iodine deficiency show a higher proportion of malignancy compared to patients who don’t.

implementing Logistic Regression on the previous question

# Convert Diagnosis to binary (1=Malignant, 0=Benign)
data$Diagnosis_binary <- ifelse(data$Diagnosis == "Malignant", 1, 0)

# Fit logistic regression model
model_iodine <- glm(Diagnosis_binary ~ Iodine_Deficiency, data = data, family = "binomial")

# Model Summary
summary(model_iodine)
## 
## Call:
## glm(formula = Diagnosis_binary ~ Iodine_Deficiency, family = "binomial", 
##     data = data)
## 
## Coefficients:
##                       Estimate Std. Error z value Pr(>|z|)    
## (Intercept)          -1.333415   0.006159  -216.5   <2e-16 ***
## Iodine_DeficiencyYes  0.511372   0.011263    45.4   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 230782  on 212690  degrees of freedom
## Residual deviance: 228779  on 212689  degrees of freedom
## AIC: 228783
## 
## Number of Fisher Scoring iterations: 4

“Patients who have Iodine Deficiency are 1.67 times more likely to have Malignant thyroid cancer compared to those without iodine deficiency, and the relationship is highly statistically significant (p < 0.001).”

From the proportion plot, it is observed that patients with iodine deficiency have a significantly higher proportion of malignant thyroid cancer compared to patients without iodine deficiency. In contrast, patients without iodine deficiency have a majority of benign cases. This visual finding aligns with the logistic regression output, confirming that iodine deficiency is an important risk factor for thyroid malignancy.

14 Among High-Risk individuals, which risk factors (Smoking, Radiation Exposure, Obesity, Diabetes, Iodine Deficiency) are most common compared to Low-Risk individuals?

# Select High-Risk and Low-Risk individuals
high_risk <- data %>% filter(Thyroid_Cancer_Risk == "High")
low_risk <- data %>% filter(Thyroid_Cancer_Risk == "Low")

# Calculate percentage of each factor in High Risk
high_risk_factors <- colMeans(high_risk[, c("Smoking", "Obesity", "Radiation_Exposure", "Diabetes", "Iodine_Deficiency")] == "Yes") * 100

# Calculate percentage of each factor in Low Risk
low_risk_factors <- colMeans(low_risk[, c("Smoking", "Obesity", "Radiation_Exposure", "Diabetes", "Iodine_Deficiency")] == "Yes") * 100

# Combine into one dataframe
risk_compare <- data.frame(
  Factor = names(high_risk_factors),
  High_Risk_Percent = high_risk_factors,
  Low_Risk_Percent = low_risk_factors
)

print(risk_compare)
##                                Factor High_Risk_Percent Low_Risk_Percent
## Smoking                       Smoking          19.96364         20.04834
## Obesity                       Obesity          29.69313         30.09743
## Radiation_Exposure Radiation_Exposure          30.93753         12.19415
## Diabetes                     Diabetes          20.07962         20.10001
## Iodine_Deficiency   Iodine_Deficiency          47.19619         20.99679
library(tidyr)


# Pivot data for ggplot
risk_compare_melt <- pivot_longer(risk_compare, 
                                  cols = -Factor, 
                                  names_to = "variable", 
                                  values_to = "value")

# Plot
ggplot(risk_compare_melt, aes(x = Factor, y = value, fill = variable)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Comparison of Risk Factors in High vs Low Risk Individuals",
       x = "Risk Factors", y = "Percentage (%)") +
  theme_minimal()

Iodine Deficiency and Radiation Exposure are key distinguishing risk factors between high-risk and low-risk individuals.

Obesity, Diabetes, and Smoking do not show significant differences between the two groups in this data.