library(comapr)
library(GenomicRanges)
#> Loading required package: stats4
#> Loading required package: BiocGenerics
#>
#> Attaching package: 'BiocGenerics'
#> The following objects are masked from 'package:stats':
#>
#> IQR, mad, sd, var, xtabs
#> The following objects are masked from 'package:base':
#>
#> Filter, Find, Map, Position, Reduce, anyDuplicated, aperm, append,
#> as.data.frame, basename, cbind, colnames, dirname, do.call,
#> duplicated, eval, evalq, get, grep, grepl, intersect, is.unsorted,
#> lapply, mapply, match, mget, order, paste, pmax, pmax.int, pmin,
#> pmin.int, rank, rbind, rownames, sapply, saveRDS, setdiff, table,
#> tapply, union, unique, unsplit, which.max, which.min
#> Loading required package: S4Vectors
#>
#> Attaching package: 'S4Vectors'
#> The following object is masked from 'package:utils':
#>
#> findMatches
#> The following objects are masked from 'package:base':
#>
#> I, expand.grid, unname
#> Loading required package: IRanges
#> Loading required package: GenomeInfoDb
library(BiocParallel)
Install via BiocManager as follow:
comapr
lets you interrogate the genotyping results for a
sequence of markers across the chromosome and detect meiotic crossovers
from genotype shifts. In this document, we demonstrate how genetic
distances are calculated from genotyping results for a group of samples
using functions available from comapr
.
The package includes a small data object that contains 70 markers and their genotyping results for 22 samples. The 22 samples are the BC1F1 progenies generated by
Therefore, the genotype shifts detected in BC1F1 samples represent crossovers that have happened during meiosis for the F1 parents.
BiocParallel::register(SerialParam())
BiocParallel::bpparam()
#> class: SerialParam
#> bpisup: FALSE; bpnworkers: 1; bptasks: 0; bpjobname: BPJOB
#> bplog: FALSE; bpthreshold: INFO; bpstopOnError: TRUE
#> bpRNGseed: ; bptimeout: NA; bpprogressbar: FALSE
#> bpexportglobals: FALSE; bpexportvariables: FALSE; bpforceGC: FALSE
#> bpfallback: FALSE
#> bplogdir: NA
#> bpresultdir: NA
In order to detect crossovers from the 22 samples’ genotype results
(BC1F1 samples), we need to format the result into
Homo_ref
, Homo_alt
and Het
encodings. This can be simply done through comparing with the parents’
genotypes.
Here, the genotype noted as “Fail” will be converted to NA. Please also note that we supplied “Homo_ref” as one of the fail options because “Homo_ref” is not in the possible genotypes of markers in BC1F1 samples.
corrected_geno <- correctGT(gt_matrix = mcols(snp_geno_gr),
ref = parents_geno$ref,
alt = parents_geno$alt,
fail = "Fail",
wrong_label = "Homo_ref")
mcols(snp_geno_gr) <- corrected_geno
The corrected_geno
matrix
head(mcols(snp_geno_gr)[,1:5])
#> DataFrame with 6 rows and 5 columns
#> X92 X93 X94 X95 X96
#> <character> <character> <character> <character> <character>
#> 1 Homo_alt Homo_alt Homo_alt Homo_alt Homo_alt
#> 2 Homo_alt Homo_alt Homo_alt Homo_alt Homo_alt
#> 3 Homo_alt Homo_alt Homo_alt Homo_alt Homo_alt
#> 4 Homo_alt Homo_alt Homo_alt Homo_alt Homo_alt
#> 5 NA Homo_alt Homo_alt Homo_alt Homo_alt
#> 6 Het Homo_alt Homo_alt Homo_alt Homo_alt
Note that there are missing values in this resulting matrix that can be resulted from:
NA
In this step, we try to identify markers that have NA
genotype across many samples or samples that have a lot markers failed
for removal. We use the countGT
function for find bad
markers/samples.
The number of markes and samples are saved in a list returned by
countGT
genotype_counts$n_markers
#> [1] 30 33 33 33 33 33 31 31 32 33 33 33 32 33 33 33 32 32 33 32 33 33
genotype_counts$n_samples
#> [1] 22 22 22 22 18 22 22 22 22 22 22 21 22 22 22 22 22 22 22 22 22 22 22 22 22
#> [26] 22 22 22 16 22 22 21 22
We now filter out markers/samples by using function
filterGT
. min_markers
specifies at least how
many markers a sample needs to be kept. Likewise for
min_samples
.
A printed message contains information about how much markers or samples have been filtered.
Sample duplicates are identified by finding samples that share
exactly same genotypes across all available markers.
findDupSamples
can be applied and a threshold value is
provided and used as a cut-off on the percentage of same genotype
markers the duplicated samples should share.
dups <- findDupSamples(mcols(corrected_geno),
threshold = 0.99)
dups
#> X98
#> [1,] "X98"
#> [2,] "X99"
Now we remove the duplicated samples.
Crossovers are detected and counted through examining the patterns of
genotypes along the chromosome. When there is a shift from one genotype
block to another, a crossover is observed. This is done through calling
countCOs
function which returns a GRange
object with crossover counts for the list of marker intervals.
The crossover count values in the columns can be non-integer when one observed crossover can not be determined to be completely distributed to the marker interval in the corresponding row. The observed crossover is then distributed to the adjacent intervals proportionally to their interval base pair sizes.
marker_gr_cos <- countCOs(corrected_geno)
marker_gr_cos[1:5,1:5]
#> GRanges object with 5 ranges and 5 metadata columns:
#> seqnames ranges strand | X92 X93 X94
#> <Rle> <IRanges> <Rle> | <numeric> <numeric> <numeric>
#> [1] 1 6655965-21638463 * | 0.9358742 0 0
#> [2] 1 21638465-22665059 * | 0.0641258 0 0
#> [3] 1 22665061-34590735 * | 0.0000000 0 0
#> [4] 1 35033642-38996025 * | 0.0000000 0 0
#> [5] 2 4248665-5348752 * | 0.0000000 0 0
#> X95 X96
#> <numeric> <numeric>
#> [1] 0 0
#> [2] 0 0
#> [3] 0 0
#> [4] 0 0
#> [5] 0 0
#> -------
#> seqinfo: 4 sequences from an unspecified genome; no seqlengths
The genetic distances of marker intervals are calcuated based on the
crossover rates via applying mapping function, Kosambi
or
Haldane
by calling the calGeneticDist
function. The returned genetic distances are in unit of centiMorgan.
dist_gr <- calGeneticDist(marker_gr_cos,
mapping_fun = "k")
dist_gr[1:5,]
#> GRanges object with 5 ranges and 1 metadata column:
#> seqnames ranges strand | kosambi_cm
#> <Rle> <IRanges> <Rle> | <numeric>
#> [1] 1 6655965-21638463 * | 14.36279
#> [2] 1 21638465-22665059 * | 5.08472
#> [3] 1 22665061-34590735 * | 9.64156
#> [4] 1 35033642-38996025 * | 9.64156
#> [5] 2 4248665-5348752 * | 4.77638
#> -------
#> seqinfo: 4 sequences from an unspecified genome; no seqlengths
Alternatively, instead of returning the genetic distances in supplied
marker intervals, we can specify a bin_size
which tells
calGeneticDist
to return calculated genetic distances for
equally sized chromosome bins.
dist_bin_gr <- calGeneticDist(marker_gr_cos,bin_size = 1e6)
dist_bin_gr[1:5,]
#> GRanges object with 5 ranges and 1 metadata column:
#> seqnames ranges strand | kosambi_cm
#> <Rle> <IRanges> <Rle> | <numeric>
#> [1] 1 1-998753 * | 0
#> [2] 1 998754-1997506 * | 0
#> [3] 1 1997507-2996258 * | 0
#> [4] 1 2996259-3995011 * | 0
#> [5] 1 3995012-4993763 * | 0
#> -------
#> seqinfo: 4 sequences from mm10 genome
With genetic distances calculated, we can do a sum of all genetic distances across all marker intervals. We can see that we got the same total genetic distances for marker based intervals and the equally binned intervals.
comapr
also includes functions for visulising genetic
distances of marker intervals or binned intervals.
We can also plot the cumulative genetic distances of certain chromosomes
Multiple chromosomes
sessionInfo()
#> R version 4.4.1 (2024-06-14)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.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.26.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=C
#> [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] BiocParallel_1.39.0 GenomicRanges_1.57.2 GenomeInfoDb_1.41.2
#> [4] IRanges_2.39.2 S4Vectors_0.43.2 BiocGenerics_0.53.0
#> [7] comapr_1.11.0 BiocStyle_2.35.0
#>
#> loaded via a namespace (and not attached):
#> [1] RColorBrewer_1.1-3 shape_1.4.6.1
#> [3] sys_3.4.3 rstudioapi_0.17.1
#> [5] jsonlite_1.8.9 magrittr_2.0.3
#> [7] GenomicFeatures_1.57.1 farver_2.1.2
#> [9] rmarkdown_2.28 GlobalOptions_0.1.2
#> [11] BiocIO_1.17.0 zlibbioc_1.51.2
#> [13] vctrs_0.6.5 memoise_2.0.1
#> [15] Rsamtools_2.21.2 RCurl_1.98-1.16
#> [17] base64enc_0.1-3 htmltools_0.5.8.1
#> [19] S4Arrays_1.5.11 progress_1.2.3
#> [21] curl_5.2.3 SparseArray_1.5.45
#> [23] Formula_1.2-5 sass_0.4.9
#> [25] bslib_0.8.0 htmlwidgets_1.6.4
#> [27] plyr_1.8.9 Gviz_1.49.0
#> [29] httr2_1.0.5 plotly_4.10.4
#> [31] cachem_1.1.0 buildtools_1.0.0
#> [33] GenomicAlignments_1.41.0 iterators_1.0.14
#> [35] lifecycle_1.0.4 pkgconfig_2.0.3
#> [37] Matrix_1.7-1 R6_2.5.1
#> [39] fastmap_1.2.0 GenomeInfoDbData_1.2.13
#> [41] MatrixGenerics_1.17.1 digest_0.6.37
#> [43] colorspace_2.1-1 AnnotationDbi_1.69.0
#> [45] Hmisc_5.2-0 RSQLite_2.3.7
#> [47] labeling_0.4.3 filelock_1.0.3
#> [49] fansi_1.0.6 httr_1.4.7
#> [51] abind_1.4-8 compiler_4.4.1
#> [53] withr_3.0.2 bit64_4.5.2
#> [55] htmlTable_2.4.3 backports_1.5.0
#> [57] DBI_1.2.3 highr_0.11
#> [59] biomaRt_2.63.0 rappdirs_0.3.3
#> [61] DelayedArray_0.31.14 rjson_0.2.23
#> [63] tools_4.4.1 foreign_0.8-87
#> [65] nnet_7.3-19 glue_1.8.0
#> [67] restfulr_0.0.15 grid_4.4.1
#> [69] checkmate_2.3.2 reshape2_1.4.4
#> [71] cluster_2.1.6 generics_0.1.3
#> [73] gtable_0.3.6 BSgenome_1.73.1
#> [75] tidyr_1.3.1 ensembldb_2.29.1
#> [77] data.table_1.16.2 hms_1.1.3
#> [79] xml2_1.3.6 utf8_1.2.4
#> [81] XVector_0.45.0 foreach_1.5.2
#> [83] pillar_1.9.0 stringr_1.5.1
#> [85] circlize_0.4.16 dplyr_1.1.4
#> [87] BiocFileCache_2.15.0 lattice_0.22-6
#> [89] deldir_2.0-4 rtracklayer_1.65.0
#> [91] bit_4.5.0 biovizBase_1.55.0
#> [93] tidyselect_1.2.1 maketools_1.3.1
#> [95] Biostrings_2.75.0 knitr_1.48
#> [97] gridExtra_2.3 ProtGenerics_1.37.1
#> [99] SummarizedExperiment_1.35.5 xfun_0.48
#> [101] Biobase_2.67.0 matrixStats_1.4.1
#> [103] stringi_1.8.4 UCSC.utils_1.1.0
#> [105] lazyeval_0.2.2 yaml_2.3.10
#> [107] evaluate_1.0.1 codetools_0.2-20
#> [109] interp_1.1-6 tibble_3.2.1
#> [111] BiocManager_1.30.25 cli_3.6.3
#> [113] rpart_4.1.23 munsell_0.5.1
#> [115] jquerylib_0.1.4 dichromat_2.0-0.1
#> [117] Rcpp_1.0.13 dbplyr_2.5.0
#> [119] png_0.1-8 XML_3.99-0.17
#> [121] parallel_4.4.1 ggplot2_3.5.1
#> [123] blob_1.2.4 prettyunits_1.2.0
#> [125] latticeExtra_0.6-30 jpeg_0.1-10
#> [127] AnnotationFilter_1.31.0 bitops_1.0-9
#> [129] viridisLite_0.4.2 VariantAnnotation_1.51.2
#> [131] scales_1.3.0 purrr_1.0.2
#> [133] crayon_1.5.3 rlang_1.1.4
#> [135] KEGGREST_1.45.1