A programming exercise in finding an ungapped query match in a reference sequence. The name “Simple BLAST” describes the exercise; the code is a small sequence-matching routine rather than the full BLAST algorithm.

Question

Can I produce a simple BLAST function? If I input the query sequence ATAC and the reference sequence GGATACTF, the function should output where the query sequence is optimally matched on the reference sequence.

Additional rules (which is why I called this “simple” BLAST):

  • NO GAPS

Code

library(ggplot2)
  
# Create a matrix to store alignment scores
RS = c("GCGATC") # reference sequence
QS = c("GATC") # query sequence

for (k in 1:(nchar(RS)-nchar(QS)+1)){   # RS bp - QS bp + 1: how many types of alignments?

# START with the 1st alignment (no gaps)
# create matrix
  matching_score <- c()
  alignment_matrix <- matrix("", nrow = nchar(QS) + 1, ncol = nchar(RS) + 1)
    for (i in 1:nchar(QS)) {     # QS bp
    for (j in 1:nchar(RS)) {     # RS bp
          alignment_matrix[1, j+1] <- substr(RS, j, j)
          alignment_matrix[i+1, 1] <- substr(QS, i, i)
    }
    }

# assign matching scores in this matrix (how many scores = how long is the query sequence)AND
# input the matching scores for all alignments
  
				for (s in 1:nchar(QS)) {
          if (alignment_matrix[1, k+s] == alignment_matrix[s+1, 1]){
	            alignment_matrix[s+1, k+s] <- as.numeric(1)
          } else { alignment_matrix[s+1, k+s] <- as.numeric(-1) }
    
    # save these matching scores
    matching_score <- c(matching_score,
                        as.numeric(alignment_matrix[s+1, s+k]))
    
  }
  

# output everytime when a matrix is finished with scores assignment
    assign(paste0("matching_score","_",k), 
           matching_score,
           envir=.GlobalEnv)
  
                              }
                                    
            

# visualization

matchingScore <- c()
for (i in 1:(nchar(RS)-nchar(QS)+1)){

      # calculate how many "1" are there
      matchingScore[[i]] <- sum(mget(paste0("matching_score_", i))[[1]] == 1)
}



      matchingScore_value <- max(unlist(matchingScore))
      matchingScore_start <- which(unlist(matchingScore) == matchingScore_value)
      
      
# Calculate cumulative sum
cumulative_sum <- cumsum(c(0, as.numeric(
                                    mget(
                                          paste0("matching_score_", matchingScore_start))[[1]]
                                    )))  # Add a 0 at the beginning

# Create an index vector (x-axis values starting with 0)
indices <- seq_along(cumulative_sum) - 1  # Subtract 1 to start with index 0

# Plot the line chart
plot(indices, 
            cumulative_sum, 
            main = paste0("Alignment at ",matchingScore_start, " bp of reference sequence \nMatching bp =", matchingScore_value),
            type = "b", 
            xlab = "bp of query sequence", 
            ylab = "Cumulative Sum", 
            ylim = c(-nchar(QS), 
                     nchar(QS)))
abline(h=0, col="red")
Recorded output of the ungapped sequence-matching exercise
Recorded output of the ungapped sequence-matching exercise
← Back to projects