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
| 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 |