knitr::opts_chunk$set(echo = TRUE)

1 Problem: We have given a expression_data table where each column has problematic data. We have to clean it up before any anaysis

getwd()
## [1] "I:/OxfordBioDiscovery2025/2026/Single cell RNAseq"
data <- read.csv("I:/OxfordBioDiscovery2025/2026/Single cell RNAseq/expression_data.csv", header = TRUE)
View(data)


# Changing column name
colnames(data) <- c("Gene_ID","Sample_ID","Expression_Level","Upregulated","Tissue" ,"Quality_Score" )
View(data)


#Column 1: Gene_ID column cleaning
# We have ALK#, PTEN* and a space before MYC, we need to remove them
data$Gene_ID <- gsub("\\#", "" , data$Gene_ID)
data$Gene_ID <- gsub("\\*", "" , data$Gene_ID)
data$Gene_ID <- gsub(" ", "" , data$Gene_ID)

View(data)

# Find out and remove Data duplication
duplicated(data$Gene_ID)
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
# We will select only the rows where duplicated 'TRUE' "is not" marked by ! and all columns.
data <- data[ !duplicated(data$Gene_ID), ]

View(data)


# Column 2: Sample_ID cleaning
# Because it follows a sequential order, it is easy to make a 'for-loop'
# we first make a empty vector, and append each value of i sequentially
length(data)
## [1] 6
s<- c()
s
## NULL
for(i in 1:nrow(data)){
      x<- paste("S", i, sep = "")
      # We need to use append option to sequentially put S value
      s <- append(s, x)
      print(s)
      
}
## [1] "S1"
## [1] "S1" "S2"
## [1] "S1" "S2" "S3"
## [1] "S1" "S2" "S3" "S4"
## [1] "S1" "S2" "S3" "S4" "S5"
## [1] "S1" "S2" "S3" "S4" "S5" "S6"
## [1] "S1" "S2" "S3" "S4" "S5" "S6" "S7"
## [1] "S1" "S2" "S3" "S4" "S5" "S6" "S7" "S8"
## [1] "S1" "S2" "S3" "S4" "S5" "S6" "S7" "S8" "S9"
##  [1] "S1"  "S2"  "S3"  "S4"  "S5"  "S6"  "S7"  "S8"  "S9"  "S10"
data$Sample_ID <- s
View(data)


# If we want to do it as a Non sequential way. we can do it, but it will take time
# First make everything upper case with 'toupper' function
#data$Sample_ID <- toupper(data$Sample_ID)
#View(data)

#data$Sample_ID <- gsub("SAMPLE","S",data$Sample_ID)
#data$Sample_ID <- gsub("\\_","",data$Sample_ID)
#data$Sample_ID <- gsub("\\-","",data$Sample_ID)
#data$Sample_ID <- gsub("S0","S",data$Sample_ID)

#view(data)




#Column 3: Expression_Level cleaning

data$Expression_Level
##  [1]    23.4      NA   150.8   -10.2   300.5   450.6   120.1      NA 98000.0
## [10]    47.3
# have missing data in position #2 and #8
# use is.na function
is.na(data$Expression_Level)
##  [1] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
#Now select every row that is not NA (TRUE) and all column
data <- data[!is.na(data$Expression_Level), ]

# Because row read count couldn't be a negative number and suppose more than 10,000, so I want to select everything between 0 and 10,000 and rest should be ignored
data <- data[data$Expression_Level >= 0 & data$Expression_Level <= 10000, ]

View(data)

#Also, I want to make it integer, not a fraction, because raw count could not be a fraction
data$Expression_Level <- as.integer(data$Expression_Level)
View(data)



#Column 4: Upregulated cleaning
# I want to make it all capital first, and then change YES to TRUE, 1 to TURE, NO to FALSE and 0 to FALSE
data$Upregulated <- toupper(data$Upregulated)

data$Upregulated <- gsub("YES","TRUE",data$Upregulated)
data$Upregulated <- gsub("NO","FALSE",data$Upregulated)
data$Upregulated <- gsub("1","TRUE",data$Upregulated)
data$Upregulated <- gsub("0","FALSE",data$Upregulated)

View(data)



# Column 5: Tissue cleaning
is.na(data$Tissue)
## [1] FALSE FALSE FALSE FALSE FALSE FALSE
#Wow! row 4 is not a NA here, it is empty string, that is why in.na(data$Tissue) did not work
data <- data[!is.na(data$Tissue), ]

#Try this
data <- data[!is.na(data$Tissue) & data$Tissue != "", ]
View(data)


# Column 6: Quality_Score cleaning
# I arbitrarily considered anything below 65 is low quality, so I will employ a 'ifelse' function

data$Quality_Score <- ifelse(data$Quality_Score >= 65, "HIGH", "LOW")

# becuase one high has been provided in lowercase, so I changed to everything upper.
data$Quality_Score <-toupper(data$Quality_Score)

View(data)


# I wanted to show the final data as a table in my Rpub. So, took the help of ChatGPT for following code only
#Final data to be shown as a table in RPubs after knitting
knitr::kable(
  data,
  caption = "Final Cleaned Expression Data",
  align = "c"
)
Final Cleaned Expression Data
Gene_ID Sample_ID Expression_Level Upregulated Tissue Quality_Score
1 TP53 S1 23 TRUE Liver HIGH
3 MYC S3 150 TRUE Heart HIGH
5 ALK S5 300 TRUE Kidney LOW
7 MDM2 S7 120 TRUE Skin HIGH
10 PAX8 S10 47 FALSE Brain LOW