R is widely used for data analysis, but running NCBI’s standard BLAST tools within R has traditionally been slow. Because the NCBI C++ toolkit is massive and difficult to compile for R, existing packages are forced to run BLAST as an external subprocess, creating major read/write bottlenecks.
QuickBLAST solves this by building a direct bridge between R and the NCBI C++ toolkit via Rcpp. By bypassing traditional text-based formatting and transporting data directly into memory using Apache Arrow, QuickBLAST performs sequence comparisons exceptionally fast.
QuickBLAST operates using “instances”. An instance is an active C++ object pointer (QuickBLAST_XPtr) that holds your BLAST configuration open in memory.
library(QuickBLAST)
#> QuickBLAST Loaded!
#> Version: 1.99.8
#> Github: https://github.com/vizkidd/QuickBLAST
QuickBLAST::isQuickBLASTLoaded()
#> [1] TRUE
# Create instances for different sequence types and programs. Note: seq_type =
# 1 (Protein), seq_type = 0 (Nucleotide)
blastp_inst <- QuickBLAST::CreateQuickBLASTInstance(seq_type = 1, strand = 0, program = "blastp",
save_sequences = TRUE, options = "-evalue 100000")
#> Option: evalue set to : 100000
blastn_inst <- QuickBLAST::CreateQuickBLASTInstance(seq_type = 0, strand = 0, program = "blastn",
options = "-evalue 100000")
#> Option: evalue set to : 100000
tblastx_inst <- QuickBLAST::CreateQuickBLASTInstance(seq_type = 0, strand = 0, program = "tblastx")
#> Using tblastx Defaults...
# Inspecting an instance reveals its underlying C++ pointer and attributes
blastn_inst
#> <pointer: 0x5633f8109f80>
#> attr(,"seq_type")
#> [1] 0
#> attr(,"strand")
#> [1] 0
#> attr(,"program")
#> [1] "blastn"
#> attr(,"options")
#> [1] "-evalue 100000"
#> attr(,"save_sequences")
#> [1] FALSE
#> attr(,"save_hsp_sequences")
#> [1] FALSE
#> attr(,"class")
#> [1] "QuickBLAST_XPtr"Because QuickBLAST creates objects in C++, we provide convenience functions to track, verify, and clean up instances to prevent memory leaks.
QuickBLAST::GetInstanceCount()
#> [1] 3
QuickBLAST::GetInstanceID(blastp_inst)
#> [1] 0
# Clean up memory by deleting specific instances
QuickBLAST::DeleteQuickBLASTInstance(QuickBLAST::GetQuickBLASTInstance(1))
#> [1] TRUE
QuickBLAST::DeleteQuickBLASTInstance(2)
#> [1] TRUE
QuickBLAST::GetInstanceCount()
#> [1] 1
# Attempting to fetch a deleted instance securely throws a C++ map error
# try(identical(try(QuickBLAST::GetQuickBLASTInstance(1), silent = TRUE,
# outFile = stdout()), blastn_inst), silent = TRUE, outFile = stdout())
# Recreate the blastn instance for later steps
blastn_inst <- QuickBLAST::CreateQuickBLASTInstance(seq_type = 0, strand = 0, program = "blastn")
#> Using blastn Defaults...You can pass raw character strings directly to QuickBLAST. The engine evaluates the sequences in memory instantly. Notice that QuickBLAST includes automatic recovery: if a pointer is dead, it will attempt to reload it.
# (~)Successful TBLASTX execution : Garbage low information nucleotide sequences
try(QuickBLAST::BLAST2Seqs(tblastx_inst, "AAAAAAAAAAAATTTTTTTTTTTTGGGGGGGGGGGCCCCCCCCC", "TTTTTTTTTTTGGGGGGGGGGGG"), silent = TRUE, outFile = stdout())
#> Dead pointer detected. Attempting to reload...
#> Using tblastx Defaults...
#> Clock : 0.00202956 seconds
#> 1
#> RecordBatchVector size: 1
#> Total rows across all batches: 1
#> [[1]]
#> seq_info_num_alignments seq_info_seqids_qseqid seq_info_seqids_sseqid
#> 1 1 1 2
#> seq_info_seqs_qseq seq_info_seqs_sseq seq_info_strands seq_info_lengths_qlen
#> 1 +/+ 44
#> seq_info_lengths_slen hsps_qhsp hsps_shsp hsps_pident hsps_pident_gap
#> 1 23 0 0
#> hsps_frames hsps_evalue hsps_length hsps_length01 hsps_qstart hsps_qend
#> 1 3/2 0 207 1.045455 14 35
#> hsps_sstart hsps_send hsps_bitscore hsps_score hsps_qcovhsp hsps_blast_score
#> 1 1 23 0 0 0 0
#> hsps_gaps hsps_nident hsps_mismatch hsps_positive hsps_n_splices hsps_hsp_num
#> 1 0 0 207 0 0 1
#> hsps_sum_evalue hsps_product_coverage hsps_overall_identity
#> 1 0 0 0
#> hsps_negative_count hsps_matches hsps_high_quality_percent_coverage
#> 1 0 0 0
#> hsps_exon_identity hsps_consensus_splices hsps_comp_adj_method
#> 1 0 0 0
# Expected empty results due to mismatched pointer type (Nucleotide vs Nucleotide with a blastp pointer)
try(QuickBLAST::BLAST2Seqs(blastp_inst, "AAAAAAAAAAAATTTTTTTTTTTTGGGGGGGGGGGCCCCCCCCC", "TTTTTTTTTTTGGGGGGGGGGGG"), silent = TRUE, outFile = stdout())
#> Clock : 0.00135856 seconds
#> 1
#> RecordBatchVector size: 1
#> list()
# (~)Successful Protein-Protein search : Same protein
QuickBLAST::BLAST2Seqs(blastp_inst, "MQILLVEDDNTLFQELKKELEQWDFNVAGIEDFGKVMDTFESFNPEIVILDVQLPKYDGFYWCRKMREVSNVPILFLSSRDNPMDQVMSMELGADDYMQKPFYTNVLIAKLQAIYRRVYEFTAEEKRTLTWQDAVVDLSKDSIQKGDDTIFLSKTEMIILEILITKKNQIVSRDTIITALWDDEAFVSDNTLTVNVNRLRKKLSEISMDSAIETKVGKGYMAHE", "MQILLVEDDNTLFQELKKELEQWDFNVAGIEDFGKVMDTFESFNPEIVILDVQLPKYDGFYWCRKMREVSNVPILFLSSRDNPMDQVMSMELGADDYMQKPFYTNVLIAKLQAIYRRVYEFTAEEKRTLTWQDAVVDLSKDSIQKGDDTIFLSKTEMIILEILITKKNQIVSRDTIITALWDDEAFVSDNTLTVNVNRLRKKLSEISMDSAIETKVGKGYMAHE")
#> Clock : 0.00169728 seconds
#> 1
#> RecordBatchVector size: 1
#> Total rows across all batches: 1
#> [[1]]
#> seq_info_num_alignments seq_info_seqids_qseqid seq_info_seqids_sseqid
#> 1 1 3 4
#> seq_info_seqs_qseq
#> 1 MQILLVEDDNTLFQELKKELEQWDFNVAGIEDFGKVMDTFESFNPEIVILDVQLPKYDGFYWCRKMREVSNVPILFLSSRDNPMDQVMSMELGADDYMQKPFYTNVLIAKLQAIYRRVYEFTAEEKRTLTWQDAVVDLSKDSIQKGDDTIFLSKTEMIILEILITKKNQIVSRDTIITALWDDEAFVSDNTLTVNVNRLRKKLSEISMDSAIETKVGKGYMAHE
#> seq_info_seqs_sseq
#> 1 MQILLVEDDNTLFQELKKELEQWDFNVAGIEDFGKVMDTFESFNPEIVILDVQLPKYDGFYWCRKMREVSNVPILFLSSRDNPMDQVMSMELGADDYMQKPFYTNVLIAKLQAIYRRVYEFTAEEKRTLTWQDAVVDLSKDSIQKGDDTIFLSKTEMIILEILITKKNQIVSRDTIITALWDDEAFVSDNTLTVNVNRLRKKLSEISMDSAIETKVGKGYMAHE
#> seq_info_strands seq_info_lengths_qlen seq_info_lengths_slen hsps_qhsp
#> 1 */* 224 224
#> hsps_shsp hsps_pident hsps_pident_gap hsps_frames hsps_evalue hsps_length
#> 1 100 100 0/0 9.626626e-172 224
#> hsps_length01 hsps_qstart hsps_qend hsps_sstart hsps_send hsps_bitscore
#> 1 1 1 224 1 224 458.7585
#> hsps_score hsps_qcovhsp hsps_blast_score hsps_gaps hsps_nident hsps_mismatch
#> 1 1179 1 1179 0 224 0
#> hsps_positive hsps_n_splices hsps_hsp_num hsps_sum_evalue
#> 1 224 0 1 0
#> hsps_product_coverage hsps_overall_identity hsps_negative_count hsps_matches
#> 1 0 0 0 0
#> hsps_high_quality_percent_coverage hsps_exon_identity hsps_consensus_splices
#> 1 0 0 0
#> hsps_comp_adj_method
#> 1 2
# Successful NT-NT search
QuickBLAST::BLAST2Seqs(blastn_inst, "ATGGAGGAGCCGCAGTCAGATCCTAGCGTCGAGCCCCCTCTGAGTCAGGAAACATTTTCA", "ATGGAGGAGCCGCAGTCAGATCCTAGCCTCGAGCCCCCTCTGAGTCAGGAAACATTTTCA")
#> Clock : 0.0010263 seconds
#> 1
#> RecordBatchVector size: 1
#> Total rows across all batches: 1
#> [[1]]
#> seq_info_num_alignments seq_info_seqids_qseqid seq_info_seqids_sseqid
#> 1 1 1 2
#> seq_info_seqs_qseq seq_info_seqs_sseq seq_info_strands seq_info_lengths_qlen
#> 1 +/+ 60
#> seq_info_lengths_slen hsps_qhsp hsps_shsp hsps_pident hsps_pident_gap
#> 1 60 98.33333 98.33333
#> hsps_frames hsps_evalue hsps_length hsps_length01 hsps_qstart hsps_qend
#> 1 2/2 2.763249e-29 60 1 1 60
#> hsps_sstart hsps_send hsps_bitscore hsps_score hsps_qcovhsp hsps_blast_score
#> 1 1 60 106.3793 57 0 57
#> hsps_gaps hsps_nident hsps_mismatch hsps_positive hsps_n_splices hsps_hsp_num
#> 1 0 59 1 0 0 1
#> hsps_sum_evalue hsps_product_coverage hsps_overall_identity
#> 1 0 0 0
#> hsps_negative_count hsps_matches hsps_high_quality_percent_coverage
#> 1 0 0 0
#> hsps_exon_identity hsps_consensus_splices hsps_comp_adj_method
#> 1 0 0 0If you do not want to compile databases locally, QuickBLAST can interface directly with NCBI’s remote servers.
``` r
# Safely check if the machine has internet access before running
if (requireNamespace("curl", quietly = TRUE) && curl::has_internet()) {
# Example of a remote timeout handling
try(QuickBLAST::RemoteBLAST(blastn_inst, query_input = "AAAAAAAAAAAATTTTTTTTTTTTGGGGGGGGGGGCCCCCCCCC", database = "nr", input_type = 1, return_values = TRUE), silent = TRUE, outFile = stdout())
# Successful Remote Protein Query against the PDB database
QuickBLAST::RemoteBLAST(blastp_inst, query_input = "MQILLVEDDNTLFQELKKELEQWDFNVAGIEDFGKVMDTFESFNPEIVILDVQLPKYDGFYWCRKMREVSNVPILFLSSRDNPMDQVMSMELGADDYMQKPFYTNVLIAKLQAIYRRVYEFTAEEKRTLTWQDAVVDLSKDSIQKGDDTIFLSKTEMIILEILITKKNQIVSRDTIITALWDDEAFVSDNTLTVNVNRLRKKLSEISMDSAIETKVGKGYMAHE", database = "pdb", input_type = 1, return_values = TRUE)
} else {
message("No internet connection available. Skipping remote BLAST examples.")
}
```For large-scale genomics, sequences are often stored in FASTA files. QuickBLAST can compare two files directly via multi-threaded reading, without loading everything into the R global environment first.
safe_temp_dir <- normalizePath(tempdir(check = TRUE), mustWork = FALSE)
# Create temporary FASTA files
query_fasta <- normalizePath(tempfile(fileext = ".fasta", tmpdir = safe_temp_dir), mustWork = FALSE)
subject_fasta <- normalizePath(tempfile(fileext = ".fasta", tmpdir = safe_temp_dir), mustWork = FALSE)
# Human TP53 gene fragment (Query)
writeLines(c(
">Human_p53_fragment\nATGGAGGAGCCGCAGTCAGATCCTAGCGTCGAGCCCCCTCTGAGTCAGGAAACATTTTCA"
), query_fasta)
# Slightly mutated version (Subject - e.g., an ortholog or variant)
writeLines(c(
">Variant_p53_fragment\nATGGAGGAGCCGCAGTCAGATCCTAGCCTCGAGCCCCCTCTGAGTCAGGAAACATTTTCA"
), subject_fasta)
# Efficiently compare the files using the BLASTN instance
file_results <- QuickBLAST::BLAST2Files(
blastn_inst,
query = query_fasta,
subject = subject_fasta,
return_values = TRUE,
num_threads = 1
)
#> Num Threads: 1
#> Total Records (Q + S): 2 (1 + 1)
#> Batch Size: 2
#> Computing: [========================================] 100% (done)
#> Total Records Processed: 1
#> Clock : 0.00328778 seconds
#> RecordBatchVector size: 1
#> Total rows across all batches: 1
print(file_results)
#> [[1]]
#> seq_info_num_alignments seq_info_seqids_qseqid seq_info_seqids_sseqid
#> 1 1 Human_p53_fragment Variant_p53_fragment
#> seq_info_seqs_qseq seq_info_seqs_sseq seq_info_strands seq_info_lengths_qlen
#> 1 +/+ 60
#> seq_info_lengths_slen hsps_qhsp hsps_shsp hsps_pident hsps_pident_gap
#> 1 60 98.33333 98.33333
#> hsps_frames hsps_evalue hsps_length hsps_length01 hsps_qstart hsps_qend
#> 1 2/2 2.763249e-29 60 1 1 60
#> hsps_sstart hsps_send hsps_bitscore hsps_score hsps_qcovhsp hsps_blast_score
#> 1 1 60 106.3793 57 0 57
#> hsps_gaps hsps_nident hsps_mismatch hsps_positive hsps_n_splices hsps_hsp_num
#> 1 0 59 1 0 0 1
#> hsps_sum_evalue hsps_product_coverage hsps_overall_identity
#> 1 0 0 0
#> hsps_negative_count hsps_matches hsps_high_quality_percent_coverage
#> 1 0 0 0
#> hsps_exon_identity hsps_consensus_splices hsps_comp_adj_method
#> 1 0 0 0For high-throughput homology searches against a fixed reference, compiling the sequences into an indexed BLAST database is much faster than raw file-to-file comparisons. QuickBLAST wraps the NCBI makeblastdb functionality directly into R.
safe_temp_dir <- normalizePath(tempdir(check = TRUE), mustWork = FALSE)
query_fasta <- normalizePath(tempfile(fileext = ".fasta", tmpdir = safe_temp_dir), mustWork = FALSE)
subject_fasta <- normalizePath(tempfile(fileext = ".fasta", tmpdir = safe_temp_dir), mustWork = FALSE)
# Human TP53 gene fragment (Query)
writeLines(c(
">Human_p53_fragment\nATGGAGGAGCCGCAGTCAGATCCTAGCGTCGAGCCCCCTCTGAGTCAGGAAACATTTTCA"
), query_fasta)
# Mutant TP53 gene fragment (Subject)
writeLines(c(
">Variant_p53_fragment\nATGGAGGAGCCGCAGTCAGATCCTAGCCTCGAGCCCCCTCTGAGTCAGGAAACATTTTCA"
), subject_fasta)
db_path <- file.path(safe_temp_dir, "My_Test_DB")
# db_path_sub <- file.path(safe_temp_dir, "My_Test_DB_sub")
# 1. Compile the local BLAST database
# db_type can be "nucl" or "prot"
# QuickBLAST::MakeBLASTDB(
# ptr = blastn_inst,
# input_file = query_fasta,
# database_name = db_path,
# parse_seqids = FALSE,
# stdout_opt = "",
# stderr_opt = FALSE
# )
try(QuickBLAST::MakeBLASTDB(
ptr = blastn_inst,
input_file = subject_fasta,
database_name = db_path,
parse_seqids = FALSE
), silent = TRUE, outFile = stdout())
#> [MakeBLASTDB] Executing command: /tmp/Rtmpeh7NMR/Rinstf2ce3d3806/QuickBLAST/bin//makeblastdb -in /tmp/Rtmp3MHqJB/file663b1f05d443.fasta -dbtype nucl -out /tmp/Rtmp3MHqJB/My_Test_DB
#> makeblastdb finished successfully
#> [1] "/tmp/Rtmp3MHqJB/My_Test_DB"
# 2. Search a query file or query database against the custom local database
db_results <- try(QuickBLAST::BLAST2DBs(
blastn_inst,
query = query_fasta,
subject = db_path,
return_values = TRUE,
num_threads = 2
), silent = TRUE, outFile = stdout())
#> [MakeBLASTDB] Executing command: /tmp/Rtmpeh7NMR/Rinstf2ce3d3806/QuickBLAST/bin//makeblastdb -in /tmp/Rtmp3MHqJB/file663b2f7e7356.fasta -dbtype nucl -out /tmp/Rtmp3MHqJB/file663b2f7e7356.fasta.db
#> makeblastdb finished successfully
#> Q :/tmp/Rtmp3MHqJB/file663b2f7e7356.fasta.db
#> S :/tmp/Rtmp3MHqJB/My_Test_DB
#> Num Threads: 2
#> Total Records (Q + S): 2 (1 + 1)
#> Batch Size: 3
#> Batch Hits: 1
#> Processed Batches:1
#> Total Records Processed: 2
#> Clock : 0.0787094 seconds
#> RecordBatchVector size: 1
#> Total rows across all batches: 1
print(db_results)
#> [[1]]
#> seq_info_num_alignments seq_info_seqids_qseqid seq_info_seqids_sseqid
#> 1 1 Human_p53_fragment Human_p53_fragment
#> seq_info_seqs_qseq seq_info_seqs_sseq seq_info_strands seq_info_lengths_qlen
#> 1 +/+ 60
#> seq_info_lengths_slen hsps_qhsp hsps_shsp hsps_pident hsps_pident_gap
#> 1 60 98.33333 98.33333
#> hsps_frames hsps_evalue hsps_length hsps_length01 hsps_qstart hsps_qend
#> 1 1/1 2.763249e-29 60 1 0 59
#> hsps_sstart hsps_send hsps_bitscore hsps_score hsps_qcovhsp hsps_blast_score
#> 1 0 59 106.3793 57 0 57
#> hsps_gaps hsps_nident hsps_mismatch hsps_positive hsps_n_splices hsps_hsp_num
#> 1 0 59 1 0 0 1
#> hsps_sum_evalue hsps_product_coverage hsps_overall_identity
#> 1 0 0 0
#> hsps_negative_count hsps_matches hsps_high_quality_percent_coverage
#> 1 0 0 0
#> hsps_exon_identity hsps_consensus_splices hsps_comp_adj_method
#> 1 0 0 0By default, the return_values = TRUE flag seen above brings data directly into R as an Rcpp::List. However, when processing millions of alignments, memory can max out quickly.
To solve this, QuickBLAST writes results asynchronously using Apache Arrow formats (arrow::parquet, arrow::ipc and arrow::csv). This creates a highly compressed, blazingly fast columnar storage file, an inter-process-communicable file or a tabular CSV.
safe_temp_dir <- normalizePath(tempdir(check = TRUE), mustWork = FALSE)
query_fasta <- normalizePath(tempfile(fileext = ".fasta", tmpdir = safe_temp_dir), mustWork = FALSE)
subject_fasta <- normalizePath(tempfile(fileext = ".fasta", tmpdir = safe_temp_dir), mustWork = FALSE)
# Human TP53 gene fragment (Query)
writeLines(c(
">Human_p53_fragment\nATGGAGGAGCCGCAGTCAGATCCTAGCGTCGAGCCCCCTCTGAGTCAGGAAACATTTTCA"
), query_fasta)
# Mutant TP53 gene fragment (Subject)
writeLines(c(
">Variant_p53_fragment\nATGGAGGAGCCGCAGTCAGATCCTAGCCTCGAGCCCCCTCTGAGTCAGGAAACATTTTCA"
), subject_fasta)
# Specify an output path
out_parquet <- normalizePath(tempfile(fileext = ".parquet"), mustWork = FALSE)
out_ipc <- normalizePath(tempfile(fileext = ".ipc"), mustWork = FALSE)
out_csv <- normalizePath(tempfile(fileext = ".csv"), mustWork = FALSE)
# Perform the search and write straight to an Arrow Parquet/IPC/CSV file
# We don't need it in RAM, we are writing to disk
QuickBLAST::BLAST2Files(
blastn_inst,
query = query_fasta,
subject = subject_fasta,
out_file = out_parquet,
out_format = "parquet",
return_values = FALSE,
verbose = TRUE
)
#> Writing to : /tmp/Rtmp3MHqJB/file663b70e017da.parquet
#> Output Format : parquet
#> Num Threads: 2
#> Total Records (Q + S): 2 (1 + 1)
#> Batch Size: 3
#> Computing: [========================================] 100% (done)
#> Done writing to file.
#> Total Records Processed: 5
#> Clock : 0.0502711 seconds
#> [1] TRUE
QuickBLAST::BLAST2Files(
blastn_inst,
query = query_fasta,
subject = subject_fasta,
out_file = out_ipc,
out_format = "ipc",
return_values = FALSE
)
#> Writing to : /tmp/Rtmp3MHqJB/file663b2e293b8f.ipc
#> Output Format : ipc
#> Num Threads: 2
#> Total Records (Q + S): 2 (1 + 1)
#> Batch Size: 3
#> Computing: [========================================] 100% (done)
#> Done writing to file.
#> Total Records Processed: 5
#> Clock : 0.0502079 seconds
#> [1] TRUE
QuickBLAST::BLAST2Files(
blastn_inst,
query = query_fasta,
subject = subject_fasta,
out_file = out_csv,
out_format = "csv",
return_values = FALSE
)
#> Writing to : /tmp/Rtmp3MHqJB/file663b6ddd6fb8.csv
#> Output Format : csv
#> Num Threads: 2
#> Total Records (Q + S): 2 (1 + 1)
#> Batch Size: 3
#> Done writing to file.
#> Total Records Processed: 5
#> Clock : 0.0502244 seconds
#> [1] TRUE
# Load the hits back into an R data.frame natively via QuickBLAST
hits_df <- QuickBLAST::LoadBLASTHits(out_parquet, format = "parquet")
head(hits_df)
#> # A tibble: 6 × 2
#> seq_info$num_alignments $seqids$qseqid $$sseqid $seqs$qseq $strands hsps$qhsp
#> <int> <chr> <chr> <chr> <chr> <chr>
#> 1 1 Human_p53_frag… Variant… "" +/+ ""
#> 2 1 Human_p53_frag… Variant… "" +/+ ""
#> 3 1 Human_p53_frag… Variant… "" +/+ ""
#> 4 1 Human_p53_frag… Variant… "" +/+ ""
#> 5 1 Human_p53_frag… Variant… "" +/+ ""
#> 6 1 Human_p53_frag… Variant… "" +/+ ""
#> # ℹ 32 more variables: seq_info$seqs$sseq <chr>, seq_info$lengths <tibble[,2]>,
#> # hsps$shsp <chr>, $pident <dbl>, $pident_gap <dbl>, $frames <chr>,
#> # $evalue <dbl>, $length <int>, $length01 <dbl>, $qstart <int>, $qend <int>,
#> # $sstart <int>, $send <int>, $bitscore <dbl>, $score <dbl>, $qcovhsp <dbl>,
#> # $blast_score <dbl>, $gaps <int>, $nident <int>, $mismatch <int>,
#> # $positive <int>, $n_splices <int>, $hsp_num <int>, $sum_evalue <dbl>,
#> # $product_coverage <dbl>, $overall_identity <dbl>, $negative_count <int>, …
hits_df <- QuickBLAST::LoadBLASTHits(out_ipc, format = "ipc")
head(hits_df)
#> # A tibble: 6 × 39
#> num_alignments seqids_qseqid seqids_sseqid seqs_qseq seqs_sseq strands
#> <int> <chr> <chr> <chr> <chr> <chr>
#> 1 1 Human_p53_fragment Variant_p53_fra… "" "" +/+
#> 2 1 Human_p53_fragment Variant_p53_fra… "" "" +/+
#> 3 1 Human_p53_fragment Variant_p53_fra… "" "" +/+
#> 4 1 Human_p53_fragment Variant_p53_fra… "" "" +/+
#> 5 1 Human_p53_fragment Variant_p53_fra… "" "" +/+
#> 6 1 Human_p53_fragment Variant_p53_fra… "" "" +/+
#> # ℹ 33 more variables: lengths_qlen <int>, lengths_slen <int>, qhsp <chr>,
#> # shsp <chr>, pident <dbl>, pident_gap <dbl>, frames <chr>, evalue <dbl>,
#> # length <int>, length01 <dbl>, qstart <int>, qend <int>, sstart <int>,
#> # send <int>, bitscore <dbl>, score <dbl>, qcovhsp <dbl>, blast_score <dbl>,
#> # gaps <int>, nident <int>, mismatch <int>, positive <int>, n_splices <int>,
#> # hsp_num <int>, sum_evalue <dbl>, product_coverage <dbl>,
#> # overall_identity <dbl>, negative_count <int>, matches <dbl>, …
hits_df <- QuickBLAST::LoadBLASTHits(out_csv, format = "csv", sep = "\t", header = TRUE)
head(hits_df)
#> # A tibble: 6 × 39
#> seq_info.num_alignments seq_info.seqids.qseqid seq_info.seqids.sseqid
#> <int> <chr> <chr>
#> 1 1 Human_p53_fragment Variant_p53_fragment
#> 2 1 Human_p53_fragment Variant_p53_fragment
#> 3 1 Human_p53_fragment Variant_p53_fragment
#> 4 1 Human_p53_fragment Variant_p53_fragment
#> 5 1 Human_p53_fragment Variant_p53_fragment
#> 6 1 Human_p53_fragment Variant_p53_fragment
#> # ℹ 36 more variables: seq_info.seqs.qseq <???>, seq_info.seqs.sseq <???>,
#> # seq_info.strands <chr>, seq_info.lengths.qlen <int>,
#> # seq_info.lengths.slen <int>, hsps.qhsp <???>, hsps.shsp <???>,
#> # hsps.pident <dbl>, hsps.pident_gap <dbl>, hsps.frames <chr>,
#> # hsps.evalue <dbl>, hsps.length <int>, hsps.length01 <int>,
#> # hsps.qstart <int>, hsps.qend <int>, hsps.sstart <int>, hsps.send <int>,
#> # hsps.bitscore <dbl>, hsps.score <int>, hsps.qcovhsp <int>, …QuickBLAST modernizes sequence alignment in R. By managing your instances appropriately, keeping data in native C++ structures, and offloading massive search results to Apache Arrow formats, you can run high-throughput bioinformatic pipelines natively without relying on slow Sys.Call() bash wrappers.
sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: Etc/UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] QuickBLAST_1.99.8 rmarkdown_2.31
#>
#> loaded via a namespace (and not attached):
#> [1] tidyr_1.3.2 utf8_1.2.6 sass_0.4.10
#> [4] future_1.75.0 generics_0.1.4 listenv_1.0.0
#> [7] digest_0.6.39 magrittr_2.0.5 evaluate_1.0.5
#> [10] iterators_1.0.14 fastmap_1.2.0 jsonlite_2.0.0
#> [13] processx_3.9.0 RcppProgress_0.4.2 ps_1.9.3
#> [16] formatR_1.14 purrr_1.2.2 codetools_0.2-20
#> [19] jquerylib_0.1.4 RcppThread_2.4.0 cli_3.6.6
#> [22] rlang_1.3.0 parallelly_1.48.0 future.apply_1.20.2
#> [25] bit64_4.8.2 withr_3.0.3 cachem_1.1.0
#> [28] yaml_2.3.12 otel_0.2.0 tools_4.6.1
#> [31] parallel_4.6.1 tzdb_0.5.0 dplyr_1.2.1
#> [34] globals_0.19.1 assertthat_0.2.1 buildtools_1.0.0
#> [37] vctrs_0.7.3 R6_2.6.1 lifecycle_1.0.5
#> [40] fs_2.1.0 bit_4.6.0 arrow_25.0.0
#> [43] pkgconfig_2.0.3 callr_3.8.0 pillar_1.11.1
#> [46] bslib_0.11.0 glue_1.8.1 Rcpp_1.1.2
#> [49] xfun_0.60 tibble_3.3.1 tidyselect_1.2.1
#> [52] future.callr_1.0.0 sys_3.4.3 knitr_1.51
#> [55] htmltools_0.5.9 BH_1.90.0-1 maketools_1.3.2
#> [58] compiler_4.6.1