Section A – Vectors

Problem 1: Recording Volunteer Names

Task: Create a vector with their names and print the first volunteer.

volunteers <- c("Hashem", "Haris", "Mostafa")
volunteers[1]
## [1] "Hashem"

Problem 2: Assigning Patient IDs

Task: Store these IDs in a numeric vector and print them.

patient_ids <- c(1, 2, 3, 4)
print(patient_ids)
## [1] 1 2 3 4

Problem 3: Student Participants in a Workshop

Task: Create a vector of these names and check its class.

students <- c("Maria", "Shirmin", "Alam")
class(students)
## [1] "character"

Problem 4: Extracting Test Results

Task: Store the readings in a vector and extract the last two readings.

bp_readings <- c(120, 132, 138)
bp_readings[2:3]
## [1] 132 138

Problem 5: Labeling Gene Expression

Task: Store the values in a vector, assign the gene names as labels, and extract BRCA1’s value.

gene_expression <- c(230, 120, 450)
names(gene_expression) <- c("TP53", "BRCA1", "MYC")
gene_expression["BRCA1"]
## BRCA1 
##   120

Section B – Matrices

Problem 6: Creating an Expression Matrix

Task: Create a 4x3 matrix using values 1:12 filled row by row.

expr_matrix <- matrix(1:12, nrow = 4, ncol = 3, byrow = TRUE)
expr_matrix
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
## [4,]   10   11   12

Problem 7: Checking Data Structure

Task: Use class() on the matrix from Problem 6 to check.

class(expr_matrix)
## [1] "matrix" "array"

Problem 8: Mixing Data Types

Task: Create a 2x3 matrix mixing text and numbers. Observe what happens.

mixed_matrix <- matrix(c(1, 2, "hello", 4, "hi", "bye"), nrow = 2, ncol = 3, byrow = TRUE)
mixed_matrix
##      [,1] [,2] [,3]   
## [1,] "1"  "2"  "hello"
## [2,] "4"  "hi" "bye"
# here R coerces the numbers into character strings to maintain a single data type
class(mixed_matrix[1,1]) 
## [1] "character"

Problem 9: Combining Patient Results into a Matrix

Task: Create a matrix from these three patient vectors.

Asif <- c(90, 160, 120)
Harun <- c(100, 180, 150)
Afridi <- c(80, 145, 110)
glucose_matrix <- rbind(Asif, Harun, Afridi)
glucose_matrix
##        [,1] [,2] [,3]
## Asif     90  160  120
## Harun   100  180  150
## Afridi   80  145  110

Problem 10: Adding Column Names for Time Points

Task: Assign these labels as column names.

colnames(glucose_matrix) <- c("Baseline", "Treatment1", "Treatment2")
glucose_matrix
##        Baseline Treatment1 Treatment2
## Asif         90        160        120
## Harun       100        180        150
## Afridi       80        145        110

Problem 11: Adding Row Names for Patients

Task: Assign “Asif”, “Harun”, and “Afridi” as row names.

rownames(glucose_matrix) <- c("Asif", "Harun", "Afridi")
glucose_matrix
##        Baseline Treatment1 Treatment2
## Asif         90        160        120
## Harun       100        180        150
## Afridi       80        145        110

Problem 12: Extracting a Specific Value

Task: Extract Asif’s glucose level during “Treatment2” using row and column labels.

glucose_matrix["Asif", "Treatment2"]
## [1] 120

Problem 13: Comparing Two Patients

Task: Extract Asif and Afridi’s glucose levels at “Baseline” and “Treatment2”.

subset_matrix <- glucose_matrix[c("Asif", "Afridi"), c("Baseline", "Treatment2")]
subset_matrix
##        Baseline Treatment2
## Asif         90        120
## Afridi       80        110

Problem 14: Extracting Row Subsets

Task: Extract Harun’s results but only for the first two conditions.

harun_subset <- glucose_matrix["Harun", c("Baseline", "Treatment1")]
harun_subset
##   Baseline Treatment1 
##        100        180

Section C – Data Frames

Problem 16: Building a Patient Data Frame

Task: Create a data frame from the patient attributes.

Name <- c("Tamim", "Imrul", "Fiz")
Age <- c(35, 39, 37)
Mutations <- c(4, 1, 0)
Married <- c(TRUE, TRUE, TRUE)

patient_df <- data.frame(Name, Age, Mutations, Married)
patient_df
##    Name Age Mutations Married
## 1 Tamim  35         4    TRUE
## 2 Imrul  39         1    TRUE
## 3   Fiz  37         0    TRUE

Problem 17: Exploring Data Frame Structure

Task: Use str() and View() to explore the data.

str(patient_df)
## 'data.frame':    3 obs. of  4 variables:
##  $ Name     : chr  "Tamim" "Imrul" "Fiz"
##  $ Age      : num  35 39 37
##  $ Mutations: num  4 1 0
##  $ Married  : logi  TRUE TRUE TRUE
# View(patient_df) # Commented out so it doesn't block HTML knitting

Problem 18: Renaming Columns

Task: Rename the columns to “Patient”, “Age”, “Mutations”, “Married”.

colnames(patient_df) <- c("Patient", "Age", "Mutations", "Married")
patient_df
##   Patient Age Mutations Married
## 1   Tamim  35         4    TRUE
## 2   Imrul  39         1    TRUE
## 3     Fiz  37         0    TRUE

Problem 19: Extracting a Subset of Data

Task: Use indexing to extract the “Patient” and “Age” of the first two patients.

patient_df[1:2, c("Patient", "Age")]
##   Patient Age
## 1   Tamim  35
## 2   Imrul  39

Problem 20: Extracting a Single Column

Task: Extract the “Mutations” column using both df[,3] and df$Mutations.

patient_df[, 3]
## [1] 4 1 0
patient_df$Mutations
## [1] 4 1 0

Problem 21: Adding Row Names

Task: Assign “tamim”, “imrul”, “fiz” as row names.

rownames(patient_df) <- c("tamim", "imrul", "fiz")
patient_df
##       Patient Age Mutations Married
## tamim   Tamim  35         4    TRUE
## imrul   Imrul  39         1    TRUE
## fiz       Fiz  37         0    TRUE

Problem 22: Updating a Value

Task: Update Tamim’s mutations to 5.

patient_df["tamim", "Mutations"] <- 5
patient_df
##       Patient Age Mutations Married
## tamim   Tamim  35         5    TRUE
## imrul   Imrul  39         1    TRUE
## fiz       Fiz  37         0    TRUE

Problem 23: Sorting Patients by Age

Task: Sort the data frame by the “Age” column in ascending order.

patient_df <- patient_df[order(patient_df$Age), ]
patient_df
##       Patient Age Mutations Married
## tamim   Tamim  35         5    TRUE
## fiz       Fiz  37         0    TRUE
## imrul   Imrul  39         1    TRUE

Section D – Factors

Problem 24: Academic Titles

Task: Create a factor variable with levels ordered from lecturer to professor.

titles <- c("lecturer", "assistant_professor", "associate_professor", "professor")
titles_factor <- factor(titles, 
                        levels = c("lecturer", "assistant_professor", "associate_professor", "professor"), 
                        ordered = TRUE)

titles_factor
## [1] lecturer            assistant_professor associate_professor
## [4] professor          
## 4 Levels: lecturer < assistant_professor < ... < professor

Problem 25: Lab Storage Temperature

Task: Convert temperatures into a factor with the order “medium” < “cold” < “hot”.

temps <- c("cold", "medium", "hot")
temps_factor <- factor(temps, 
                       levels = c("medium", "cold", "hot"), 
                       ordered = TRUE)
temps_factor
## [1] cold   medium hot   
## Levels: medium < cold < hot

Advanced Biological Applications

Problem 1: Identifying Patients with Abnormal Glucose Patterns

Task 1: Create a matrix of the glucose values.

glucose_data <- matrix(c(95, 160, 120,
                         110, 190, 170,
                         85, 150, 130,
                         98, 200, 180,
                         102, 175, 150), nrow = 5, byrow = TRUE)
rownames(glucose_data) <- c("P1", "P2", "P3", "P4", "P5")
colnames(glucose_data) <- c("Fasting", "1-hour", "2-hour")
glucose_data
##    Fasting 1-hour 2-hour
## P1      95    160    120
## P2     110    190    170
## P3      85    150    130
## P4      98    200    180
## P5     102    175    150

Task 2: Identify which patients have abnormal results at any time point.

# Abnormal criteria: Fasting >= 100 OR 1-hour > 180 OR 2-hour >= 140
abnormal_fasting <- glucose_data[, "Fasting"] >= 100
abnormal_1hr <- glucose_data[, "1-hour"] > 180
abnormal_2hr <- glucose_data[, "2-hour"] >= 140

abnormal_any <- abnormal_fasting | abnormal_1hr | abnormal_2hr
abnormal_any
##    P1    P2    P3    P4    P5 
## FALSE  TRUE FALSE  TRUE  TRUE

Task 3: Return only the abnormal patients and their corresponding values.

glucose_data[abnormal_any, ]
##    Fasting 1-hour 2-hour
## P2     110    190    170
## P4      98    200    180
## P5     102    175    150

Problem 2: Differential Gene Expression Analysis

Task 1: Create a data frame with the RNA-seq data.

genes <- c("TP53", "BRCA1", "MYC", "EGFR", "ACTB")
Healthy <- c(250, 120, 500, 300, 1000)
Tumor <- c(800, 130, 2000, 900, 1000)
gene_df <- data.frame(Gene = genes, Healthy = Healthy, Tumor = Tumor)
gene_df
##    Gene Healthy Tumor
## 1  TP53     250   800
## 2 BRCA1     120   130
## 3   MYC     500  2000
## 4  EGFR     300   900
## 5  ACTB    1000  1000

Task 2: Compute the fold-change for each gene.

gene_df$FoldChange <- gene_df$Tumor / gene_df$Healthy

# Calculated as Experimental Value divided by Control Value (A / B)

gene_df
##    Gene Healthy Tumor FoldChange
## 1  TP53     250   800   3.200000
## 2 BRCA1     120   130   1.083333
## 3   MYC     500  2000   4.000000
## 4  EGFR     300   900   3.000000
## 5  ACTB    1000  1000   1.000000

Task 3: Add a new column “Status” labeling genes.

gene_df$Status <- ifelse(gene_df$FoldChange >= 2, "Upregulated",
                         ifelse(gene_df$FoldChange <= 0.5, "Downregulated", "No Change"))
gene_df
##    Gene Healthy Tumor FoldChange      Status
## 1  TP53     250   800   3.200000 Upregulated
## 2 BRCA1     120   130   1.083333   No Change
## 3   MYC     500  2000   4.000000 Upregulated
## 4  EGFR     300   900   3.000000 Upregulated
## 5  ACTB    1000  1000   1.000000   No Change

Task 4: Which genes are upregulated in tumors?

gene_df$Gene[gene_df$Status == "Upregulated"]
## [1] "TP53" "MYC"  "EGFR"

Problem 3: Clinical Trial Stratification

Task 1: Create a data frame with the blood pressure dataset.

ID <- c("P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8")
Age <- c(45, 50, 39, 60, 55, 42, 48, 52)
Baseline_BP <- c(160, 150, 145, 170, 160, 135, 155, 162)
Post_BP <- c(140, 135, 142, 155, 150, 130, 138, 145)
bp_df <- data.frame(ID, Age, Baseline_BP, Post_BP)
bp_df
##   ID Age Baseline_BP Post_BP
## 1 P1  45         160     140
## 2 P2  50         150     135
## 3 P3  39         145     142
## 4 P4  60         170     155
## 5 P5  55         160     150
## 6 P6  42         135     130
## 7 P7  48         155     138
## 8 P8  52         162     145

Task 2: Add a new column “Response” labeling each patient.

bp_df$BP_Drop <- bp_df$Baseline_BP - bp_df$Post_BP
bp_df$Response <- ifelse(bp_df$BP_Drop >= 15, "Responder", "Non responder")
bp_df
##   ID Age Baseline_BP Post_BP BP_Drop      Response
## 1 P1  45         160     140      20     Responder
## 2 P2  50         150     135      15     Responder
## 3 P3  39         145     142       3 Non responder
## 4 P4  60         170     155      15     Responder
## 5 P5  55         160     150      10 Non responder
## 6 P6  42         135     130       5 Non responder
## 7 P7  48         155     138      17     Responder
## 8 P8  52         162     145      17     Responder

Task 3: Use indexing to extract only the responders older than 50 years.

bp_df[bp_df$Response == "Responder" & bp_df$Age > 50, ]
##   ID Age Baseline_BP Post_BP BP_Drop  Response
## 4 P4  60         170     155      15 Responder
## 8 P8  52         162     145      17 Responder

Problem 4: Cancer Staging with Factors

Task 1: Store the staging as a factor with correct order.

Patient <- c("P1", "P2", "P3", "P4", "P5")
Stage <- c("II", "IV", "I", "III", "II")
cancer_df <- data.frame(Patient, Stage)
cancer_df$Stage <- factor(cancer_df$Stage, levels = c("I", "II", "III", "IV"), ordered = TRUE)
cancer_df$Stage
## [1] II  IV  I   III II 
## Levels: I < II < III < IV

Task 2: Count how many patients are in each stage.

table(cancer_df$Stage)
## 
##   I  II III  IV 
##   1   2   1   1

Task 3: Extract patients who are Stage III or Stage IV (advanced cancer).

cancer_df[cancer_df$Stage %in% c("III", "IV"), ]
##   Patient Stage
## 2      P2    IV
## 4      P4   III

Problem 5: Epidemiology – Identifying High-Risk Cities

Task 1: Create a data frame with the dataset.

City <- c("Dhaka", "Chittagong", "Rajshahi", "Sylhet", "Khulna", "Barisal")
Population_m <- c(21, 9, 3, 2, 5, 1.5) # in millions
Cases_k <- c(350, 150, 40, 70, 60, 15) # in thousands
epi_df <- data.frame(City, Population_m, Cases_k)
epi_df
##         City Population_m Cases_k
## 1      Dhaka         21.0     350
## 2 Chittagong          9.0     150
## 3   Rajshahi          3.0      40
## 4     Sylhet          2.0      70
## 5     Khulna          5.0      60
## 6    Barisal          1.5      15

Task 2: Compute cases per 100,000 population for each city.

# 1 million = 1,000,000 | 1 thousand = 1,000
# Formula: (Cases_k * 1000) / (Population_m * 1000000) * 100000
epi_df$Cases_per_100k <- (epi_df$Cases_k * 1000) / (epi_df$Population_m * 1000000) * 100000
epi_df
##         City Population_m Cases_k Cases_per_100k
## 1      Dhaka         21.0     350       1666.667
## 2 Chittagong          9.0     150       1666.667
## 3   Rajshahi          3.0      40       1333.333
## 4     Sylhet          2.0      70       3500.000
## 5     Khulna          5.0      60       1200.000
## 6    Barisal          1.5      15       1000.000

Task 3: Add a new column “Risk_Level”.

epi_df$Risk_Level <- ifelse(epi_df$Cases_per_100k >= 200, "High",
                            ifelse(epi_df$Cases_per_100k >= 100, "Moderate", "Low"))
epi_df
##         City Population_m Cases_k Cases_per_100k Risk_Level
## 1      Dhaka         21.0     350       1666.667       High
## 2 Chittagong          9.0     150       1666.667       High
## 3   Rajshahi          3.0      40       1333.333       High
## 4     Sylhet          2.0      70       3500.000       High
## 5     Khulna          5.0      60       1200.000       High
## 6    Barisal          1.5      15       1000.000       High

Task 4: Which cities fall into the High Risk category?

epi_df$City[epi_df$Risk_Level == "High"]
## [1] "Dhaka"      "Chittagong" "Rajshahi"   "Sylhet"     "Khulna"    
## [6] "Barisal"