tTEscanR includes a dedicated preprocessing module that provides multiple functions for generating ready-to-use data count matrices. The primary goal of this module is to facilitate the transformation from (sc)ATAC-seq count matrices to tRNA abundance count matrices where tRNA genes are the rows and the conditions the columns. Additionally, it helps annotating the tRNA genes.
if (!requireNamespace("BiocManager", quietly = TRUE)) {
install.packages("BiocManager")
}
BiocManager::install("tTEscanR")To illustrate the functionality of the tRNA specific preprocessing module we generated a toy example dataset representing a peak count matrix where the fragment regions are placed as rows and the samples as columns. We have also defined the corresponding metadata.
library(Matrix)
# Parameters
num_peaks <- 100
num_cells <- 20 # Increased to pass min.cells = 10
set.seed(42)
# Create peak names with "-" separator
chroms <- sample(paste0("chr", 1:3), num_peaks, replace = TRUE)
starts <- seq(1000, by = 5000, length.out = num_peaks)
ends <- starts + 300
peak_names <- paste(chroms, starts, ends, sep = "-")
# Create a sparse matrix
counts <- Matrix(
rpois(num_peaks * num_cells, lambda = 5),
nrow = num_peaks,
ncol = num_cells,
sparse = TRUE
)
rownames(counts) <- peak_names
colnames(counts) <- paste0("Cell_", seq_len(num_cells))
saveRDS(counts, "foo.RDS")library(dplyr)
library(Rsamtools)
#> Loading required package: Seqinfo
#> Loading required package: BiocGenerics
#> Loading required package: generics
#>
#> Attaching package: 'generics'
#> The following object is masked from 'package:dplyr':
#>
#> explain
#> The following objects are masked from 'package:base':
#>
#> as.difftime, as.factor, as.ordered, intersect, is.element, setdiff,
#> setequal, union
#>
#> Attaching package: 'BiocGenerics'
#> The following object is masked from 'package:dplyr':
#>
#> combine
#> The following object is masked from 'package:tTEscanR':
#>
#> updateObject
#> The following objects are masked from 'package:stats':
#>
#> IQR, mad, sd, var, xtabs
#> The following object is masked from 'package:utils':
#>
#> data
#> The following objects are masked from 'package:base':
#>
#> anyDuplicated, aperm, append, as.data.frame, basename, cbind,
#> colnames, dirname, do.call, duplicated, eval, evalq, Filter, Find,
#> get, grep, grepl, is.unsorted, lapply, Map, mapply, match, mget,
#> order, paste, pmax, pmax.int, pmin, pmin.int, Position, rank,
#> rbind, Reduce, rownames, sapply, saveRDS, scale, sequence, table,
#> tapply, transform, unique, unsplit, which.max, which.min
#> Loading required package: GenomicRanges
#> Loading required package: stats4
#> Loading required package: S4Vectors
#>
#> Attaching package: 'S4Vectors'
#> The following objects are masked from 'package:Matrix':
#>
#> expand, unname
#> The following objects are masked from 'package:dplyr':
#>
#> first, rename
#> The following object is masked from 'package:utils':
#>
#> findMatches
#> The following objects are masked from 'package:base':
#>
#> expand.grid, I, unname
#> Loading required package: IRanges
#>
#> Attaching package: 'IRanges'
#> The following objects are masked from 'package:dplyr':
#>
#> collapse, desc, slice
#> Loading required package: Biostrings
#> Loading required package: XVector
#>
#> Attaching package: 'Biostrings'
#> The following object is masked from 'package:base':
#>
#> strsplit
# Generate fragments based on our counts matrix
fragment_list <- list()
for (i in 1:ncol(counts)) {
cell_name <- colnames(counts)[i]
for (j in 1:nrow(counts)) {
cnt <- counts[j, i]
if (cnt > 0) {
parts <- strsplit(rownames(counts)[j], "-", fixed = TRUE)[[1]]
for (k in 1:cnt) {
fragment_list[[length(fragment_list) + 1]] <- data.frame(
chr = parts[1],
start = as.numeric(parts[2]) + k,
end = as.numeric(parts[3]) - k,
cell = cell_name,
count = 1
)
}
}
}
}
fragments_df <- bind_rows(fragment_list) %>%
arrange(chr, start) # Sorting is mandatory for indexing
# Write to a temporary text file
temp_txt <- "foo.fragments.txt"
write.table(
fragments_df, temp_txt,
sep = "\t",
row.names = FALSE, col.names = FALSE, quote = FALSE
)
# Bgzip compress and index (Requires Rsamtools)
# This creates foo.fragments.txt.gz and foo.fragments.txt.gz.tbi
bgzip(temp_txt, dest = "foo.fragments.txt.gz", overwrite = TRUE)
#> [1] "foo.fragments.txt.gz"
indexTabix("foo.fragments.txt.gz", format = "bed")
#> [1] "foo.fragments.txt.gz.tbi"
# Clean up the uncompressed temp file
file.remove(temp_txt)
#> [1] TRUElibrary(Signac)
library(Seurat)
#> Loading required package: SeuratObject
#> Loading required package: sp
#>
#> Attaching package: 'sp'
#> The following object is masked from 'package:IRanges':
#>
#> %over%
#> 'SeuratObject' was built under R 4.6.0 but the current version is
#> 4.6.1; it is recomended that you reinstall 'SeuratObject' as the ABI
#> for R may have changed
#> 'SeuratObject' was built with package 'Matrix' 1.7.5 but the current
#> version is 1.7.6; it is recomended that you reinstall 'SeuratObject' as
#> the ABI for 'Matrix' may have changed
#>
#> Attaching package: 'SeuratObject'
#> The following object is masked from 'package:Biostrings':
#>
#> intersect
#> The following object is masked from 'package:GenomicRanges':
#>
#> intersect
#> The following object is masked from 'package:IRanges':
#>
#> intersect
#> The following object is masked from 'package:S4Vectors':
#>
#> intersect
#> The following object is masked from 'package:Seqinfo':
#>
#> intersect
#> The following object is masked from 'package:BiocGenerics':
#>
#> intersect
#> The following objects are masked from 'package:base':
#>
#> intersect, t
#> v5.6 adds significant improvements in speed and efficiency, particularly for large datasets.
#> For more information, see https://satijalab.org/seurat/articles/announcements.
counts_loaded <- readRDS("foo.RDS")
fragment_file <- "foo.fragments.txt.gz"
chrom_assay <- CreateChromatinAssay(
counts = counts_loaded,
sep = c("-", "-"),
fragments = fragment_file,
min.cells = 10,
min.features = 0
)
#> Computing hash
chrom_obj <- CreateSeuratObject(
counts = chrom_assay,
assay = "peaks"
)
print(chrom_obj)
#> An object of class Seurat
#> 100 features across 20 samples within 1 assay
#> Active assay: peaks (100 features, 0 variable features)
#> 2 layers present: counts, dataThe first step is to generate the tRNA matrix and translate the peak fragments into tRNA gene names.
tRNA_matrix <- tRNAGetMatrix(
data = chrom_obj, assay = "peaks", confidence_set = NULL, species = "hg38"
)
#> 1 . Importing the high-confidence tRNA annotations.
#> The default hg38 'confidence_set' will be used.
#> 1 . COMPLETED
#> 2 . Filtering tRNA genes with unknown annotations.
#> Loading required namespace: Structstrings
#> The default hg38 'tRNA_name_map' will be used.
#> 2 . COMPLETED
#> 3 . Finding overlaps and aggregating tRNA counts.
#> Extracting reads overlapping genomic regions
#> 3 . COMPLETED#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04.1 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] stats4 stats graphics grDevices utils datasets methods
#> [8] base
#>
#> other attached packages:
#> [1] Seurat_5.6.0 SeuratObject_5.4.0 sp_2.2-4
#> [4] Signac_1.17.1 Rsamtools_2.29.0 Biostrings_2.81.9
#> [7] XVector_0.53.0 GenomicRanges_1.65.4 IRanges_2.47.5
#> [10] S4Vectors_0.51.10 Seqinfo_1.3.2 BiocGenerics_0.59.12
#> [13] generics_0.1.4 Matrix_1.7-6 dplyr_1.2.1
#> [16] biomaRt_2.69.4 tTEscanR_0.99.1 BiocStyle_2.41.0
#>
#> loaded via a namespace (and not attached):
#> [1] RcppAnnoy_0.0.23 splines_4.6.1
#> [3] later_1.4.8 bitops_1.1-0
#> [5] filelock_1.0.3 tibble_3.3.1
#> [7] polyclip_1.10-7 fastDummies_1.7.6
#> [9] lifecycle_1.0.5 httr2_1.3.0
#> [11] rstatix_1.1.0 globals_0.20.0
#> [13] lattice_0.23-1 MASS_7.3-66
#> [15] MultiAssayExperiment_1.39.1 backports_1.5.1
#> [17] magrittr_2.0.5 plotly_4.12.1
#> [19] sass_0.4.10 rmarkdown_2.32
#> [21] jquerylib_0.1.4 yaml_2.3.12
#> [23] httpuv_1.6.17 otel_0.2.0
#> [25] sctransform_0.4.3 spam_2.11-4
#> [27] spatstat.sparse_3.2-0 reticulate_1.47.0
#> [29] cowplot_1.2.0 pbapply_1.7-5
#> [31] DBI_1.3.0 buildtools_1.0.0
#> [33] RColorBrewer_1.1-3 abind_1.4-8
#> [35] Rtsne_0.17 purrr_1.2.2
#> [37] ggrepel_0.9.8 irlba_2.4.1
#> [39] spatstat.utils_3.2-5 listenv_1.1.0
#> [41] maketools_1.3.2 goftest_1.2-3
#> [43] RSpectra_0.16-2 spatstat.random_3.5-2
#> [45] fitdistrplus_1.2-6 parallelly_1.48.0
#> [47] codetools_0.2-20 DelayedArray_0.39.8
#> [49] RcppRoll_0.4.0 tidyselect_1.2.1
#> [51] UCSC.utils_1.9.0 farver_2.1.2
#> [53] matrixStats_1.5.0 BiocFileCache_3.3.0
#> [55] spatstat.explore_3.8-3 jsonlite_2.0.0
#> [57] progressr_1.0.0 Formula_1.2-6
#> [59] ggridges_0.5.7 survival_3.8-12
#> [61] tools_4.6.1 progress_1.2.3
#> [63] ica_1.0-3 Rcpp_1.1.2
#> [65] glue_1.8.1 gridExtra_2.3.1
#> [67] SparseArray_1.13.4 BiocBaseUtils_1.15.1
#> [69] xfun_0.61 DESeq2_1.53.6
#> [71] MatrixGenerics_1.25.0 GenomeInfoDb_1.49.1
#> [73] withr_3.0.3 BiocManager_1.30.27
#> [75] fastmap_1.2.0 digest_0.6.39
#> [77] R6_2.6.1 mime_0.13
#> [79] scattermore_1.2 tensor_1.5.1
#> [81] spatstat.data_3.1-9 RSQLite_3.53.3
#> [83] tidyr_1.3.2 data.table_1.18.6.1
#> [85] Structstrings_1.29.0 prettyunits_1.2.0
#> [87] httr_1.4.9 htmlwidgets_1.6.4
#> [89] S4Arrays_1.13.2 uwot_0.2.5
#> [91] pkgconfig_2.0.3 gtable_0.3.6
#> [93] blob_1.3.0 lmtest_0.9-40
#> [95] S7_0.2.2 sys_3.4.3
#> [97] htmltools_0.5.9 carData_3.0-6
#> [99] dotCall64_1.2 scales_1.4.0
#> [101] Biobase_2.73.2 png_0.1-9
#> [103] spatstat.univar_3.2-0 knitr_1.52
#> [105] reshape2_1.4.5 nlme_3.1-171
#> [107] curl_8.1.0 cachem_1.1.0
#> [109] zoo_1.9-1 stringr_1.6.0
#> [111] KernSmooth_2.23-27 parallel_4.6.1
#> [113] miniUI_0.1.2 AnnotationDbi_1.75.2
#> [115] pillar_1.11.1 grid_4.6.1
#> [117] vctrs_0.7.3 RANN_2.6.3
#> [119] promises_1.5.0 ggpubr_1.0.0
#> [121] car_3.1-5 dbplyr_2.6.0
#> [123] xtable_1.8-8 cluster_2.1.8.3
#> [125] evaluate_1.0.5 cli_3.6.6
#> [127] locfit_1.5-9.12 compiler_4.6.1
#> [129] rlang_1.3.0 crayon_1.5.3
#> [131] future.apply_1.20.2 ggsignif_0.6.4
#> [133] labeling_0.4.3 plyr_1.8.9
#> [135] stringi_1.8.9 deldir_2.0-4
#> [137] viridisLite_0.4.3 BiocParallel_1.47.0
#> [139] spatstat.geom_3.8-3 RcppHNSW_0.7.0
#> [141] hms_1.1.4 patchwork_1.3.2
#> [143] sparseMatrixStats_1.25.0 bit64_4.8.6
#> [145] future_1.76.0 ggplot2_4.0.3
#> [147] KEGGREST_1.53.6 shiny_1.14.0
#> [149] SummarizedExperiment_1.43.0 ROCR_1.0-12
#> [151] igraph_2.3.4 broom_1.0.13
#> [153] memoise_2.0.1 bslib_0.12.0
#> [155] fastmatch_1.1-8 bit_4.6.0