From 1455aff7c76add17228409b6373dc4ba454d2879 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Mon, 7 Apr 2025 22:54:32 +0200 Subject: [PATCH 01/36] [chore] add R project to ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 28c2b28c..9f6f84ef 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ src/*.dll docs/* .idea/* vignettes/web_only/*.html +immunr.Rproj From fbbb352444b64a2606cf77b7b3280c19eb872081 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 8 Apr 2025 01:11:51 +0200 Subject: [PATCH 02/36] [refactor] Refactor pretty much the whole package: fix doc links, move unnecessary dependencies to Suggests, create a startup message and a new vignette to start preparing users for 1.0.0 --- DESCRIPTION | 35 ++-- R/align_lineage.R | 2 +- R/annotation.R | 33 +--- R/clonality.R | 4 +- R/clustering.R | 32 +-- R/dimensions.R | 8 +- R/distance.R | 2 +- R/diversity.R | 4 +- R/dynamics.R | 4 +- R/explore.R | 4 +- R/gene_usage.R | 6 +- R/germline.R | 2 +- R/kmers.R | 4 +- R/overlap.R | 8 +- R/phylip.R | 5 +- R/preprocessing.R | 18 +- R/public.R | 4 +- R/sampling.R | 4 +- R/seqCluster.R | 11 +- R/shiny.R | 282 ++++++++++++++------------- R/singlecell.R | 4 +- R/spectratyping.R | 4 +- R/{vis.R => v0-vis.R} | 190 +++++++++++++----- R/zzz.R | 59 ++++++ immunr.Rproj | 1 + man/coding.Rd | 8 +- man/dbAnnotate.Rd | 10 +- man/geneUsage.Rd | 6 +- man/getKmers.Rd | 4 +- man/immunr_hclust.Rd | 16 +- man/immunr_pca.Rd | 8 +- man/inc_overlap.Rd | 4 +- man/pubRep.Rd | 4 +- man/repAlignLineage.Rd | 2 +- man/repClonality.Rd | 4 +- man/repDiversity.Rd | 4 +- man/repExplore.Rd | 4 +- man/repGermline.Rd | 2 +- man/repOverlap.Rd | 4 +- man/repSample.Rd | 4 +- man/select_barcodes.Rd | 4 +- man/seqCluster.Rd | 2 +- man/seqDist.Rd | 2 +- man/spectratype.Rd | 4 +- man/top.Rd | 8 +- man/trackClonotypes.Rd | 4 +- man/vis.Rd | 2 +- man/vis.clonal_family.Rd | 2 +- man/vis.clonal_family_tree.Rd | 2 +- man/vis.immunr_chao1.Rd | 2 +- man/vis.immunr_clonal_prop.Rd | 2 +- man/vis.immunr_dynamics.Rd | 2 +- man/vis.immunr_exp_vol.Rd | 2 +- man/vis.immunr_gene_usage.Rd | 4 +- man/vis.immunr_hclust.Rd | 4 +- man/vis.immunr_inc_overlap.Rd | 2 +- man/vis.immunr_kmeans.Rd | 12 +- man/vis.immunr_kmer_table.Rd | 2 +- man/vis.immunr_mds.Rd | 2 +- man/vis.immunr_ov_matrix.Rd | 4 +- man/vis.immunr_public_repertoire.Rd | 2 +- man/vis.immunr_public_statistics.Rd | 4 +- man/vis.step_failure_ignored.Rd | 2 +- man/vis_bar.Rd | 2 +- man/vis_box.Rd | 4 +- man/vis_circos.Rd | 6 +- man/vis_heatmap.Rd | 2 +- man/vis_heatmap2.Rd | 2 +- man/vis_hist.Rd | 4 +- man/vis_immunr_kmer_profile_main.Rd | 2 +- man/vis_public_clonotypes.Rd | 2 +- man/vis_public_frequencies.Rd | 2 +- man/vis_textlogo.Rd | 4 +- vignettes/immunarch_v1_migration.Rmd | 91 +++++++++ vignettes/v1_introduction.Rmd | 2 +- 75 files changed, 630 insertions(+), 383 deletions(-) rename R/{vis.R => v0-vis.R} (93%) create mode 100644 R/zzz.R create mode 100644 vignettes/immunarch_v1_migration.Rmd diff --git a/DESCRIPTION b/DESCRIPTION index eeca17eb..82b6f514 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,9 +1,10 @@ Package: immunarch Type: Package Title: Bioinformatics Analysis of T-Cell and B-Cell Immune Repertoires -Version: 0.9.1 +Version: 0.9.1.1 Authors@R: c( - person("Vadim I.", "Nazarov", , "support@immunomind.io", c("aut", "cre")), + person("Vadim", "Nazarov", "I.", "support@immunomind.com", role = c("aut", "cre"), + comment = c(ORCID = "0000-0003-3659-2709")), person("Vasily O.", "Tsvetkov", , role = "aut"), person("Siarhei", "Fiadziushchanka", , role = "aut"), person("Eugene", "Rumynskiy", , role = "aut"), @@ -28,26 +29,18 @@ License: Apache License (== 2.0) URL: https://immunarch.com/, https://github.com/immunomind/immunarch BugReports: https://github.com/immunomind/immunarch/issues Imports: - factoextra (>= 1.0.4), - fpc, - UpSetR (>= 1.4.0), + cli, pheatmap (>= 1.0.12), - ggrepel (>= 0.8.0), reshape2 (>= 1.4.2), circlize, MASS (>= 7.3), Rtsne (>= 0.15), - readxl (>= 1.3.1), - shiny (>= 1.4.0), - shinythemes, airr, ggseqlogo, - ggalluvial (>= 0.10.0), Rcpp (>= 1.0), magrittr, methods, scales, - ggpubr (>= 0.2), rlang (>= 0.4), plyr, purrr, @@ -58,16 +51,13 @@ Imports: tibble, tidyselect, tidyr, - igraph, ape, doParallel, rlist, utils, glue, - phangorn, uuid, - stringi, - ggraph + stringi Depends: R (>= 4.0.0), ggplot2 (>= 3.1.0), @@ -82,9 +72,20 @@ Suggests: testthat (>= 2.1.0), pkgdown (>= 0.1.0), assertthat, - rmarkdown + rmarkdown, + factoextra (>= 1.0.4), + fpc, + ggpubr (>= 0.2), + ggraph, + igraph, + phangorn, + ggalluvial (>= 0.10.0), + UpSetR (>= 1.4.0), + ggrepel (>= 0.8.0), + shiny (>= 1.4.0), + shinythemes VignetteBuilder: knitr Encoding: UTF-8 -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 LazyData: true LazyDataCompression: xz diff --git a/R/align_lineage.R b/R/align_lineage.R index a38ecdee..4e2a42a9 100644 --- a/R/align_lineage.R +++ b/R/align_lineage.R @@ -24,7 +24,7 @@ #' #' repAlignLineage(.data, .min_lineage_sequences, .prepare_threads, .align_threads, .nofail) #' -#' @param .data The data to be processed. Can be \link{data.frame}, \link{data.table} +#' @param .data The data to be processed. Can be \link{data.frame}, [data.table::data.table] #' or a list of these objects. #' #' @param .min_lineage_sequences If number of sequences in the same clonal lineage and the same diff --git a/R/annotation.R b/R/annotation.R index 2af67526..ff30d962 100644 --- a/R/annotation.R +++ b/R/annotation.R @@ -5,7 +5,6 @@ if (getRversion() >= "2.15.1") { #' Load clonotype databases such as VDJDB and McPAS into the R workspace #' -#' @importFrom readxl read_xlsx #' @importFrom readr read_csv read_tsv #' #' @concept annotation @@ -52,8 +51,8 @@ if (getRversion() >= "2.15.1") { #' @export dbLoad <- function(.path, .db, .species = NA, .chain = NA, .pathology = NA) { .db <- tolower(.db) - if (!(.db %in% c("vdjdb", "vdjdb-search", "mcpas", "mcpas-tcr", "pird", "tbadb"))) { - stop('Unknown .db argument. Please provide one of the following: "vdjdb", "vdjdb-search", "mcpas" or "tbadb"') + if (!(.db %in% c("vdjdb", "vdjdb-search", "mcpas", "mcpas-tcr", "pird"))) { + stop('Unknown .db argument. Please provide one of the following: "vdjdb", "vdjdb-search", "mcpas"') } if (.db == "vdjdb") { @@ -72,23 +71,6 @@ dbLoad <- function(.path, .db, .species = NA, .chain = NA, .pathology = NA) { db_file$Chain <- !is.na(db_file$CDR3.beta.aa) db_file$Chain <- "TRB" - } else if (.db == "tbadb") { - # ToDo: check for conflicting chains, such as TRB and BCR - sheet_index <- 1 - if (is.na(.chain)[1]) { - stop("TBAdb requires the .chain argument. Please specify it and try again.") - } - - chain_col <- paste0(.chain, collapse = "") - if (grepl("TRG", chain_col) || grepl("TRD", chain_col)) { - sheet_index <- 2 - } else if (grepl("IGH", chain_col) || grepl("IGL", chain_col) || grepl("IGK", chain_col)) { - sheet_index <- 3 - } - db_file <- read_xlsx(.path, sheet_index) - - db_file$Chain <- db_file$Locus - db_file$Pathology <- db_file$Disease.name } if (!is.na(.species)) { @@ -124,13 +106,14 @@ dbLoad <- function(.path, .db, .species = NA, .chain = NA, .pathology = NA) { } -#' Annotate clonotypes in immune repertoires using clonotype databases such as VDJDB and MCPAS +#' Annotate clonotypes in immune repertoires using clonotype databases (e.g., VDJDB, McPAS) #' #' @concept annotation #' -#' @description Annotate clonotypes using immune receptor databases with known condition-associated receptors. -#' Before using this function, you need to download database files first. -#' For more details see the tutorial \url{https://immunarch.com/articles/web_only/v11_db.html}. +#' @description +#' Annotate clonotypes by matching them to known condition-associated immune receptors in a database. +#' Before using this function, you must download or load the relevant database files. +#' For more information, see the [online tutorial](https://immunarch.com/articles/web_only/v11_db.html). #' #' @param .data The data to process. It can be a \link{data.frame}, a #' \link{data.table}, or a list of these objects. @@ -139,7 +122,7 @@ dbLoad <- function(.path, .db, .species = NA, .chain = NA, .pathology = NA) { #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/clonality.R b/R/clonality.R index 9b104aa0..f15c0882 100644 --- a/R/clonality.R +++ b/R/clonality.R @@ -8,13 +8,13 @@ #' clonal proportions in a given repertoire. #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/clustering.R b/R/clustering.R index 497c71e7..afbede35 100644 --- a/R/clustering.R +++ b/R/clustering.R @@ -4,8 +4,6 @@ #' #' @aliases immunr_hclust immunr_kmeans immunr_dbscan #' -#' @importFrom fpc dbscan -#' @importFrom factoextra hcut fviz_nbclust #' @importFrom stats kmeans as.dist cmdscale dist #' #' @description Clusters the data with one of the following methods: @@ -28,27 +26,27 @@ #' #' @param .k The number of clusters to create, defined as \code{k} to \link[factoextra]{hcut} or as \code{centers} to \link{kmeans}. #' -#' @param .k.max Limits the maximum number of clusters. It is passed as \code{k.max} to \link{fviz_nbclust} for \code{immunr_hclust} and \code{immunr_kmeans}. +#' @param .k.max Limits the maximum number of clusters. It is passed as \code{k.max} to [factoextra::fviz_nbclust] for \code{immunr_hclust} and \code{immunr_kmeans}. #' #' @param .eps Local radius for expanding clusters, minimal distance between points to expand clusters. Passed as \code{eps} to \link[fpc]{dbscan}. #' -#' @param .method Passed to \link[factoextra]{hcut} or as \link{fviz_nbclust}. +#' @param .method Passed to [factoextra::hcut] or as [factoextra::fviz_nbclust]. #' -#' In case of \link[factoextra]{hcut} the agglomeration method is going to be used (argument \code{hc_method}). +#' In case of [factoextra::hcut] the agglomeration method is going to be used (argument \code{hc_method}). #' -#' In case of \link{fviz_nbclust} it is the method to be used for estimating the optimal number of clusters (argument \code{method}). +#' In case of [factoextra::fviz_nbclust] it is the method to be used for estimating the optimal number of clusters (argument \code{method}). #' #' @param .dist If TRUE then ".data" is expected to be a distance matrix. If FALSE then the euclidean distance is computed for the input objects. #' #' @return -#' \code{immunr_hclust} - list with two elements. The first element is an output from \link{hcut}. -#' The second element is an output from \link{fviz_nbclust} +#' \code{immunr_hclust} - list with two elements. The first element is an output from [factoextra::hcut]. +#' The second element is an output from [factoextra::fviz_nbclust] #' #' \code{immunr_kmeans} - list with three elements. The first element is an output from \link{kmeans}. -#' The second element is an output from \link{fviz_nbclust}. +#' The second element is an output from [factoextra::fviz_nbclust]. #' The third element is the input dataset \code{.data}. #' -#' \code{immunr_dbscan} - list with two elements. The first element is an output from \link{dbscan}. +#' \code{immunr_dbscan} - list with two elements. The first element is an output from [fpc::dbscan]. #' The second element is the input dataset \code{.data}. #' #' @examples @@ -60,14 +58,22 @@ #' immunr_kmeans(t(as.matrix(gu[, -1]))) #' @export immunr_hclust immunr_kmeans immunr_dbscan immunr_hclust <- function(.data, .k = 2, .k.max = nrow(.data) - 1, .method = "complete", .dist = TRUE) { + + if (!requireNamespace("fpc", quietly = TRUE)) { + stop("Package 'fpc' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + if (!requireNamespace("factoextra", quietly = TRUE)) { + stop("Package 'factoextra' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + if (.dist) { dist_mat <- as.dist(.data) } else { dist_mat <- dist(.data) } res <- list( - hcut = add_class(hcut(dist_mat, k = .k, hc_method = .method), "immunr_hcut"), - nbclust = add_class(fviz_nbclust(.data, hcut, k.max = .k.max), "immunr_nbclust") + hcut = add_class(factoextra::hcut(dist_mat, k = .k, hc_method = .method), "immunr_hcut"), + nbclust = add_class(factoextra::fviz_nbclust(.data, factoextra::hcut, k.max = .k.max), "immunr_nbclust") ) add_class(res, "immunr_hclust") } @@ -75,7 +81,7 @@ immunr_hclust <- function(.data, .k = 2, .k.max = nrow(.data) - 1, .method = "co immunr_kmeans <- function(.data, .k = 2, .k.max = as.integer(sqrt(nrow(.data))) + 1, .method = c("silhouette", "gap_stat")) { res <- list( kmeans = add_class(kmeans(.data, .k), "immunr_kmeans"), - nbclust = add_class(fviz_nbclust(.data, kmeans, k.max = .k.max, .method[1]), "immunr_nbclust"), + nbclust = add_class(factoextra::fviz_nbclust(.data, kmeans, k.max = .k.max, .method[1]), "immunr_nbclust"), data = .data ) add_class(res, "immunr_kmeans") diff --git a/R/dimensions.R b/R/dimensions.R index 881bcb95..f92e88f0 100644 --- a/R/dimensions.R +++ b/R/dimensions.R @@ -41,8 +41,8 @@ default_scale_fun <- function(x) { #' @param .scale A function to apply to your data before passing it to any of #' dimensionality reduction algorithms. There is no scaling by default. #' -#' @param .perp The perplexity parameter for \link[Rtsne]{Rtsne}. Sepcifies the number -#' of neighbours each data point must have in the resulting plot. +#' @param .perp The perplexity parameter for \link[Rtsne]{Rtsne}. Specifies the number +#' of neighbors each data point must have in the resulting plot. #' #' @param .raw If TRUE then returns the non-processed output from dimensionality reduction #' algorithms. Pass FALSE if you want to visualise results. @@ -57,9 +57,9 @@ default_scale_fun <- function(x) { #' @return #' \code{immunr_pca} - an output from \link{prcomp}. #' -#' \code{immunr_mds} - an output from \link{isoMDS}. +#' \code{immunr_mds} - an output from \link[MASS]{isoMDS}. #' -#' \code{immunr_tsne} - an output from \link{Rtsne}. +#' \code{immunr_tsne} - an output from \\link[Rtsne]{Rtsne}. #' #' @seealso \link{vis.immunr_pca} for visualisations. #' diff --git a/R/distance.R b/R/distance.R index 45eddac5..55539483 100644 --- a/R/distance.R +++ b/R/distance.R @@ -16,7 +16,7 @@ #' .group_by = c("V.name", "J.name"), .group_by_seqLength = TRUE, .trim_genes = TRUE, ...) #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format \link{immunarch_data_format} #' diff --git a/R/diversity.R b/R/diversity.R index 0fd027b1..b0642094 100644 --- a/R/diversity.R +++ b/R/diversity.R @@ -24,13 +24,13 @@ if (getRversion() >= "2.15.1") { #' or FALSE (don't do normalisation), respectively. #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/dynamics.R b/R/dynamics.R index 7c4e7370..70152743 100644 --- a/R/dynamics.R +++ b/R/dynamics.R @@ -12,13 +12,13 @@ #' time points after vaccination. #' #' @param .data The data to process. It can be a \link{data.frame}, a -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/explore.R b/R/explore.R index acec387f..efea02c9 100644 --- a/R/explore.R +++ b/R/explore.R @@ -11,13 +11,13 @@ #' and sequence length distribution across the input dataset. #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/gene_usage.R b/R/gene_usage.R index bf66f361..25829704 100644 --- a/R/gene_usage.R +++ b/R/gene_usage.R @@ -12,16 +12,16 @@ if (getRversion() >= "2.15.1") { #' @description #' An utility function to analyse the immune receptor gene usage #' (IGHD, IGHJ, IDHV, IGIJ, IGKJ, IGKV, IGLJ, IGLV, TRAJ, TRAV, TRBD, etc.) -#' and statistics. For gene details run \code{gene_stats()}. +#' and statistics. For gene details run `gene_stats()`. #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections,or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/germline.R b/R/germline.R index 8d21a700..e7da4863 100644 --- a/R/germline.R +++ b/R/germline.R @@ -24,7 +24,7 @@ #' #' repGermline(.data, .species, .min_nuc_outside_cdr3, .threads) #' -#' @param .data The data to be processed. Can be \link{data.frame}, \link{data.table} +#' @param .data The data to be processed. Can be \link{data.frame}, [data.table::data.table] #' or a list of these objects. #' #' It must have columns in the immunarch compatible format \link{immunarch_data_format}. diff --git a/R/kmers.R b/R/kmers.R index 6560565b..5f6284b1 100644 --- a/R/kmers.R +++ b/R/kmers.R @@ -8,13 +8,13 @@ #' @aliases getKmers get.kmers makeKmerTable #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections,or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/overlap.R b/R/overlap.R index 5bc97436..2a2cfad5 100644 --- a/R/overlap.R +++ b/R/overlap.R @@ -11,13 +11,13 @@ #' sequences that are shared between individuals. #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. @@ -335,13 +335,13 @@ horn_index <- function(.x, .y) { #' @description For reference please look up https://www.pnas.org/content/111/16/5980 (Fig. 4). #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/phylip.R b/R/phylip.R index b96bba88..60c819c3 100644 --- a/R/phylip.R +++ b/R/phylip.R @@ -11,7 +11,6 @@ #' @importFrom stringi stri_replace_all_fixed #' @importFrom utils capture.output #' @importFrom parallel mclapply detectCores -#' @importFrom phangorn write.phyDat #' @importFrom ape read.tree #' @importFrom uuid UUIDgenerate #' @importFrom data.table fread @@ -143,6 +142,10 @@ process_dataframe <- function(df, vis_groups, .threads, sample_name = NA) { } process_cluster <- function(cluster_row, vis_groups) { + if (!requireNamespace("phangorn", quietly = TRUE)) { + stop("Package 'phangorn' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + # alignment, sequences and aa_frame_starts should be extracted from 1-element lists # because of these columns format alignment <- cluster_row[["Alignment"]][[1]] diff --git a/R/preprocessing.R b/R/preprocessing.R index 0a52eac4..98b7ddb7 100644 --- a/R/preprocessing.R +++ b/R/preprocessing.R @@ -4,21 +4,21 @@ #' #' @importFrom dplyr top_n collect #' -#' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' @param .data The data to be processed. Can be [data.frame], +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. #' @param .n Numeric. Number of the most abundant clonotypes to return. #' #' @return -#' Data frame with the \code{.n} most abundant clonotypes only. +#' Data frame with the `.n` most abundant clonotypes only. #' #' @examples #' data(immdata) @@ -62,14 +62,14 @@ top <- function(.data, .n = 10) { #' #' outofframes(.data) #' -#' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' @param .data The data to be processed. Can be [data.frame], +#' [data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, Apache Spark DataFrame from "copy_to" or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. @@ -81,7 +81,7 @@ top <- function(.data, .n = 10) { #' data(immdata) #' immdata_cod <- coding(immdata$data) #' immdata_cod1 <- coding(immdata$data[[1]]) -#' @export coding noncoding inframes outofframes +#' @export coding coding <- function(.data) { if (has_class(.data, "list")) { lapply(.data, coding) diff --git a/R/public.R b/R/public.R index 344c10d3..a7dd4bee 100644 --- a/R/public.R +++ b/R/public.R @@ -10,13 +10,13 @@ #' @importFrom dplyr full_join ungroup #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/sampling.R b/R/sampling.R index ee5b7790..d26868b5 100644 --- a/R/sampling.R +++ b/R/sampling.R @@ -25,13 +25,13 @@ #' Sample (downsample) repertoires using different approches. #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/seqCluster.R b/R/seqCluster.R index 8bbb37db..1847aeef 100644 --- a/R/seqCluster.R +++ b/R/seqCluster.R @@ -6,7 +6,6 @@ #' @importFrom magrittr %>% %<>% #' @importFrom reshape2 melt #' @importFrom dplyr group_by mutate ungroup select cur_group_id left_join -#' @importFrom igraph graph_from_data_frame clusters #' @importFrom reshape2 melt #' @importFrom tibble rownames_to_column #' @importFrom glue glue @@ -18,7 +17,7 @@ #' seqCluster(.data, .dist, .perc_similarity, .nt_similarity, .fixed_threshold) #' #' @param .data The data which was used to caluculate .dist object. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format \link{immunarch_data_format} #' @@ -44,6 +43,10 @@ #' @export seqCluster seqCluster <- function(.data, .dist, .perc_similarity, .nt_similarity, .fixed_threshold = 10) { + if (!requireNamespace("igraph", quietly = TRUE)) { + stop("Package 'igraph' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + grouping_cols <- attr(.dist, "group_by") matching_col <- attr(.dist, "col") trimmed <- attr(.dist, "trimmed") @@ -122,8 +125,8 @@ seqCluster <- function(.data, .dist, .perc_similarity, .nt_similarity, .fixed_th ifelse(x > t, NA, x) }, .y)) seq_clusters <- map(mat_dist, ~ melt(.x, na.rm = TRUE) %>% - graph_from_data_frame() %>% - clusters() %>% + igraph::graph_from_data_frame() %>% + igraph::clusters() %>% .$membership %>% melt() %>% suppressWarnings()) diff --git a/R/shiny.R b/R/shiny.R index dd5d0f88..7b2bd36b 100644 --- a/R/shiny.R +++ b/R/shiny.R @@ -10,11 +10,6 @@ if (getRversion() >= "2.15.1") { #' @aliases fixVis #' #' @importFrom graphics plot -#' @importFrom shiny fluidPage titlePanel sidebarLayout sidebarPanel downloadButton actionButton br -#' @importFrom shiny tabsetPanel tabPanel textOutput sliderInput checkboxInput selectInput textInput textAreaInput -#' @importFrom shiny mainPanel uiOutput renderText renderUI renderPlot plotOutput observe updateSliderInput -#' @importFrom shiny observeEvent downloadHandler splitLayout -#' @importFrom shinythemes shinytheme #' #' @description The \code{fixVis} is a built-in software tool for the manipulation #' of plots, such as adjusting title text font and size, axes, and more. It is a powerful @@ -41,43 +36,50 @@ fixVis <- function(.plot = NA) { objs <- list(title = .name) - objs <- c(objs, list(br())) + objs <- c(objs, list(shiny::br())) if (.is.title) { objs <- c(objs, list( - splitLayout( + shiny::splitLayout( cellWidths = c("60%", "40%"), - checkboxInput(.full("remove"), "Remove the legend"), - checkboxInput(.full("contin"), "Continuous?") + shiny::checkboxInput(.full("remove"), "Remove the legend"), + shiny::checkboxInput(.full("contin"), "Continuous?") ), - sliderInput(.full("ncol"), "Number of columns:", + shiny::sliderInput(.full("ncol"), "Number of columns:", min = 1, max = 40, value = 1, step = 1 ), - br(), - textInput(.full("text"), "Title text:", .name, placeholder = "Samples") + shiny::br(), + shiny::textInput(.full("text"), "Title text:", .name, placeholder = "Samples") )) } objs <- c(objs, list( - sliderInput(.full("size"), "Text size:", + shiny::sliderInput(.full("size"), "Text size:", min = 1, max = 40, value = ifelse(.is.title, 16, 11), step = .5 ), - sliderInput(.full("hjust"), "Text horizontal adjustment:", + shiny::sliderInput(.full("hjust"), "Text horizontal adjustment:", min = 0, max = 1, value = 0, step = .05 ), - sliderInput(.full("vjust"), "Text vertical adjustment:", + shiny::sliderInput(.full("vjust"), "Text vertical adjustment:", min = -4, max = 4, value = .5, step = .25 ), - sliderInput(.full("angle"), "Text angle:", + shiny::sliderInput(.full("angle"), "Text angle:", min = 0, max = 90, value = 0, step = 1 ), - selectInput( + shiny::selectInput( .full("face"), "Face:", list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic") ) )) - do.call(tabPanel, objs) + do.call(shiny::tabPanel, objs) + } + + if (!requireNamespace("shinythemes", quietly = TRUE)) { + stop("Package 'shinythemes' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + if (!requireNamespace("shiny", quietly = TRUE)) { + stop("Package 'shiny' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) } if (has_no_data(.plot)) { @@ -88,28 +90,28 @@ fixVis <- function(.plot = NA) { # #### UI #### # - ui <- fluidPage( - theme = shinytheme("cosmo"), - titlePanel("FixVis: make your plots publication-ready already!"), - sidebarLayout( - sidebarPanel( - downloadButton("save_plot", "Save"), - actionButton("console_plot", "Plot to R console"), - br(), - br(), - tabsetPanel( - tabPanel( + ui <- shiny::fluidPage( + theme = shinythemes::shinytheme("cosmo"), + shiny::titlePanel("FixVis: make your plots publication-ready already!"), + shiny::sidebarLayout( + shiny::sidebarPanel( + shiny::downloadButton("save_plot", "Save"), + shiny::actionButton("console_plot", "Plot to R console"), + shiny::br(), + shiny::br(), + shiny::tabsetPanel( + shiny::tabPanel( "General", - br(), - textOutput("save_text"), - br(), - # textOutput("save_text2"), - # br(), - sliderInput("plot_width", "Plot width (in):", min = 2, max = 24, value = 8), - sliderInput("plot_height", "Plot height (in):", min = 2, max = 20, value = 5), - checkboxInput("coord_flip", "Flip coordinates"), - # checkboxInput("do_interactive", "Interactive plot"), - selectInput("ggplot_theme", "Theme", + shiny::br(), + shiny::textOutput("save_text"), + shiny::br(), + # shiny::textOutput("save_text2"), + # shiny::br(), + shiny::sliderInput("plot_width", "Plot width (in):", min = 2, max = 24, value = 8), + shiny::sliderInput("plot_height", "Plot height (in):", min = 2, max = 20, value = 5), + shiny::checkboxInput("coord_flip", "Flip coordinates"), + # shiny::checkboxInput("do_interactive", "Interactive plot"), + shiny::selectInput("ggplot_theme", "Theme", selected = "Pubr", list( "Linedraw", @@ -124,60 +126,60 @@ fixVis <- function(.plot = NA) { ) ) ), - tabPanel( + shiny::tabPanel( "Title & subtitle", - br(), - tabsetPanel( - tabPanel( + shiny::br(), + shiny::tabsetPanel( + shiny::tabPanel( "Title", - br(), - textInput("title_text", "Title text:", "nice title text", placeholder = "Gene usage"), - sliderInput("title_text_size", "Title text size:", + shiny::br(), + shiny::textInput("title_text", "Title text:", "nice title text", placeholder = "Gene usage"), + shiny::sliderInput("title_text_size", "Title text size:", min = 1, max = 40, value = 25, step = .5 ), - sliderInput("title_text_hjust", "Title text horizontal adjustment:", + shiny::sliderInput("title_text_hjust", "Title text horizontal adjustment:", min = 0, max = 1, value = 0, step = .05 ), - sliderInput("title_text_vjust", "Title text vertical adjustment:", + shiny::sliderInput("title_text_vjust", "Title text vertical adjustment:", min = -4, max = 4, value = .5, step = .25 ), - sliderInput("title_text_angle", "Title text angle:", + shiny::sliderInput("title_text_angle", "Title text angle:", min = 0, max = 90, value = 0, step = 1 ), - selectInput( + shiny::selectInput( "title_face", "Face:", list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic") ) ), - tabPanel( + shiny::tabPanel( "Subtitle", - br(), - textAreaInput("subtitle_text", "Subtitle text:", "nice subtitle text", + shiny::br(), + shiny::textAreaInput("subtitle_text", "Subtitle text:", "nice subtitle text", placeholder = "Frequency of Variable gene segments presented in the input samples" ), - sliderInput("subtitle_text_size", "Subtitle text size:", + shiny::sliderInput("subtitle_text_size", "Subtitle text size:", min = 1, max = 40, value = 16, step = .5 ), - sliderInput("subtitle_text_hjust", "Subtitle text horizontal adjustment:", + shiny::sliderInput("subtitle_text_hjust", "Subtitle text horizontal adjustment:", min = 0, max = 1, value = 0, step = .05 ), - sliderInput("subtitle_text_vjust", "Subtitle text vertical adjustment:", + shiny::sliderInput("subtitle_text_vjust", "Subtitle text vertical adjustment:", min = -4, max = 4, value = .5, step = .25 ), - sliderInput("subtitle_text_angle", "Subtitle text angle:", + shiny::sliderInput("subtitle_text_angle", "Subtitle text angle:", min = 0, max = 90, value = 0, step = 1 ), - selectInput( + shiny::selectInput( "subtitle_face", "Face:", list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic") ) ) ) ), - tabPanel( + shiny::tabPanel( "Legends", - br(), - selectInput( + shiny::br(), + shiny::selectInput( "legend_position", "Legend position", list( "right", @@ -186,143 +188,143 @@ fixVis <- function(.plot = NA) { "left" ) ), - selectInput( + shiny::selectInput( "legend_box", "Legend arrangement", list( "vertical", "horizontal" ) ), - tabsetPanel( - tabPanel( + shiny::tabsetPanel( + shiny::tabPanel( "Color", - tabsetPanel( + shiny::tabsetPanel( make_legend_tab("col_title", "Title (color)", TRUE), make_legend_tab("col_text", "Labels (color)", FALSE) ) ), - tabPanel( + shiny::tabPanel( "Fill", - tabsetPanel( + shiny::tabsetPanel( make_legend_tab("fill_title", "Title (fill)", TRUE), make_legend_tab("fill_text", "Labels (fill)", FALSE) ) ), - tabPanel( + shiny::tabPanel( "Size", - tabsetPanel( + shiny::tabsetPanel( make_legend_tab("size_title", "Title (size)", TRUE), make_legend_tab("size_text", "Labels (size)", FALSE) ) ), - tabPanel( + shiny::tabPanel( "Shape", - tabsetPanel( + shiny::tabsetPanel( make_legend_tab("shape_title", "Title (shape)", TRUE), make_legend_tab("shape_text", "Labels (shape)", FALSE) ) ), - tabPanel( + shiny::tabPanel( "Linetype", - tabsetPanel( + shiny::tabsetPanel( make_legend_tab("linetype_title", "Title (linetype)", TRUE), make_legend_tab("linetype_text", "Labels (linetype)", FALSE) ) ) ) ), - tabPanel( + shiny::tabPanel( "X axis", - br(), - tabsetPanel( - tabPanel( + shiny::br(), + shiny::tabsetPanel( + shiny::tabPanel( "X title", - br(), - textInput("x_text", "X axis label:", "x axis text", placeholder = "V genes"), - checkboxInput("apply_x2y", "Apply X axis settings to Y axis"), - br(), - sliderInput("x_title_size", "X axis title text size:", + shiny::br(), + shiny::textInput("x_text", "X axis label:", "x axis text", placeholder = "V genes"), + shiny::checkboxInput("apply_x2y", "Apply X axis settings to Y axis"), + shiny::br(), + shiny::sliderInput("x_title_size", "X axis title text size:", min = 1, max = 40, value = 16, step = .5 ), - sliderInput("x_title_hjust", "X axis title text horizontal adjustment:", + shiny::sliderInput("x_title_hjust", "X axis title text horizontal adjustment:", min = 0, max = 1, value = 0.5, step = .05 ), - sliderInput("x_title_vjust", "X axis title text vertical adjustment:", + shiny::sliderInput("x_title_vjust", "X axis title text vertical adjustment:", min = -4, max = 4, value = .5, step = .25 ), - sliderInput("x_title_angle", "X axis title text angle:", + shiny::sliderInput("x_title_angle", "X axis title text angle:", min = 0, max = 90, value = 0, step = 1 ), - selectInput( + shiny::selectInput( "x_title_face", "Face:", list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic") ) ), - tabPanel( + shiny::tabPanel( "X ticks", - br(), - sliderInput("x_text_size", "X axis text size:", + shiny::br(), + shiny::sliderInput("x_text_size", "X axis text size:", min = 1, max = 40, value = 11, step = .5 ), - sliderInput("x_text_hjust", "X axis text horizontal adjustment:", + shiny::sliderInput("x_text_hjust", "X axis text horizontal adjustment:", min = -2, max = 2, value = .5, step = .1 ), - sliderInput("x_text_vjust", "X axis text vertical adjustment:", + shiny::sliderInput("x_text_vjust", "X axis text vertical adjustment:", min = -4, max = 4, value = .5, step = .25 ), - sliderInput("x_text_angle", "X axis text angle:", + shiny::sliderInput("x_text_angle", "X axis text angle:", min = 0, max = 90, value = 90, step = 1 ), - selectInput( + shiny::selectInput( "x_text_face", "Face:", list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic") ) ) ) ), - tabPanel( + shiny::tabPanel( "Y axis", - br(), - tabsetPanel( - tabPanel( + shiny::br(), + shiny::tabsetPanel( + shiny::tabPanel( "Y title", - br(), - textInput("y_text", "Y axis label:", "y axis text", placeholder = "Gene frequency"), - checkboxInput("apply_y2x", "Apply Y axis settings to X axis"), - br(), - sliderInput("y_title_size", "Y axis title text size:", + shiny::br(), + shiny::textInput("y_text", "Y axis label:", "y axis text", placeholder = "Gene frequency"), + shiny::checkboxInput("apply_y2x", "Apply Y axis settings to X axis"), + shiny::br(), + shiny::sliderInput("y_title_size", "Y axis title text size:", min = 1, max = 40, value = 16, step = .5 ), - sliderInput("y_title_hjust", "Y axis title text horizontal adjustment:", + shiny::sliderInput("y_title_hjust", "Y axis title text horizontal adjustment:", min = 0, max = 1, value = 0.5, step = .05 ), - sliderInput("y_title_vjust", "Y axis title text vertical adjustment:", + shiny::sliderInput("y_title_vjust", "Y axis title text vertical adjustment:", min = -4, max = 4, value = .5, step = .25 ), - sliderInput("y_title_angle", "Y axis title text angle:", + shiny::sliderInput("y_title_angle", "Y axis title text angle:", min = 0, max = 90, value = 90, step = 1 ), - selectInput( + shiny::selectInput( "y_title_face", "Face:", list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic") ) ), - tabPanel( + shiny::tabPanel( "Y ticks", - br(), - sliderInput("y_text_size", "Y axis text size:", + shiny::br(), + shiny::sliderInput("y_text_size", "Y axis text size:", min = 1, max = 40, value = 11, step = .5 ), - sliderInput("y_text_hjust", "Y axis text horizontal adjustment:", + shiny::sliderInput("y_text_hjust", "Y axis text horizontal adjustment:", min = -2, max = 2, value = .5, step = .1 ), - sliderInput("y_text_vjust", "Y axis text vertical adjustment:", + shiny::sliderInput("y_text_vjust", "Y axis text vertical adjustment:", min = -4, max = 4, value = .5, step = .25 ), - sliderInput("y_text_angle", "Y axis text angle:", + shiny::sliderInput("y_text_angle", "Y axis text angle:", min = 0, max = 90, value = 0, step = 1 ), - selectInput( + shiny::selectInput( "y_text_face", "Face:", list(Plain = "plain", Bold = "bold", Italic = "italic", "Bold Italic" = "bold.italic") ) @@ -331,8 +333,8 @@ fixVis <- function(.plot = NA) { ) ) ), - mainPanel( - uiOutput("main_plot", style = "position:fixed;") + shiny::mainPanel( + shiny::uiOutput("main_plot", style = "position:fixed;") ) ) ) @@ -476,40 +478,40 @@ fixVis <- function(.plot = NA) { .plot } - output$save_text <- renderText({ + output$save_text <- shiny::renderText({ 'To save the plot, press the "Save" button above or drag-n-drop the plot to your Desktop or into any file manager (Finder, File Explorer, etc.)' }) - output$save_text2 <- renderText({ + output$save_text2 <- shiny::renderText({ 'Note: saving via the "Save" button will be different from the drag-n-drop method due to R\'s peculiar properties.' }) - output$main_plot <- renderUI({ + output$main_plot <- shiny::renderUI({ # if (input$do_interactive) { # output$main_plot_helper = renderPlotly(ggplotly(create_plot(input))) # plotlyOutput("main_plot_helper") # } else { - output$main_plot_helper <- renderPlot(create_plot(input)) - plotOutput("main_plot_helper", width = input$plot_width * 72, height = input$plot_height * 72) + output$main_plot_helper <- shiny::renderPlot(create_plot(input)) + shiny::plotOutput("main_plot_helper", width = input$plot_width * 72, height = input$plot_height * 72) # } }) # # Assign X settings to Y # - observe({ + shiny::observe({ if (!is.null(input$apply_x2y)) { if (input$apply_x2y) { - updateSliderInput(session, "y_title_size", value = input$x_title_size) - updateSliderInput(session, "y_title_hjust", value = input$x_title_size) - updateSliderInput(session, "y_title_vjust", value = input$x_title_size) - updateSliderInput(session, "y_title_angle", value = input$x_title_size) + shiny::updateSliderInput(session, "y_title_size", value = input$x_title_size) + shiny::updateSliderInput(session, "y_title_hjust", value = input$x_title_size) + shiny::updateSliderInput(session, "y_title_vjust", value = input$x_title_size) + shiny::updateSliderInput(session, "y_title_angle", value = input$x_title_size) - updateSliderInput(session, "y_text_size", value = input$x_text_size) - updateSliderInput(session, "y_text_hjust", value = input$x_text_size) - updateSliderInput(session, "y_text_vjust", value = input$x_text_size) - updateSliderInput(session, "y_text_angle", value = input$x_text_size) + shiny::updateSliderInput(session, "y_text_size", value = input$x_text_size) + shiny::updateSliderInput(session, "y_text_hjust", value = input$x_text_size) + shiny::updateSliderInput(session, "y_text_vjust", value = input$x_text_size) + shiny::updateSliderInput(session, "y_text_angle", value = input$x_text_size) } } }) @@ -517,30 +519,30 @@ fixVis <- function(.plot = NA) { # # Vice versa: assign Y settings to X # - observe({ + shiny::observe({ if (!is.null(input$apply_y2x)) { if (input$apply_y2x) { - updateSliderInput(session, "x_title_size", value = input$y_title_size) - updateSliderInput(session, "x_title_hjust", value = input$y_title_hjust) - updateSliderInput(session, "x_title_vjust", value = input$y_title_vjust) - updateSliderInput(session, "x_title_angle", value = input$y_title_angle) + shiny::updateSliderInput(session, "x_title_size", value = input$y_title_size) + shiny::updateSliderInput(session, "x_title_hjust", value = input$y_title_hjust) + shiny::updateSliderInput(session, "x_title_vjust", value = input$y_title_vjust) + shiny::updateSliderInput(session, "x_title_angle", value = input$y_title_angle) - updateSliderInput(session, "x_text_size", value = input$y_text_size) - updateSliderInput(session, "x_text_hjust", value = input$y_text_hjust) - updateSliderInput(session, "x_text_vjust", value = input$y_text_vjust) - updateSliderInput(session, "x_text_angle", value = input$y_text_angle) + shiny::updateSliderInput(session, "x_text_size", value = input$y_text_size) + shiny::updateSliderInput(session, "x_text_hjust", value = input$y_text_hjust) + shiny::updateSliderInput(session, "x_text_vjust", value = input$y_text_vjust) + shiny::updateSliderInput(session, "x_text_angle", value = input$y_text_angle) } } }) - observeEvent(input$console_plot, { + shiny::observeEvent(input$console_plot, { plot(create_plot(input)) }) # # Save plots # - output$save_plot <- downloadHandler( + output$save_plot <- shiny::downloadHandler( filename = paste0("plot shiny ", Sys.time(), ".png"), content = function(file) { ggsave(file, plot = create_plot(input), width = input$plot_width, height = input$plot_height, device = "png") diff --git a/R/singlecell.R b/R/singlecell.R index b2074882..3f8ecd34 100644 --- a/R/singlecell.R +++ b/R/singlecell.R @@ -16,13 +16,13 @@ if (getRversion() >= "2.15.1") { #' and proportions are changed accordingly to the filtered barcodes. #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/spectratyping.R b/R/spectratyping.R index b1670076..e9b9debb 100644 --- a/R/spectratyping.R +++ b/R/spectratyping.R @@ -5,13 +5,13 @@ #' @importFrom dplyr summarise group_by #' #' @param .data The data to be processed. Can be \link{data.frame}, -#' \link{data.table}, or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' \link{immunarch_data_format} #' #' Competent users may provide advanced data representations: -#' DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +#' DBI database connections, or a list #' of these objects. They are supported with the same limitations as basic objects. #' #' Note: each connection must represent a separate repertoire. diff --git a/R/vis.R b/R/v0-vis.R similarity index 93% rename from R/vis.R rename to R/v0-vis.R index 164cdf87..ec621680 100644 --- a/R/vis.R +++ b/R/v0-vis.R @@ -12,6 +12,52 @@ if (getRversion() >= "2.15.1") { )) } +theme_pubr <- function (base_size = 12, base_family = "", border = FALSE, margin = TRUE, + legend = c("top", "bottom", "left", "right", "none"), x.text.angle = 0) +{ + half_line <- base_size/2 + if (!is.numeric(legend)) + legend <- match.arg(legend) + if (x.text.angle > 5) + xhjust <- 1 + else xhjust <- NULL + if (border) { + panel.border <- element_rect(fill = NA, colour = "black", + size = 0.7) + axis.line <- element_blank() + } + else { + panel.border <- element_blank() + axis.line = element_line(colour = "black", size = 0.5) + } + if (margin) + plot.margin <- margin(half_line, half_line, half_line, + half_line) + else plot.margin <- unit(c(0.5, 0.3, 0.3, 0.3), "mm") + .theme <- theme_bw(base_size = base_size, base_family = base_family) %+replace% + theme(panel.border = panel.border, panel.grid.major = element_blank(), + panel.grid.minor = element_blank(), axis.line = axis.line, + axis.text = element_text(color = "black"), legend.key = element_blank(), + strip.background = element_rect(fill = "#F2F2F2", + colour = "black", size = 0.7), plot.margin = plot.margin, + legend.position = legend, complete = TRUE) + if (x.text.angle != 0) + .theme <- .theme + theme(axis.text.x = element_text(angle = x.text.angle, + hjust = xhjust)) + .theme +} + + +rotate_x_text <- function (angle = 90, hjust = NULL, vjust = NULL, ...) +{ + if (missing(hjust) & angle > 5) + hjust <- 1 + if (missing(vjust) & angle == 90) + vjust <- 0.5 + theme(axis.text.x = element_text(angle = angle, hjust = hjust, + vjust = vjust, ...)) +} + ##### Utility functions ##### @@ -105,11 +151,8 @@ theme_cleveland2 <- function(rotate = TRUE) { #' @name vis #' #' @import ggplot2 -#' @importFrom factoextra fviz_cluster fviz_dend fviz_pca_ind #' @importFrom grDevices colorRampPalette #' @importFrom tidyr drop_na -#' @importFrom igraph graph_from_data_frame -#' @importFrom ggraph ggraph geom_edge_diagonal geom_node_point theme_graph #' #' @description Output from every function in immunarch can be visualised with a #' single function - \code{vis}. The \code{vis} automatically detects @@ -228,7 +271,7 @@ vis <- function(.data, ...) { #' #' - "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; #' -#' - "circos" - passes arguments to \link{vis_circos} and \link{chordDiagram} from the "circlize" package; +#' - "circos" - passes arguments to \link{vis_circos} and [circlize::chordDiagram] from the "circlize" package; #' #' @return #' A ggplot2, pheatmap or circlize object. @@ -465,14 +508,14 @@ vis_heatmap2 <- function(.data, .meta = NA, .by = NA, .title = NA, .color = colo #' #' @name vis_circos #' -#' @description Visualise matrices with the \link{chordDiagram} function +#' @description Visualise matrices with the [circlize::chordDiagram] function #' from the circlize package. #' #' @param .data Input matrix. #' #' @param .title The The text for the title of the plot. #' -#' @param ... Other arguments passed to \link{chordDiagram} from the 'circlize' package. +#' @param ... Other arguments passed to [circlize::chordDiagram] from the 'circlize' package. #' #' @return #' A circlize object. @@ -720,15 +763,13 @@ vis.immunr_public_repertoire <- function(.data, .plot = c("freq", "clonotypes"), #' #' @concept pubrep #' -#' @importFrom UpSetR upset fromExpression -#' #' @name vis.immunr_public_statistics #' #' @description Visualise public clonotype frequencies. #' #' @param .data Public repertoire - an output from the \link{pubRep} function. #' -#' @param ... Other arguments passsed directly to \link{upset}. +#' @param ... Other arguments passsed directly to [UpSetR::upset]. #' #' @return #' A ggplot2 object. @@ -740,9 +781,14 @@ vis.immunr_public_repertoire <- function(.data, .plot = c("freq", "clonotypes"), #' pubRepStatistics(pr) %>% vis() #' @export vis.immunr_public_statistics <- function(.data, ...) { + + if (!requireNamespace("UpSetR", quietly = TRUE)) { + stop("Package 'UpSetR' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + upsetr_data <- as.list(.data$Count) names(upsetr_data) <- .data$Group - upset(fromExpression(upsetr_data), ...) + UpSetR::upset(UpSetR::fromExpression(upsetr_data), ...) } @@ -1075,7 +1121,7 @@ vis_public_clonotypes <- function(.data, .x.rep = NA, .y.rep = NA, #' #' - "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; #' -#' - "circos" - passes arguments to \link{vis_circos} and \link{chordDiagram} from the "circlize" package. +#' - "circos" - passes arguments to \link{vis_circos} and [circlize::chordDiagram] from the "circlize" package. #' #' @return #' A ggplot2 object, pheatmap or circlize object. @@ -1158,7 +1204,7 @@ vis.immunr_gene_usage <- function(.data, .plot = c("hist", "box", "heatmap", "he #' #' @param .labs A character vector of length two with names for x-axis and y-axis, respectively. #' -#' @param .melt If TRUE then apply \link{melt} to the ".data" before plotting. +#' @param .melt If TRUE then apply [reshape2::melt] to the ".data" before plotting. #' In this case ".data" is supposed to be a data frame with the first character column reserved #' for names of genes and other numeric columns reserved to counts or frequencies of genes. #' Each numeric column should be associated with a specific repertoire sample. @@ -1338,7 +1384,7 @@ vis_hist <- function(.data, .by = NA, .meta = NA, .title = "Gene usage", .ncol = #' such as age, serostatus or hla. #' @param .title The text for the title of the plot. #' @param .labs Character vector of length two with names for x-axis and y-axis, respectively. -#' @param .melt If TRUE then apply \link{melt} to the ".data" before plotting. +#' @param .melt If TRUE then apply [reshape2::melt] to the ".data" before plotting. #' In this case ".data" is supposed to be a data frame with the first character column reserved #' for names of genes and other numeric columns reserved to counts or frequencies of genes. #' Each numeric column should be associated with a specific repertoire sample. @@ -1366,6 +1412,10 @@ vis_box <- function(.data, .by = NA, .meta = NA, .melt = TRUE, .labs = c("X", "Y"), .title = "Boxplot (.title argument)", .subtitle = "Subtitle (.subtitle argument)", .legend = NA, .leg.title = "Legend (.leg.title argument)", .legend.pos = "right") { + if (!requireNamespace("ggpubr", quietly = TRUE)) { + stop("Package 'ggpubr' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + if (.melt) { res <- reshape2::melt(.data) res <- res[1:nrow(res), ] @@ -1437,7 +1487,7 @@ vis_box <- function(.data, .by = NA, .meta = NA, .melt = TRUE, } } - p_df <- compare_means(Value ~ Group, .data, comparisons = comparisons, p.adjust.method = "holm") + p_df <- ggpubr::compare_means(Value ~ Group, .data, comparisons = comparisons, p.adjust.method = "holm") y_max <- max(.data$Value) p.value.y.coord <- rep(y_max, nrow(p_df)) @@ -1450,18 +1500,18 @@ vis_box <- function(.data, .by = NA, .meta = NA, .melt = TRUE, p.adj = format.pval(p.adj, digits = 1) ) - p <- p + geom_signif( + p <- p + ggpubr::geom_signif( data = p_df, aes(xmin = group1, xmax = group2, annotations = p.adj, y_position = y.coord), manual = TRUE, tip_length = 0.03, size = .5, inherit.aes = FALSE ) } else { # Seems fine... - # p_df = compare_means(Value ~ Group, group.by = "Grouping.var", method = "kruskal.test", .data, p.adjust.method = "holm") + # p_df = ggpubr::compare_means(Value ~ Group, group.by = "Grouping.var", method = "kruskal.test", .data, p.adjust.method = "holm") # print(p_df) p <- p + - stat_compare_means(aes(label = after_stat(p.adj)), + ggpubr::stat_compare_means(aes(label = after_stat(p.adj)), bracket.size = .5, size = .signif.label.size, label.y = max(.data$Value, na.rm = TRUE) * 1.07 ) @@ -1501,7 +1551,7 @@ vis_box <- function(.data, .by = NA, .meta = NA, .melt = TRUE, #' @aliases vis.immunr_hclust #' #' @param .data Clustering results from \link{repOverlapAnalysis} or \link{geneUsageAnalysis}. -#' @param .rect Passed to \link{fviz_dend} - whether to add a rectangle around groups. +#' @param .rect Passed to [factoextra::fviz_dend] - whether to add a rectangle around groups. #' @param .plot A character vector of length one or two specifying which plots to visualise. #' If "clust" then plot only the clustering. If "best" then plot the number of optimal clusters. #' If both then plot both. @@ -1518,9 +1568,13 @@ vis_box <- function(.data, .by = NA, .meta = NA, .melt = TRUE, #' repOverlapAnalysis(ov, "mds+hclust") %>% vis() #' @export vis.immunr_hclust <- function(.data, .rect = FALSE, .plot = c("clust", "best"), ...) { + if (!requireNamespace("factoextra", quietly = TRUE)) { + stop("Package 'factoextra' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + p1 <- NULL if ("clust" %in% .plot) { - p1 <- fviz_dend(.data[[1]], main = "Hierarchical clustering", rect = .rect) + p1 <- factoextra::fviz_dend(.data[[1]], main = "Hierarchical clustering", rect = .rect) } p2 <- NULL @@ -1552,11 +1606,11 @@ vis.immunr_hclust <- function(.data, .rect = FALSE, .plot = c("clust", "best"), #' @aliases vis.immunr_kmeans vis.immunr_dbscan #' #' @param .data Clustering results from \link{repOverlapAnalysis} or \link{geneUsageAnalysis}. -#' @param .point If TRUE then plot sample points. Passed to \link{fviz_cluster}. -#' @param .text If TRUE then plot text labels. Passed to \link{fviz_cluster}. -#' @param .ellipse If TRUE then plot ellipses around all samples. Passed to "ellipse" from \link{fviz_cluster}. -#' @param .point.size Size of points, passed to "pointsize" from \link{fviz_cluster}. -#' @param .text.size Size of text labels, passed to labelsize from \link{fviz_cluster}. +#' @param .point If TRUE then plot sample points. Passed to [factoextra::fviz_cluster]. +#' @param .text If TRUE then plot text labels. Passed to [factoextra::fviz_cluster]. +#' @param .ellipse If TRUE then plot ellipses around all samples. Passed to "ellipse" from [factoextra::fviz_cluster]. +#' @param .point.size Size of points, passed to "pointsize" from [factoextra::fviz_cluster]. +#' @param .text.size Size of text labels, passed to labelsize from [factoextra::fviz_cluster]. #' @param .plot A character vector of length one or two specifying which plots to visualise. #' If "clust" then plot only the clustering. If "best" then plot the number of optimal clusters. #' If both then plot both. @@ -1575,9 +1629,13 @@ vis.immunr_hclust <- function(.data, .rect = FALSE, .plot = c("clust", "best"), vis.immunr_kmeans <- function(.data, .point = TRUE, .text = TRUE, .ellipse = TRUE, .point.size = 2, .text.size = 10, .plot = c("clust", "best"), ...) { + if (!requireNamespace("factoextra", quietly = TRUE)) { + stop("Package 'factoextra' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + p1 <- NULL if ("clust" %in% .plot) { - p1 <- fviz_cluster(.data[[1]], + p1 <- factoextra::fviz_cluster(.data[[1]], data = .data[[3]], main = "K-means clustering", geom = c("point", "text")[c(.point, .text)], show.legend.text = FALSE, show.clust.cent = FALSE, repel = TRUE, ellipse = .ellipse, shape = 16, pointsize = .point.size, labelsize = .text.size, label.rectangle = TRUE @@ -1606,7 +1664,11 @@ vis.immunr_kmeans <- function(.data, .point = TRUE, .text = TRUE, .ellipse = TRU #' @export vis.immunr_dbscan <- function(.data, .point = TRUE, .text = TRUE, .ellipse = TRUE, .point.size = 2, .text.size = 10, .plot = c("clust", "best"), ...) { - fviz_cluster(.data[[1]], + if (!requireNamespace("factoextra", quietly = TRUE)) { + stop("Package 'factoextra' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + + factoextra::fviz_cluster(.data[[1]], data = .data[[2]], main = "DBSCAN clustering", geom = c("point", "text")[c(.point, .text)], show.legend.text = FALSE, show.clust.cent = FALSE, repel = TRUE, ellipse = .ellipse, shape = 16, pointsize = .point.size, labelsize = .text.size, label.rectangle = TRUE @@ -1623,8 +1685,6 @@ vis.immunr_dbscan <- function(.data, .point = TRUE, .text = TRUE, .ellipse = TRU #' #' @concept post_analysis #' -#' @importFrom ggpubr ggscatter -#' #' @aliases vis.immunr_mds vis.immunr_pca vis.immunr_tsne #' #' @param .data Output from analysis functions such as \link{geneUsageAnalysis} or @@ -1668,6 +1728,10 @@ vis.immunr_dbscan <- function(.data, .point = TRUE, .text = TRUE, .ellipse = TRU vis.immunr_mds <- function(.data, .by = NA, .meta = NA, .point = TRUE, .text = TRUE, .ellipse = TRUE, .point.size = 2, .text.size = 4, ...) { + if (!requireNamespace("factoextra", quietly = TRUE)) { + stop("Package 'factoextra' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + if (!.point & !.text) { stop("Error: Please provide at least one of the arguments: .point and .text") } @@ -1677,7 +1741,7 @@ vis.immunr_mds <- function(.data, .by = NA, .meta = NA, .ellipse <- FALSE } - fviz_pca_ind(.data, + factoextra::fviz_pca_ind(.data, habillage = group_res$group_column, geom = c("point", "text")[c(.point, .text)], repel = TRUE, addEllipses = .ellipse, mean.point = FALSE, pointshape = 16, pointsize = .point.size, labelsize = .text.size, label.rectangle = TRUE, show.legend.text = FALSE @@ -1691,6 +1755,10 @@ vis.immunr_mds <- function(.data, .by = NA, .meta = NA, vis.immunr_pca <- function(.data, .by = NA, .meta = NA, .point = TRUE, .text = TRUE, .ellipse = TRUE, .point.size = 2, .text.size = 4, ...) { + if (!requireNamespace("factoextra", quietly = TRUE)) { + stop("Package 'factoextra' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + if (!.point & !.text) { stop("Error: Please provide at least one of the arguments: .point and .text") } @@ -1700,7 +1768,7 @@ vis.immunr_pca <- function(.data, .by = NA, .meta = NA, .ellipse <- FALSE } - fviz_pca_ind(.data, + factoextra::fviz_pca_ind(.data, habillage = group_res$group_column, geom = c("point", "text")[c(.point, .text)], repel = TRUE, addEllipses = .ellipse, mean.point = FALSE, pointshape = 16, pointsize = .point.size, labelsize = .text.size, label.rectangle = TRUE, show.legend.text = FALSE @@ -1714,6 +1782,14 @@ vis.immunr_pca <- function(.data, .by = NA, .meta = NA, vis.immunr_tsne <- function(.data, .by = NA, .meta = NA, .point = TRUE, .text = TRUE, .ellipse = TRUE, .point.size = 2, .text.size = 4, ...) { + if (!requireNamespace("factoextra", quietly = TRUE)) { + stop("Package 'factoextra' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + + if (!requireNamespace("ggpubr", quietly = TRUE)) { + stop("Package 'ggpubr' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + .data <- data.frame(.data) colnames(.data) <- c("Dim1", "Dim2") .data$Sample <- row.names(.data) @@ -1725,7 +1801,7 @@ vis.immunr_tsne <- function(.data, .by = NA, .meta = NA, .ellipse <- FALSE } - ggscatter( + ggpubr::ggscatter( data = .data, x = "Dim1", y = "Dim2", color = "Group", ellipse = .ellipse, size = .point.size, point = .point, label = ifelse(.text, "Sample", NULL), repel = TRUE, label.rectangle = TRUE, show.legend.text = FALSE ) + @@ -2011,8 +2087,6 @@ vis.immunr_rare_prop <- function(.data, .by = NA, .meta = NA, .errorbars = c(0.0 #' #' @concept vis #' -#' @importFrom ggpubr compare_means geom_signif stat_compare_means theme_pubr rotate_x_text -#' #' @name vis_bar #' #' @param .data Data to visualise. @@ -2058,6 +2132,10 @@ vis_bar <- function(.data, .by = NA, .meta = NA, .errorbars = c(0.025, 0.975), . .subtitle = "Subtitle (.subtitle argument)", .legend = NA, .leg.title = "Legend (.leg.title argument)", .legend.pos = "right", .rotate_x = 90) { + if (!requireNamespace("ggpubr", quietly = TRUE)) { + stop("Package 'ggpubr' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + group_res <- process_metadata_arguments(.data, .by, .meta, .defgroupby) group_column <- group_res$name .data$Group <- group_res$group_column @@ -2156,7 +2234,7 @@ vis_bar <- function(.data, .by = NA, .meta = NA, .errorbars = c(0.025, 0.975), . } } - p_df <- compare_means(Value ~ Group, .data, comparisons = comparisons, p.adjust.method = "holm") + p_df <- ggpubr::compare_means(Value ~ Group, .data, comparisons = comparisons, p.adjust.method = "holm") y_max <- max(.data$Value) p.value.y.coord <- rep(y_max, nrow(p_df)) @@ -2169,18 +2247,18 @@ vis_bar <- function(.data, .by = NA, .meta = NA, .errorbars = c(0.025, 0.975), . p.adj = format.pval(p.adj, digits = 1) ) - p <- p + geom_signif( + p <- p + ggpubr::geom_signif( data = p_df, aes(xmin = group1, xmax = group2, annotations = p.adj, y_position = y.coord), manual = TRUE, tip_length = 0.03, size = .5, inherit.aes = FALSE ) } else { # Seems fine... - # p_df = compare_means(Value ~ Group, group.by = "Grouping.var", method = "kruskal.test", .data, p.adjust.method = "holm") + # p_df = ggpubr::compare_means(Value ~ Group, group.by = "Grouping.var", method = "kruskal.test", .data, p.adjust.method = "holm") # print(p_df) p <- p + - stat_compare_means(aes(label = after_stat(p.adj)), + ggpubr::stat_compare_means(aes(label = after_stat(p.adj)), bracket.size = .5, size = .signif.label.size, label.y = max(.data$Value, na.rm = TRUE) * 1.07 ) @@ -2414,6 +2492,11 @@ vis.immunr_dxx <- function(.data, .by = NA, .meta = NA, vis.immunr_rarefaction <- function(.data, .by = NA, .meta = NA, .mean = TRUE, .errors = TRUE, .log = FALSE, .labels = TRUE, ...) { + + if (!requireNamespace("ggrepel", quietly = TRUE)) { + stop("Package 'ggrepel' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + .muc.res <- .data group_res <- process_metadata_arguments(.data, .by, .meta) @@ -2719,7 +2802,7 @@ vis.immunr_kmer_table <- function(.data, .head = 100, .position = c("stack", "do #' @param .data Output from the \code{kmer.profile} function. #' @param .replace.zero.with.na if TRUE then replace all zeros with NAs, therefore letters with #' zero frequency wont appear at the plot. -#' @param .scheme Character. An argumentt passed to \link{geom_logo} specifying how to colour symbols. +#' @param .scheme Character. An argument passed to [ggseqlogo::geom_logo] specifying how to colour symbols. #' @param .width Width for jitter, i.e., how much points will scatter around the verical line. Pass 0 (zero) #' to plot points on the straight vertical line for each position. #' @param ... Not used here. @@ -2743,6 +2826,10 @@ vis.immunr_kmer_table <- function(.data, .head = 100, .position = c("stack", "do vis_textlogo <- function(.data, .replace.zero.with.na = TRUE, .width = 0.1, ...) { # ToDo: make different color schemas, for type of aminoacids (polarity, etc), etc + if (!requireNamespace("ggrepel", quietly = TRUE)) { + stop("Package 'ggrepel' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + .data <- reshape2::melt(.data) if (.replace.zero.with.na) { .data$value[.data$value == 0] <- NA @@ -2833,7 +2920,6 @@ vis.immunr_kmer_profile_self <- function(.data, .plot = c("textlogo", "seqlogo") #' @concept dynamics #' #' @importFrom data.table setnames melt.data.table -#' @importFrom ggalluvial geom_flow geom_stratum #' #' @name vis.immunr_dynamics #' @@ -2896,6 +2982,11 @@ vis.immunr_kmer_profile_self <- function(.data, .plot = c("textlogo", "seqlogo") #' vis(tc, .order = sample_order) #' @export vis.immunr_dynamics <- function(.data, .plot = c("smooth", "area", "line"), .order = NA, .log = FALSE, ...) { + + if (!requireNamespace("ggalluvial", quietly = TRUE)) { + stop("Package 'ggalluvial' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + .plot <- .plot[1] if (!(.plot %in% c("smooth", "area", "line"))) { stop("Error: unknown plot identifier \"", .plot, "\". Please provide one of the following: \"smooth\", \"area\" or \"line\".") @@ -2934,8 +3025,8 @@ vis.immunr_dynamics <- function(.data, .plot = c("smooth", "area", "line"), .ord if (.plot == "smooth") { p <- p + - geom_flow() + - geom_stratum() + ggalluvial::geom_flow() + + ggalluvial::geom_stratum() } else if (.plot == "area") { p <- p + geom_area(aes(group = Clonotype), color = "black") @@ -3027,17 +3118,24 @@ vis.clonal_family <- function(.data, ...) { #' } #' @export vis.clonal_family_tree <- function(.data, ...) { + if (!requireNamespace("ggraph", quietly = TRUE)) { + stop("Package 'ggraph' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + if (!requireNamespace("igraph", quietly = TRUE)) { + stop("Package 'igraph' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) + } + links_df <- .data[c("Ancestor", "Name")] %>% drop_na("Ancestor") names(links_df) <- c("from", "to") vertices_df <- .data[c("Name", "Type", "Clones")] names(vertices_df)[1] <- "name" - tree_graph <- graph_from_data_frame(links_df, vertices = vertices_df) %>% - ggraph("tree") + - geom_edge_diagonal() + - geom_node_point(aes(color = Type, size = Clones)) + - theme_graph(base_family = "sans") + tree_graph <- igraph::graph_from_data_frame(links_df, vertices = vertices_df) %>% + ggraph::ggraph("tree") + + ggraph::geom_edge_diagonal() + + ggraph::geom_node_point(aes(color = Type, size = Clones)) + + ggraph::theme_graph(base_family = "sans") return(tree_graph) } diff --git a/R/zzz.R b/R/zzz.R new file mode 100644 index 00000000..60ee1ca2 --- /dev/null +++ b/R/zzz.R @@ -0,0 +1,59 @@ +#' @importFrom cli cli_h1 cli_alert_warning cli_par cli_text cli_end cli_alert_info cli_bullets spark_line cli_alert_success +#' @importFrom stats runif +.onAttach <- function(libname, pkgname) { + # TODO: supress https://github.com/r-lib/cli/issues/589 + # TODO: remove non-ASCII characters folder-like + # TODO: figure out the middle name stuff + # TODO: put dependendies in the cran-comments + + cli::cli_h1("{cli::col_green('immunarch')} {cli::col_yellow('0.9.x')} – Critical Pre-release Notice") + + + cli::cli_alert_warning("Update #1 [Apr 2025] -- Major changes are coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}!") + cli::cli_text(cli::col_yellow(cli::spark_line(runif(110, 0, 1)))) + + cli::cli_par() + cli::cli_text() + cli::cli_text( + "Hi, this is Vadim Nazarov speaking -- author of {cli::col_green('immunarch')}. ", + "{cli::col_green('immunarch')} is finally graduating from out of the {cli::col_yellow('0.x.y')} development cycle. ", + "I'm preparing our {cli::col_yellow('1.0.0')} release, which will remain stable and free of sudden changes until we approach {cli::col_yellow('2.0.0')}, along with ", + "a scientific publication for proper citations. ", + "Significant changes are coming, and I want to ensure you have everything you need to migrate to the new version." + ) + + cli::cli_par() + cli::cli_text() + cli::cli_text("Here’s a preview of what's coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}:") + cli::cli_bullets(c( + "i" = "Some computationally intensive or advanced features (e.g., distance computations, graph-based analyses, dimensionality reduction techniques) will move to separate packages, making {cli::col_green('immunarch')} much more lightweight to install and manage;", + "i" = "New functions will be introduced instead of the left old ones to make code more readable and maintainable. Legacy functions will remain temporarily, but they won't be updated and will be removed by {cli::col_yellow('~2027')};", + "i" = "We will discontinue support for most custom file formats because the AIRR ecosystem is now mature enough that the majority of tools adhere to the AIRR standard;", + "i" = "The package will transition from data frames to the new {cli::col_blue('ImmunData')} structure -- better suited for handling modern larger, more complex, and multi-modal datasets (e.g., single-cell, spatial);", + "i" = "{cli::col_blue('ImmunData')} is available in the separate {cli::col_blue('immundata')} package, which you can already install via {cli::col_cyan('install.packages(\"immundata\")')};", + "i" = "The {cli::col_blue('ImmunData')}-based computations will be significantly faster, support datasets larger than RAM, and fully adhere to AIRR Community standards." + )) + + cli::cli_par() + cli::cli_text() + cli::cli_text( + "See the dedicated migration guide for migration on what you can do now and how to prepare for the future:" + ) + cli::cli_text("├─ run {cli::col_cyan('vignette(\"immunarch_v1_migration\")')}, or") + cli::cli_text("└─ visit {cli::col_cyan('https://immunarch.com/articles/immunarch_v1_migration.html')}") + + cli::cli_par() + cli::cli_text() + cli::cli_alert_warning("Keep an eye on the update number and date at the beginning. I’ll share updates, tips, and important dates for our major transformation. If you happen to miss some update, call {cli::col_cyan('immunarch::immunarch_updates()')} to read previous updates.") + + cli::cli_par() + cli::cli_text() + cli::cli_alert_success("Thank you for supporting {cli::col_green('immunarch')} from its early days. Your feedback, contributions, and trust have driven its evolution, and I deeply appreciate it.") + + cli::cli_par() + cli::cli_text() + cli::cli_alert_info("Questions, comments, ideas? I'm available via:") + cli::cli_text("├─ Support email: {cli::col_cyan('support@immunomind.com')}") + cli::cli_text("├─ GitHub tickets: {cli::col_cyan('https://github.com/immunomind/immunarch')}") + cli::cli_text("└─ LinkedIn: {cli::col_cyan('https://www.linkedin.com/in/vdnaz/')}") +} diff --git a/immunr.Rproj b/immunr.Rproj index bc9a80da..533e5cdf 100644 --- a/immunr.Rproj +++ b/immunr.Rproj @@ -1,4 +1,5 @@ Version: 1.0 +ProjectId: da9e8f01-a5c3-4f70-bcaf-16f0a2db91d0 RestoreWorkspace: Default SaveWorkspace: Default diff --git a/man/coding.Rd b/man/coding.Rd index 0283251d..596efb92 100644 --- a/man/coding.Rd +++ b/man/coding.Rd @@ -16,14 +16,14 @@ inframes(.data) outofframes(.data) } \arguments{ -\item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +\item{.data}{The data to be processed. Can be [data.frame], +[data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. -\link{immunarch_data_format} +[immunarch_data_format] Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, Apache Spark DataFrame from "copy_to" or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/dbAnnotate.Rd b/man/dbAnnotate.Rd index 4e4e2979..4d1deff4 100644 --- a/man/dbAnnotate.Rd +++ b/man/dbAnnotate.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/annotation.R \name{dbAnnotate} \alias{dbAnnotate} -\title{Annotate clonotypes in immune repertoires using clonotype databases such as VDJDB and MCPAS} +\title{Annotate clonotypes in immune repertoires using clonotype databases (e.g., VDJDB, McPAS)} \usage{ dbAnnotate(.data, .db, .data.col, .db.col) } @@ -14,7 +14,7 @@ Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} @@ -31,9 +31,9 @@ to CDR3 amino acid sequences, and the second column must correspond to V gene se Data frame with input sequences and counts or proportions for each of the input repertoire. } \description{ -Annotate clonotypes using immune receptor databases with known condition-associated receptors. -Before using this function, you need to download database files first. -For more details see the tutorial \url{https://immunarch.com/articles/web_only/v11_db.html}. +Annotate clonotypes by matching them to known condition-associated immune receptors in a database. +Before using this function, you must download or load the relevant database files. +For more information, see the [online tutorial](https://immunarch.com/articles/web_only/v11_db.html). } \examples{ data(immdata) diff --git a/man/geneUsage.Rd b/man/geneUsage.Rd index f83ff5f4..6ac9725f 100644 --- a/man/geneUsage.Rd +++ b/man/geneUsage.Rd @@ -17,13 +17,13 @@ geneUsage( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections,or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} @@ -60,7 +60,7 @@ A data frame with rows corresponding to gene segments and columns corresponding \description{ An utility function to analyse the immune receptor gene usage (IGHD, IGHJ, IDHV, IGIJ, IGKJ, IGKV, IGLJ, IGLV, TRAJ, TRAV, TRBD, etc.) -and statistics. For gene details run \code{gene_stats()}. +and statistics. For gene details run `gene_stats()`. } \examples{ data(immdata) diff --git a/man/getKmers.Rd b/man/getKmers.Rd index bfa423d8..2aedd9a2 100644 --- a/man/getKmers.Rd +++ b/man/getKmers.Rd @@ -10,13 +10,13 @@ getKmers(.data, .k, .col = c("aa", "nt"), .coding = TRUE) } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections,or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/immunr_hclust.Rd b/man/immunr_hclust.Rd index 3b2f2617..a8f468f1 100644 --- a/man/immunr_hclust.Rd +++ b/man/immunr_hclust.Rd @@ -18,27 +18,27 @@ immunr_dbscan(.data, .eps, .dist = TRUE) \item{.k}{The number of clusters to create, defined as \code{k} to \link[factoextra]{hcut} or as \code{centers} to \link{kmeans}.} -\item{.k.max}{Limits the maximum number of clusters. It is passed as \code{k.max} to \link{fviz_nbclust} for \code{immunr_hclust} and \code{immunr_kmeans}.} +\item{.k.max}{Limits the maximum number of clusters. It is passed as \code{k.max} to [factoextra::fviz_nbclust] for \code{immunr_hclust} and \code{immunr_kmeans}.} -\item{.method}{Passed to \link[factoextra]{hcut} or as \link{fviz_nbclust}. +\item{.method}{Passed to [factoextra::hcut] or as [factoextra::fviz_nbclust]. -In case of \link[factoextra]{hcut} the agglomeration method is going to be used (argument \code{hc_method}). +In case of [factoextra::hcut] the agglomeration method is going to be used (argument \code{hc_method}). -In case of \link{fviz_nbclust} it is the method to be used for estimating the optimal number of clusters (argument \code{method}).} +In case of [factoextra::fviz_nbclust] it is the method to be used for estimating the optimal number of clusters (argument \code{method}).} \item{.dist}{If TRUE then ".data" is expected to be a distance matrix. If FALSE then the euclidean distance is computed for the input objects.} \item{.eps}{Local radius for expanding clusters, minimal distance between points to expand clusters. Passed as \code{eps} to \link[fpc]{dbscan}.} } \value{ -\code{immunr_hclust} - list with two elements. The first element is an output from \link{hcut}. -The second element is an output from \link{fviz_nbclust} +\code{immunr_hclust} - list with two elements. The first element is an output from [factoextra::hcut]. +The second element is an output from [factoextra::fviz_nbclust] \code{immunr_kmeans} - list with three elements. The first element is an output from \link{kmeans}. -The second element is an output from \link{fviz_nbclust}. +The second element is an output from [factoextra::fviz_nbclust]. The third element is the input dataset \code{.data}. -\code{immunr_dbscan} - list with two elements. The first element is an output from \link{dbscan}. +\code{immunr_dbscan} - list with two elements. The first element is an output from [fpc::dbscan]. The second element is the input dataset \code{.data}. } \description{ diff --git a/man/immunr_pca.Rd b/man/immunr_pca.Rd index ecca8196..1703739e 100644 --- a/man/immunr_pca.Rd +++ b/man/immunr_pca.Rd @@ -26,17 +26,17 @@ if you want to visualise results.} \item{.dist}{If TRUE then assumes that ".data" is a distance matrix.} -\item{.perp}{The perplexity parameter for \link[Rtsne]{Rtsne}. Sepcifies the number -of neighbours each data point must have in the resulting plot.} +\item{.perp}{The perplexity parameter for \link[Rtsne]{Rtsne}. Specifies the number +of neighbors each data point must have in the resulting plot.} \item{...}{Other parameters passed to \link[Rtsne]{Rtsne}.} } \value{ \code{immunr_pca} - an output from \link{prcomp}. -\code{immunr_mds} - an output from \link{isoMDS}. +\code{immunr_mds} - an output from \link[MASS]{isoMDS}. -\code{immunr_tsne} - an output from \link{Rtsne}. +\code{immunr_tsne} - an output from \\link[Rtsne]{Rtsne}. } \description{ Collects a set of principal variables, reducing the number of not important variables diff --git a/man/inc_overlap.Rd b/man/inc_overlap.Rd index 64bea612..8d5c0043 100644 --- a/man/inc_overlap.Rd +++ b/man/inc_overlap.Rd @@ -17,13 +17,13 @@ inc_overlap( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/pubRep.Rd b/man/pubRep.Rd index 49fd4df1..d268a9a7 100644 --- a/man/pubRep.Rd +++ b/man/pubRep.Rd @@ -17,13 +17,13 @@ pubRep( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/repAlignLineage.Rd b/man/repAlignLineage.Rd index 577ab94a..8f00427d 100644 --- a/man/repAlignLineage.Rd +++ b/man/repAlignLineage.Rd @@ -7,7 +7,7 @@ repAlignLineage(.data, .min_lineage_sequences, .prepare_threads, .align_threads, .nofail) } \arguments{ -\item{.data}{The data to be processed. Can be \link{data.frame}, \link{data.table} +\item{.data}{The data to be processed. Can be \link{data.frame}, [data.table::data.table] or a list of these objects.} \item{.min_lineage_sequences}{If number of sequences in the same clonal lineage and the same diff --git a/man/repClonality.Rd b/man/repClonality.Rd index 11bbb29c..be0d009b 100644 --- a/man/repClonality.Rd +++ b/man/repClonality.Rd @@ -22,13 +22,13 @@ repClonality( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/repDiversity.Rd b/man/repDiversity.Rd index 1f72f601..7254ca74 100644 --- a/man/repDiversity.Rd +++ b/man/repDiversity.Rd @@ -30,13 +30,13 @@ repDiversity( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/repExplore.Rd b/man/repExplore.Rd index dcc39b0c..681a45ff 100644 --- a/man/repExplore.Rd +++ b/man/repExplore.Rd @@ -13,13 +13,13 @@ repExplore( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/repGermline.Rd b/man/repGermline.Rd index c3acad2e..529a12be 100644 --- a/man/repGermline.Rd +++ b/man/repGermline.Rd @@ -7,7 +7,7 @@ repGermline(.data, .species, .min_nuc_outside_cdr3, .threads) } \arguments{ -\item{.data}{The data to be processed. Can be \link{data.frame}, \link{data.table} +\item{.data}{The data to be processed. Can be \link{data.frame}, [data.table::data.table] or a list of these objects. It must have columns in the immunarch compatible format \link{immunarch_data_format}.} diff --git a/man/repOverlap.Rd b/man/repOverlap.Rd index 75201b13..bed5ae5d 100644 --- a/man/repOverlap.Rd +++ b/man/repOverlap.Rd @@ -22,13 +22,13 @@ repOverlap( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/repSample.Rd b/man/repSample.Rd index 008ab92c..c607814d 100644 --- a/man/repSample.Rd +++ b/man/repSample.Rd @@ -13,13 +13,13 @@ repSample( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/select_barcodes.Rd b/man/select_barcodes.Rd index ebca611a..07bfdb1c 100644 --- a/man/select_barcodes.Rd +++ b/man/select_barcodes.Rd @@ -8,13 +8,13 @@ select_barcodes(.data, .barcodes, .force.list = FALSE) } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/seqCluster.Rd b/man/seqCluster.Rd index e726ad0b..53348193 100644 --- a/man/seqCluster.Rd +++ b/man/seqCluster.Rd @@ -8,7 +8,7 @@ seqCluster(.data, .dist, .perc_similarity, .nt_similarity, .fixed_threshold) } \arguments{ \item{.data}{The data which was used to caluculate .dist object. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format \link{immunarch_data_format}} diff --git a/man/seqDist.Rd b/man/seqDist.Rd index 6ae7762c..6d6aae8d 100644 --- a/man/seqDist.Rd +++ b/man/seqDist.Rd @@ -9,7 +9,7 @@ seqDist(.data, .col = 'CDR3.nt', .method = 'hamming', } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format \link{immunarch_data_format}} diff --git a/man/spectratype.Rd b/man/spectratype.Rd index b52d9dc0..f099b0ba 100644 --- a/man/spectratype.Rd +++ b/man/spectratype.Rd @@ -8,13 +8,13 @@ spectratype(.data, .quant = c("id", "count"), .col = "nt") } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/top.Rd b/man/top.Rd index ec7f63d0..2acc8014 100644 --- a/man/top.Rd +++ b/man/top.Rd @@ -7,14 +7,14 @@ top(.data, .n = 10) } \arguments{ -\item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +\item{.data}{The data to be processed. Can be [data.frame], +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} @@ -22,7 +22,7 @@ Note: each connection must represent a separate repertoire.} \item{.n}{Numeric. Number of the most abundant clonotypes to return.} } \value{ -Data frame with the \code{.n} most abundant clonotypes only. +Data frame with the `.n` most abundant clonotypes only. } \description{ Get the N most abundant clonotypes diff --git a/man/trackClonotypes.Rd b/man/trackClonotypes.Rd index 20cc1d5d..45211505 100644 --- a/man/trackClonotypes.Rd +++ b/man/trackClonotypes.Rd @@ -8,13 +8,13 @@ trackClonotypes(.data, .which = list(1, 15), .col = "aa", .norm = TRUE) } \arguments{ \item{.data}{The data to process. It can be a \link{data.frame}, a -\link{data.table}, or a list of these objects. +[data.table::data.table], or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} Competent users may provide advanced data representations: -DBI database connections, Apache Spark DataFrame from \link{copy_to} or a list +DBI database connections, or a list of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} diff --git a/man/vis.Rd b/man/vis.Rd index eff1ffa0..a1f6a824 100644 --- a/man/vis.Rd +++ b/man/vis.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis} \alias{vis} \title{One function to visualise them all} diff --git a/man/vis.clonal_family.Rd b/man/vis.clonal_family.Rd index 79b71eff..46023f18 100644 --- a/man/vis.clonal_family.Rd +++ b/man/vis.clonal_family.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.clonal_family} \alias{vis.clonal_family} \title{Visualise clonal family tree: wrapper for calling on the entire repClonalFamily output} diff --git a/man/vis.clonal_family_tree.Rd b/man/vis.clonal_family_tree.Rd index 7aba8f06..78d515e2 100644 --- a/man/vis.clonal_family_tree.Rd +++ b/man/vis.clonal_family_tree.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.clonal_family_tree} \alias{vis.clonal_family_tree} \title{Visualise clonal family tree} diff --git a/man/vis.immunr_chao1.Rd b/man/vis.immunr_chao1.Rd index acb0c94a..5155da64 100644 --- a/man/vis.immunr_chao1.Rd +++ b/man/vis.immunr_chao1.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_chao1} \alias{vis.immunr_chao1} \alias{vis.immunr_dxx} diff --git a/man/vis.immunr_clonal_prop.Rd b/man/vis.immunr_clonal_prop.Rd index 732350ee..122ed6c2 100644 --- a/man/vis.immunr_clonal_prop.Rd +++ b/man/vis.immunr_clonal_prop.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_clonal_prop} \alias{vis.immunr_clonal_prop} \alias{vis.immunr_homeo} diff --git a/man/vis.immunr_dynamics.Rd b/man/vis.immunr_dynamics.Rd index a7fedb08..f26c5af2 100644 --- a/man/vis.immunr_dynamics.Rd +++ b/man/vis.immunr_dynamics.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_dynamics} \alias{vis.immunr_dynamics} \title{Visualise clonotype dynamics} diff --git a/man/vis.immunr_exp_vol.Rd b/man/vis.immunr_exp_vol.Rd index 70e370db..44b4b941 100644 --- a/man/vis.immunr_exp_vol.Rd +++ b/man/vis.immunr_exp_vol.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_exp_vol} \alias{vis.immunr_exp_vol} \alias{vis.immunr_exp_count} diff --git a/man/vis.immunr_gene_usage.Rd b/man/vis.immunr_gene_usage.Rd index 939fc26c..f2d36902 100644 --- a/man/vis.immunr_gene_usage.Rd +++ b/man/vis.immunr_gene_usage.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_gene_usage} \alias{vis.immunr_gene_usage} \title{Histograms and boxplots (general case / gene usage)} @@ -29,7 +29,7 @@ - "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; -- "circos" - passes arguments to \link{vis_circos} and \link{chordDiagram} from the "circlize" package.} +- "circos" - passes arguments to \link{vis_circos} and [circlize::chordDiagram] from the "circlize" package.} } \value{ A ggplot2 object, pheatmap or circlize object. diff --git a/man/vis.immunr_hclust.Rd b/man/vis.immunr_hclust.Rd index 93bb2a6f..0ffa7a6b 100644 --- a/man/vis.immunr_hclust.Rd +++ b/man/vis.immunr_hclust.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_hclust} \alias{vis.immunr_hclust} \title{Visualisation of hierarchical clustering} @@ -9,7 +9,7 @@ \arguments{ \item{.data}{Clustering results from \link{repOverlapAnalysis} or \link{geneUsageAnalysis}.} -\item{.rect}{Passed to \link{fviz_dend} - whether to add a rectangle around groups.} +\item{.rect}{Passed to [factoextra::fviz_dend] - whether to add a rectangle around groups.} \item{.plot}{A character vector of length one or two specifying which plots to visualise. If "clust" then plot only the clustering. If "best" then plot the number of optimal clusters. diff --git a/man/vis.immunr_inc_overlap.Rd b/man/vis.immunr_inc_overlap.Rd index b12a14f9..24641b63 100644 --- a/man/vis.immunr_inc_overlap.Rd +++ b/man/vis.immunr_inc_overlap.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_inc_overlap} \alias{vis.immunr_inc_overlap} \title{Visualise incremental overlaps} diff --git a/man/vis.immunr_kmeans.Rd b/man/vis.immunr_kmeans.Rd index 736c133e..38a444ff 100644 --- a/man/vis.immunr_kmeans.Rd +++ b/man/vis.immunr_kmeans.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_kmeans} \alias{vis.immunr_kmeans} \alias{vis.immunr_dbscan} @@ -19,15 +19,15 @@ \arguments{ \item{.data}{Clustering results from \link{repOverlapAnalysis} or \link{geneUsageAnalysis}.} -\item{.point}{If TRUE then plot sample points. Passed to \link{fviz_cluster}.} +\item{.point}{If TRUE then plot sample points. Passed to [factoextra::fviz_cluster].} -\item{.text}{If TRUE then plot text labels. Passed to \link{fviz_cluster}.} +\item{.text}{If TRUE then plot text labels. Passed to [factoextra::fviz_cluster].} -\item{.ellipse}{If TRUE then plot ellipses around all samples. Passed to "ellipse" from \link{fviz_cluster}.} +\item{.ellipse}{If TRUE then plot ellipses around all samples. Passed to "ellipse" from [factoextra::fviz_cluster].} -\item{.point.size}{Size of points, passed to "pointsize" from \link{fviz_cluster}.} +\item{.point.size}{Size of points, passed to "pointsize" from [factoextra::fviz_cluster].} -\item{.text.size}{Size of text labels, passed to labelsize from \link{fviz_cluster}.} +\item{.text.size}{Size of text labels, passed to labelsize from [factoextra::fviz_cluster].} \item{.plot}{A character vector of length one or two specifying which plots to visualise. If "clust" then plot only the clustering. If "best" then plot the number of optimal clusters. diff --git a/man/vis.immunr_kmer_table.Rd b/man/vis.immunr_kmer_table.Rd index 7b00ea7d..1b63dc00 100644 --- a/man/vis.immunr_kmer_table.Rd +++ b/man/vis.immunr_kmer_table.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_kmer_table} \alias{vis.immunr_kmer_table} \title{Most frequent kmers visualisation.} diff --git a/man/vis.immunr_mds.Rd b/man/vis.immunr_mds.Rd index 9528c305..b84a2126 100644 --- a/man/vis.immunr_mds.Rd +++ b/man/vis.immunr_mds.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_mds} \alias{vis.immunr_mds} \alias{vis.immunr_pca} diff --git a/man/vis.immunr_ov_matrix.Rd b/man/vis.immunr_ov_matrix.Rd index 16601618..c4835776 100644 --- a/man/vis.immunr_ov_matrix.Rd +++ b/man/vis.immunr_ov_matrix.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_ov_matrix} \alias{vis.immunr_ov_matrix} \alias{vis.immunr_gu_matrix} @@ -24,7 +24,7 @@ - "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; -- "circos" - passes arguments to \link{vis_circos} and \link{chordDiagram} from the "circlize" package;} +- "circos" - passes arguments to \link{vis_circos} and [circlize::chordDiagram] from the "circlize" package;} } \value{ A ggplot2, pheatmap or circlize object. diff --git a/man/vis.immunr_public_repertoire.Rd b/man/vis.immunr_public_repertoire.Rd index c30e780e..d9c4a599 100644 --- a/man/vis.immunr_public_repertoire.Rd +++ b/man/vis.immunr_public_repertoire.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_public_repertoire} \alias{vis.immunr_public_repertoire} \title{Public repertoire visualisation} diff --git a/man/vis.immunr_public_statistics.Rd b/man/vis.immunr_public_statistics.Rd index 3ceb35ed..70518ed0 100644 --- a/man/vis.immunr_public_statistics.Rd +++ b/man/vis.immunr_public_statistics.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.immunr_public_statistics} \alias{vis.immunr_public_statistics} \title{Visualise sharing of clonotypes among samples} @@ -9,7 +9,7 @@ \arguments{ \item{.data}{Public repertoire - an output from the \link{pubRep} function.} -\item{...}{Other arguments passsed directly to \link{upset}.} +\item{...}{Other arguments passsed directly to [UpSetR::upset].} } \value{ A ggplot2 object. diff --git a/man/vis.step_failure_ignored.Rd b/man/vis.step_failure_ignored.Rd index 2845a2fd..26b86dd6 100644 --- a/man/vis.step_failure_ignored.Rd +++ b/man/vis.step_failure_ignored.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis.step_failure_ignored} \alias{vis.step_failure_ignored} \title{Handler for .nofail argument of pipeline steps that prevents examples from crashing diff --git a/man/vis_bar.Rd b/man/vis_bar.Rd index a36ebc41..53ae786d 100644 --- a/man/vis_bar.Rd +++ b/man/vis_bar.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_bar} \alias{vis_bar} \title{Bar plots} diff --git a/man/vis_box.Rd b/man/vis_box.Rd index fdaa8b14..5ac3f444 100644 --- a/man/vis_box.Rd +++ b/man/vis_box.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_box} \alias{vis_box} \title{Flexible box-plots for visualisation of distributions} @@ -38,7 +38,7 @@ pass NA to ".meta".} \item{.meta}{A metadata object. An R dataframe with sample names and their properties, such as age, serostatus or hla.} -\item{.melt}{If TRUE then apply \link{melt} to the ".data" before plotting. +\item{.melt}{If TRUE then apply [reshape2::melt] to the ".data" before plotting. In this case ".data" is supposed to be a data frame with the first character column reserved for names of genes and other numeric columns reserved to counts or frequencies of genes. Each numeric column should be associated with a specific repertoire sample.} diff --git a/man/vis_circos.Rd b/man/vis_circos.Rd index fb7d0a9c..d037775a 100644 --- a/man/vis_circos.Rd +++ b/man/vis_circos.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_circos} \alias{vis_circos} \title{Visualisation of matrices using circos plots} @@ -11,13 +11,13 @@ vis_circos(.data, .title = NULL, ...) \item{.title}{The The text for the title of the plot.} -\item{...}{Other arguments passed to \link{chordDiagram} from the 'circlize' package.} +\item{...}{Other arguments passed to [circlize::chordDiagram] from the 'circlize' package.} } \value{ A circlize object. } \description{ -Visualise matrices with the \link{chordDiagram} function +Visualise matrices with the [circlize::chordDiagram] function from the circlize package. } \examples{ diff --git a/man/vis_heatmap.Rd b/man/vis_heatmap.Rd index f121e015..8f675a06 100644 --- a/man/vis_heatmap.Rd +++ b/man/vis_heatmap.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_heatmap} \alias{vis_heatmap} \title{Visualisation of matrices and data frames using ggplo2-based heatmaps} diff --git a/man/vis_heatmap2.Rd b/man/vis_heatmap2.Rd index e1bd9c5d..d7abf116 100644 --- a/man/vis_heatmap2.Rd +++ b/man/vis_heatmap2.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_heatmap2} \alias{vis_heatmap2} \title{Visualisation of matrices using pheatmap-based heatmaps} diff --git a/man/vis_hist.Rd b/man/vis_hist.Rd index b15cb753..6e38be93 100644 --- a/man/vis_hist.Rd +++ b/man/vis_hist.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_hist} \alias{vis_hist} \title{Visualisation of distributions using histograms} @@ -52,7 +52,7 @@ to automatically detect the optimal number of columns.} \item{.labs}{A character vector of length two with names for x-axis and y-axis, respectively.} -\item{.melt}{If TRUE then apply \link{melt} to the ".data" before plotting. +\item{.melt}{If TRUE then apply [reshape2::melt] to the ".data" before plotting. In this case ".data" is supposed to be a data frame with the first character column reserved for names of genes and other numeric columns reserved to counts or frequencies of genes. Each numeric column should be associated with a specific repertoire sample.} diff --git a/man/vis_immunr_kmer_profile_main.Rd b/man/vis_immunr_kmer_profile_main.Rd index ab78d593..a3bb6472 100644 --- a/man/vis_immunr_kmer_profile_main.Rd +++ b/man/vis_immunr_kmer_profile_main.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_immunr_kmer_profile_main} \alias{vis_immunr_kmer_profile_main} \title{Visualise kmer profiles} diff --git a/man/vis_public_clonotypes.Rd b/man/vis_public_clonotypes.Rd index 1b0e1a4d..1fe84823 100644 --- a/man/vis_public_clonotypes.Rd +++ b/man/vis_public_clonotypes.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_public_clonotypes} \alias{vis_public_clonotypes} \title{Visualisation of public clonotypes} diff --git a/man/vis_public_frequencies.Rd b/man/vis_public_frequencies.Rd index 7701a5f3..b587b261 100644 --- a/man/vis_public_frequencies.Rd +++ b/man/vis_public_frequencies.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_public_frequencies} \alias{vis_public_frequencies} \title{Public repertoire visualisation} diff --git a/man/vis_textlogo.Rd b/man/vis_textlogo.Rd index 4fd069a7..8c1390df 100644 --- a/man/vis_textlogo.Rd +++ b/man/vis_textlogo.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/vis.R +% Please edit documentation in R/v0-vis.R \name{vis_textlogo} \alias{vis_textlogo} \alias{vis_seqlogo} @@ -20,7 +20,7 @@ to plot points on the straight vertical line for each position.} \item{...}{Not used here.} -\item{.scheme}{Character. An argumentt passed to \link{geom_logo} specifying how to colour symbols.} +\item{.scheme}{Character. An argument passed to [ggseqlogo::geom_logo] specifying how to colour symbols.} } \value{ A ggplot2 object. diff --git a/vignettes/immunarch_v1_migration.Rmd b/vignettes/immunarch_v1_migration.Rmd new file mode 100644 index 00000000..a9067515 --- /dev/null +++ b/vignettes/immunarch_v1_migration.Rmd @@ -0,0 +1,91 @@ +--- +title: "Immunarch 0.9.x -> 1.0.0 Migration Guide" +date: "support@immunomind.com" +output: + html_document: + fig_height: 8 + fig_width: 10 + theme: spacelab + toc: yes + pdf_document: + toc: yes + word_document: + toc: yes +--- + + + + +# Overview + +There are three major points related to transformations: + +- how immunarch 1.0.0 works with data, +- interface or API, i.e., names and parameters of the functions, implemented in immunarch, and +- removing or moving some functions to separate package to make immunarch easier to install and manage + +For more long-term plans take a look at the final sections. + +For the nearest changes, please continue reading. + + +# Major update for the current version: Spring 2025 + +## What changed and what you can do + +removed ggpubr, factoextra, fpc, ggraph, phangorn, igraph and some other packages +Sadly I didn't have a chance to do it gradually due to the CRAN requirements. +The good news is that immunarch now needs *only* around 80 packages to install instead of 184 before. + +If you have been using immunarch for some time, there won't be anything changing for you. + +If you want to re-install immunarch, you may encounter errors that asks you to install some of the packages. Just install it, and the function will work - nothing else was changed. + + +# Next major update: Summer 2025 + +## What will be changed + +## What can you do to mitigate risks + + +# Future major updates: Autumn-Winter 2025 + +## What will be changed + +## What can you do to mitigate risks + + +# How immunarch 1.0.0. would look like + +Why do we need even need it? + +- outdated code, hard to support and maintain +- imrpoving the code culture in academia + +## Scalable and fast data processing + +## Lighter interface + +## Modularizing the ecosystem + + + +```{r setup, include=FALSE, echo=FALSE} +# knitr::knit_hooks$set(optipng = knitr::hook_optipng) +# knitr::opts_chunk$set(optipng = '-o7') + +knitr::opts_chunk$set(echo = TRUE) +knitr::opts_chunk$set(fig.align = "center") +knitr::opts_chunk$set(fig.width = 12) +knitr::opts_chunk$set(fig.height = 6) + +library(immunarch) +# source("../R/testing.R") +# immdata = load_test_data() +data(immdata) +``` diff --git a/vignettes/v1_introduction.Rmd b/vignettes/v1_introduction.Rmd index 6ac5d90d..5fe598b6 100644 --- a/vignettes/v1_introduction.Rmd +++ b/vignettes/v1_introduction.Rmd @@ -215,7 +215,7 @@ Sys.setenv(R_REMOTES_NO_ERRORS_FROM_WARNINGS="true") 9. If you cannot install dependencies for `immunarch`, please consider manual installation of all dependencies by executing the following command in R console: ``` -install.packages(c("rematch", "prettyunits", "forcats", "cellranger", "progress", "zip", "backports", "ellipsis", "zeallot", "SparseM", "MatrixModels", "sp", "haven", "curl", "readxl", "openxlsx", "minqa", "nloptr", "RcppEigen", "utf8", "vctrs", "carData", "pbkrtest", "quantreg", "maptools", "rio", "lme4", "labeling", "munsell", "cli", "fansi", "pillar", "viridis", "car", "ellipse", "flashClust", "leaps", "scatterplot3d", "modeltools", "DEoptimR", "digest", "gtable", "lazyeval", "rlang", "scales", "tibble", "viridisLite", "withr", "assertthat", "glue", "magrittr", "pkgconfig", "R6", "tidyselect", "BH", "plogr", "purrr", "ggsci", "cowplot", "ggsignif", "polynom", "fastcluster", "plyr", "abind", "dendextend", "FactoMineR", "mclust", "flexmix", "prabclus", "diptest", "robustbase", "kernlab", "GlobalOptions", "shape", "colorspace", "stringi", "hms", "clipr", "crayon", "httpuv", "mime", "jsonlite", "xtable", "htmltools", "sourcetools", "later", "promises", "gridBase", "RColorBrewer", "yaml", "ggplot2", "dplyr", "dtplyr", "data.table", "gridExtra", "ggpubr", "pheatma3", "ggrepel", "reshape2", "DBI", "factoextra", "fpc", "circlize", "tidyr", "Rtsne", "readr", "readxl", "shiny", "shinythemes", "treemap", "igraph", "airr", "ggseqlogo", "UpSetR", "stringr", "ggalluvial", "Rcpp")) +install.packages(c("rematch", "prettyunits", "forcats", "cellranger", "progress", "zip", "backports", "ellipsis", "zeallot", "SparseM", "MatrixModels", "sp", "haven", "curl", "openxlsx", "minqa", "nloptr", "RcppEigen", "utf8", "vctrs", "carData", "pbkrtest", "quantreg", "maptools", "rio", "lme4", "labeling", "munsell", "cli", "fansi", "pillar", "viridis", "car", "ellipse", "flashClust", "leaps", "scatterplot3d", "modeltools", "DEoptimR", "digest", "gtable", "lazyeval", "rlang", "scales", "tibble", "viridisLite", "withr", "assertthat", "glue", "magrittr", "pkgconfig", "R6", "tidyselect", "BH", "plogr", "purrr", "ggsci", "cowplot", "ggsignif", "polynom", "fastcluster", "plyr", "abind", "dendextend", "FactoMineR", "mclust", "flexmix", "prabclus", "diptest", "robustbase", "kernlab", "GlobalOptions", "shape", "colorspace", "stringi", "hms", "clipr", "crayon", "httpuv", "mime", "jsonlite", "xtable", "htmltools", "sourcetools", "later", "promises", "gridBase", "RColorBrewer", "yaml", "ggplot2", "dplyr", "dtplyr", "data.table", "gridExtra", "ggpubr", "pheatma3", "ggrepel", "reshape2", "DBI", "factoextra", "fpc", "circlize", "tidyr", "Rtsne", "readr", "readxl", "shiny", "shinythemes", "treemap", "igraph", "airr", "ggseqlogo", "UpSetR", "stringr", "ggalluvial", "Rcpp")) ``` 9. If you encounter the following error while running the `devtools::install_local` function: From 272da58223a0f081f1cc770cc581acde6f67dafa Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Wed, 9 Apr 2025 18:02:12 +0200 Subject: [PATCH 03/36] [refactor] Remove dependencies; add startup messages and list of updates --- .Rbuildignore | 1 + .gitignore | 1 + DESCRIPTION | 6 +-- NAMESPACE | 65 ++++++---------------------- R/preprocessing.R | 2 +- R/zzz.R | 86 +++++++++++++++++++++++++++++++------ man/get_immunarch_news.Rd | 26 +++++++++++ man/immunarch_v1_updates.Rd | 16 +++++++ man/list_immunarch_news.Rd | 17 ++++++++ 9 files changed, 152 insertions(+), 68 deletions(-) create mode 100644 man/get_immunarch_news.Rd create mode 100644 man/immunarch_v1_updates.Rd create mode 100644 man/list_immunarch_news.Rd diff --git a/.Rbuildignore b/.Rbuildignore index cc6e0d44..88bf0c9b 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -22,3 +22,4 @@ ^.github$ ^.RDataFiles$ ^.idea$ +^cran-comments\.md$ diff --git a/.gitignore b/.gitignore index 9f6f84ef..7096ad0d 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ docs/* .idea/* vignettes/web_only/*.html immunr.Rproj +cran-comments.md diff --git a/DESCRIPTION b/DESCRIPTION index 82b6f514..f2834a58 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,9 +1,9 @@ Package: immunarch Type: Package Title: Bioinformatics Analysis of T-Cell and B-Cell Immune Repertoires -Version: 0.9.1.1 +Version: 0.9.2 Authors@R: c( - person("Vadim", "Nazarov", "I.", "support@immunomind.com", role = c("aut", "cre"), + person("Vadim I.", "Nazarov", , "support@immunomind.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-3659-2709")), person("Vasily O.", "Tsvetkov", , role = "aut"), person("Siarhei", "Fiadziushchanka", , role = "aut"), @@ -16,7 +16,7 @@ Authors@R: c( person("Victor", "Greiff", , role = "ctb"), person("ImmunoMind", role = c("cph", "fnd")) ) -Contact: support@immunomind.io +Contact: support@immunomind.com Description: A comprehensive framework for bioinformatics exploratory analysis of bulk and single-cell T-cell receptor and antibody repertoires. It provides seamless data loading, analysis and visualisation for AIRR (Adaptive Immune Receptor Repertoire) data, both bulk immunosequencing (RepSeq) diff --git a/NAMESPACE b/NAMESPACE index db875b92..e7180f9b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -61,6 +61,7 @@ export(geneUsageAnalysis) export(gene_stats) export(getKmers) export(get_genes) +export(get_immunarch_news) export(immunr_dbscan) export(immunr_hclust) export(immunr_kmeans) @@ -75,6 +76,7 @@ export(js_div) export(kl_div) export(kmer_profile) export(lessthan) +export(list_immunarch_news) export(morethan) export(noncoding) export(outofframes) @@ -120,12 +122,21 @@ export(vis_textlogo) import(ggplot2) importFrom(Rcpp,cppFunction) importFrom(Rcpp,sourceCpp) -importFrom(UpSetR,fromExpression) -importFrom(UpSetR,upset) importFrom(ape,as.DNAbin) importFrom(ape,clustal) importFrom(ape,read.tree) importFrom(circlize,chordDiagram) +importFrom(cli,cli_alert_info) +importFrom(cli,cli_alert_success) +importFrom(cli,cli_alert_warning) +importFrom(cli,cli_bullets) +importFrom(cli,cli_end) +importFrom(cli,cli_h1) +importFrom(cli,cli_inform) +importFrom(cli,cli_par) +importFrom(cli,cli_text) +importFrom(cli,spark_line) +importFrom(cli,start_app) importFrom(data.table,":=") importFrom(data.table,as.data.table) importFrom(data.table,data.table) @@ -168,24 +179,6 @@ importFrom(dplyr,tally) importFrom(dplyr,top_n) importFrom(dplyr,ungroup) importFrom(dtplyr,lazy_dt) -importFrom(factoextra,fviz_cluster) -importFrom(factoextra,fviz_dend) -importFrom(factoextra,fviz_nbclust) -importFrom(factoextra,fviz_pca_ind) -importFrom(factoextra,hcut) -importFrom(fpc,dbscan) -importFrom(ggalluvial,geom_flow) -importFrom(ggalluvial,geom_stratum) -importFrom(ggpubr,compare_means) -importFrom(ggpubr,geom_signif) -importFrom(ggpubr,ggscatter) -importFrom(ggpubr,rotate_x_text) -importFrom(ggpubr,stat_compare_means) -importFrom(ggpubr,theme_pubr) -importFrom(ggraph,geom_edge_diagonal) -importFrom(ggraph,geom_node_point) -importFrom(ggraph,ggraph) -importFrom(ggraph,theme_graph) importFrom(ggseqlogo,geom_logo) importFrom(ggseqlogo,theme_logo) importFrom(glue,glue) @@ -193,8 +186,6 @@ importFrom(grDevices,colorRampPalette) importFrom(graphics,plot) importFrom(grid,gpar) importFrom(grid,rectGrob) -importFrom(igraph,clusters) -importFrom(igraph,graph_from_data_frame) importFrom(jsonlite,read_json) importFrom(magrittr,"%<>%") importFrom(magrittr,"%>%") @@ -209,7 +200,6 @@ importFrom(parallel,parApply) importFrom(parallel,stopCluster) importFrom(patchwork,plot_annotation) importFrom(patchwork,wrap_plots) -importFrom(phangorn,write.phyDat) importFrom(pheatmap,pheatmap) importFrom(plyr,.) importFrom(plyr,adply) @@ -236,38 +226,10 @@ importFrom(readr,read_csv) importFrom(readr,read_delim) importFrom(readr,read_tsv) importFrom(readr,write_lines) -importFrom(readxl,read_xlsx) importFrom(reshape2,melt) importFrom(rlang,sym) importFrom(rlist,list.remove) importFrom(scales,percent) -importFrom(shiny,actionButton) -importFrom(shiny,br) -importFrom(shiny,checkboxInput) -importFrom(shiny,downloadButton) -importFrom(shiny,downloadHandler) -importFrom(shiny,fluidPage) -importFrom(shiny,mainPanel) -importFrom(shiny,observe) -importFrom(shiny,observeEvent) -importFrom(shiny,plotOutput) -importFrom(shiny,renderPlot) -importFrom(shiny,renderText) -importFrom(shiny,renderUI) -importFrom(shiny,selectInput) -importFrom(shiny,sidebarLayout) -importFrom(shiny,sidebarPanel) -importFrom(shiny,sliderInput) -importFrom(shiny,splitLayout) -importFrom(shiny,tabPanel) -importFrom(shiny,tabsetPanel) -importFrom(shiny,textAreaInput) -importFrom(shiny,textInput) -importFrom(shiny,textOutput) -importFrom(shiny,titlePanel) -importFrom(shiny,uiOutput) -importFrom(shiny,updateSliderInput) -importFrom(shinythemes,shinytheme) importFrom(stats,as.dist) importFrom(stats,cmdscale) importFrom(stats,cor) @@ -278,6 +240,7 @@ importFrom(stats,na.omit) importFrom(stats,prcomp) importFrom(stats,qnorm) importFrom(stats,rmultinom) +importFrom(stats,runif) importFrom(stringdist,stringdistmatrix) importFrom(stringi,stri_replace_all_fixed) importFrom(stringr,boundary) diff --git a/R/preprocessing.R b/R/preprocessing.R index 98b7ddb7..2d01161e 100644 --- a/R/preprocessing.R +++ b/R/preprocessing.R @@ -81,7 +81,7 @@ top <- function(.data, .n = 10) { #' data(immdata) #' immdata_cod <- coding(immdata$data) #' immdata_cod1 <- coding(immdata$data[[1]]) -#' @export coding +#' @export coding noncoding inframes outofframes coding <- function(.data) { if (has_class(.data, "list")) { lapply(.data, coding) diff --git a/R/zzz.R b/R/zzz.R index 60ee1ca2..e256f86a 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,14 +1,8 @@ -#' @importFrom cli cli_h1 cli_alert_warning cli_par cli_text cli_end cli_alert_info cli_bullets spark_line cli_alert_success +#' @importFrom cli cli_h1 cli_alert_warning cli_par cli_text cli_end cli_alert_info cli_bullets spark_line cli_alert_success start_app cli_inform #' @importFrom stats runif -.onAttach <- function(libname, pkgname) { - # TODO: supress https://github.com/r-lib/cli/issues/589 - # TODO: remove non-ASCII characters folder-like - # TODO: figure out the middle name stuff - # TODO: put dependendies in the cran-comments - +immunarch_v1_update_apr_2025 <- function() { cli::cli_h1("{cli::col_green('immunarch')} {cli::col_yellow('0.9.x')} – Critical Pre-release Notice") - cli::cli_alert_warning("Update #1 [Apr 2025] -- Major changes are coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}!") cli::cli_text(cli::col_yellow(cli::spark_line(runif(110, 0, 1)))) @@ -39,8 +33,8 @@ cli::cli_text( "See the dedicated migration guide for migration on what you can do now and how to prepare for the future:" ) - cli::cli_text("├─ run {cli::col_cyan('vignette(\"immunarch_v1_migration\")')}, or") - cli::cli_text("└─ visit {cli::col_cyan('https://immunarch.com/articles/immunarch_v1_migration.html')}") + cli::cli_text(">> run {cli::col_cyan('vignette(\"immunarch_v1_migration\")')}, or") + cli::cli_text(">> visit {cli::col_cyan('https://immunarch.com/articles/immunarch_v1_migration.html')}") cli::cli_par() cli::cli_text() @@ -53,7 +47,73 @@ cli::cli_par() cli::cli_text() cli::cli_alert_info("Questions, comments, ideas? I'm available via:") - cli::cli_text("├─ Support email: {cli::col_cyan('support@immunomind.com')}") - cli::cli_text("├─ GitHub tickets: {cli::col_cyan('https://github.com/immunomind/immunarch')}") - cli::cli_text("└─ LinkedIn: {cli::col_cyan('https://www.linkedin.com/in/vdnaz/')}") + cli::cli_text(">> Support email: {cli::col_cyan('support@immunomind.com')}") + cli::cli_text(">> GitHub tickets: {cli::col_cyan('https://github.com/immunomind/immunarch')}") + cli::cli_text(">> LinkedIn: {cli::col_cyan('https://www.linkedin.com/in/vdnaz/')}") +} + +#' Some description +immunarch_v1_updates <- c( + "Apr 2025" = immunarch_v1_update_apr_2025 +) + +#' Get the Latest immunarch Update +#' +#' Retrieves an update message for immunarch. +#' +#' If `datepoint` is set to `"latest"`, the function returns the most recent update. +#' Otherwise, specify the update date key (e.g., `"Apr 2025"`) to retrieve that particular update. +#' If no matching update is found, a warning is issued along with available update keys. +#' +#' @param datepoint A string specifying the update date. Use `"latest"` for the most recent update +#' or supply a valid date key (e.g., `"Apr 2025"`). +#' +#' @return A character string with the update details or a warning if the key is not found. +#' +#' @seealso [list_immunarch_news()] +#' +#' @export +get_immunarch_news <- function(datepoint = "latest") { + if (datepoint == "latest") { + immunarch_v1_updates[[length(immunarch_v1_updates)]]() + } else if (datepoint %in% names(immunarch_v1_updates)) { + immunarch_v1_updates[[datepoint]]() + } else { + cli::cli_alert_warning("No {datepoint} date in the list of {cli::col_green('immunarch')} updates. Available update names are: {immunarch:::list_immunarch_news()}") + } +} + +#' List Available immunarch Updates +#' +#' Returns the list of available update keys for immunarch v1. +#' +#' @return A character vector containing all the date keys for the available updates. +#' +#' @seealso [get_immunarch_news()] +#' +#' @export +list_immunarch_news <- function() { + names(immunarch_v1_updates) +} + +.onAttach <- function(libname, pkgname) { + msg <- paste0( + "Hi, this is Vadim Nazarov speaking -- author of ", + cli::col_green("immunarch"), + ".\n", + cli::col_green("immunarch"), + " is evolving towards its 1.0.0 release. Soon it will be faster, more user-friendly, and ready for its long-awaited publication. Some functions will no longer be supported or will be replaced with new, more powerful methods.\n", + "\n -- Please run ", + cli::col_cyan("get_immunarch_news()"), + " in your R console to read the latest update and learn what has changed, what's new, how to migrate your code, and what changes are planned for the next update.\n", + "\n -- Run ", + cli::col_cyan("list_immunarch_news()"), + " to list all available updates and catch up on any you may have missed. Latest update: ", cli::col_yellow("#1, Apr 2025"), "\n", + "\n -- To import the package without this message, run ", + cli::col_cyan("suppressPackageStartupMessages(library(\"immunarch\"))"), + "\n", + "Thank you." + ) + + cli::cli_inform(msg, class = "packageStartupMessage") } diff --git a/man/get_immunarch_news.Rd b/man/get_immunarch_news.Rd new file mode 100644 index 00000000..3965fdc5 --- /dev/null +++ b/man/get_immunarch_news.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/zzz.R +\name{get_immunarch_news} +\alias{get_immunarch_news} +\title{Get the Latest immunarch Update} +\usage{ +get_immunarch_news(datepoint = "latest") +} +\arguments{ +\item{datepoint}{A string specifying the update date. Use `"latest"` for the most recent update +or supply a valid date key (e.g., `"Apr 2025"`).} +} +\value{ +A character string with the update details or a warning if the key is not found. +} +\description{ +Retrieves an update message for immunarch. +} +\details{ +If `datepoint` is set to `"latest"`, the function returns the most recent update. +Otherwise, specify the update date key (e.g., `"Apr 2025"`) to retrieve that particular update. +If no matching update is found, a warning is issued along with available update keys. +} +\seealso{ +[list_immunarch_news()] +} diff --git a/man/immunarch_v1_updates.Rd b/man/immunarch_v1_updates.Rd new file mode 100644 index 00000000..76e1719c --- /dev/null +++ b/man/immunarch_v1_updates.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/zzz.R +\docType{data} +\name{immunarch_v1_updates} +\alias{immunarch_v1_updates} +\title{Some description} +\format{ +An object of class \code{NULL} of length 0. +} +\usage{ +immunarch_v1_updates +} +\description{ +Some description +} +\keyword{datasets} diff --git a/man/list_immunarch_news.Rd b/man/list_immunarch_news.Rd new file mode 100644 index 00000000..366ca870 --- /dev/null +++ b/man/list_immunarch_news.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/zzz.R +\name{list_immunarch_news} +\alias{list_immunarch_news} +\title{List Available immunarch Updates} +\usage{ +list_immunarch_news() +} +\value{ +A character vector containing all the date keys for the available updates. +} +\description{ +Returns the list of available update keys for immunarch v1. +} +\seealso{ +[get_immunarch_news()] +} From e200317cd19a3e7d1d7d07a61d2be614e5087fc4 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Sat, 16 Aug 2025 13:50:31 +0200 Subject: [PATCH 04/36] docs: add deprecation badges and convert to markdown --- R/align_lineage.R | 12 ++-- R/annotation.R | 23 +++++--- R/clonality.R | 30 +++++----- R/clustering.R | 34 +++++++----- R/dimensions.R | 26 +++++---- R/distance.R | 22 +++++--- R/diversity.R | 17 +++--- R/dynamics.R | 11 ++-- R/explore.R | 14 +++-- R/filters.R | 4 ++ R/gene_usage.R | 11 ++-- R/gene_usage_analysis.R | 22 +++++--- R/germline.R | 10 +++- R/info_theory.R | 6 +- R/io.R | 30 ++++++---- R/kmers.R | 77 ++++++-------------------- R/overlap.R | 30 ++++++---- R/overlap_analysis.R | 22 +++++--- R/phylip.R | 6 +- R/preprocessing.R | 2 +- R/public.R | 28 +++++++--- R/sampling.R | 20 +++---- R/seqCluster.R | 15 +++-- R/shiny.R | 2 +- R/singlecell.R | 24 +++++--- R/somatic_hypermutation.R | 6 +- R/spectratyping.R | 9 ++- man/apply_symm.Rd | 2 +- man/bcrdata.Rd | 6 +- man/coding.Rd | 14 ++--- man/dbAnnotate.Rd | 8 ++- man/dbLoad.Rd | 2 + man/entropy.Rd | 2 + man/figures/lifecycle-deprecated.svg | 21 +++++++ man/figures/lifecycle-experimental.svg | 21 +++++++ man/figures/lifecycle-stable.svg | 29 ++++++++++ man/figures/lifecycle-superseded.svg | 21 +++++++ man/geneUsage.Rd | 16 +++--- man/geneUsageAnalysis.Rd | 16 +++--- man/getKmers.Rd | 4 +- man/get_immunarch_news.Rd | 12 ++-- man/immdata.Rd | 6 +- man/immunarch_v1_updates.Rd | 2 +- man/immunr_data_format.Rd | 46 ++++++--------- man/immunr_hclust.Rd | 33 +++++------ man/immunr_pca.Rd | 21 +++---- man/inc_overlap.Rd | 4 +- man/list_immunarch_news.Rd | 4 +- man/matrixdiagcopy.Rd | 2 +- man/pubRep.Rd | 15 +++-- man/pubRepApply.Rd | 2 +- man/pubRepFilter.Rd | 2 + man/pubRepStatistics.Rd | 2 +- man/repAlignLineage.Rd | 26 +++++---- man/repClonalFamily.Rd | 30 +++++----- man/repClonality.Rd | 4 +- man/repDiversity.Rd | 34 +++++------- man/repExplore.Rd | 4 +- man/repFilter.Rd | 32 ++++++----- man/repGermline.Rd | 14 +++-- man/repLoad.Rd | 66 ++++++++++------------ man/repOverlap.Rd | 4 +- man/repOverlapAnalysis.Rd | 18 +++--- man/repSample.Rd | 2 +- man/repSave.Rd | 2 + man/repSomaticHypermutation.Rd | 20 ++++--- man/scdata.Rd | 6 +- man/select_barcodes.Rd | 4 +- man/select_clusters.Rd | 2 + man/seqCluster.Rd | 7 ++- man/seqDist.Rd | 6 +- man/spectratype.Rd | 4 +- man/split_to_kmers.Rd | 2 +- man/top.Rd | 6 +- man/trackClonotypes.Rd | 15 ++--- man/vis.Rd | 68 +++++++++++------------ man/vis.clonal_family.Rd | 2 +- man/vis.clonal_family_tree.Rd | 2 +- man/vis.immunr_chao1.Rd | 10 ++-- man/vis.immunr_clonal_prop.Rd | 10 ++-- man/vis.immunr_exp_vol.Rd | 10 ++-- man/vis.immunr_gene_usage.Rd | 31 +++++------ man/vis.immunr_hclust.Rd | 2 +- man/vis.immunr_kmeans.Rd | 10 ++-- man/vis.immunr_mds.Rd | 11 ++-- man/vis.immunr_ov_matrix.Rd | 22 ++++---- man/vis.immunr_public_repertoire.Rd | 10 ++-- man/vis.immunr_public_statistics.Rd | 2 +- man/vis_box.Rd | 2 +- man/vis_circos.Rd | 4 +- man/vis_heatmap2.Rd | 8 +-- man/vis_hist.Rd | 8 +-- man/vis_immunr_kmer_profile_main.Rd | 8 +-- man/vis_textlogo.Rd | 6 +- 94 files changed, 771 insertions(+), 589 deletions(-) create mode 100644 man/figures/lifecycle-deprecated.svg create mode 100644 man/figures/lifecycle-experimental.svg create mode 100644 man/figures/lifecycle-stable.svg create mode 100644 man/figures/lifecycle-superseded.svg diff --git a/R/align_lineage.R b/R/align_lineage.R index 4e2a42a9..cbc25187 100644 --- a/R/align_lineage.R +++ b/R/align_lineage.R @@ -12,8 +12,12 @@ #' @importFrom ape as.DNAbin clustal #' @importFrom doParallel registerDoParallel stopImplicitCluster #' @importFrom parallel mclapply - -#' @description This function aligns all sequences (incliding germline) that belong to one clonal +#' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' This function aligns all sequences (incliding germline) that belong to one clonal #' lineage and one cluster. After clustering and building the clonal lineage and germline, the next #' step is to analyze the degree of mutation and maturity of each clonal lineage. This allows for #' finding high mature cells and cells with a large number of offspring. The phylogenetic analysis @@ -24,7 +28,7 @@ #' #' repAlignLineage(.data, .min_lineage_sequences, .prepare_threads, .align_threads, .nofail) #' -#' @param .data The data to be processed. Can be \link{data.frame}, [data.table::data.table] +#' @param .data The data to be processed. Can be [data.frame], [data.table::data.table] #' or a list of these objects. #' #' @param .min_lineage_sequences If number of sequences in the same clonal lineage and the same @@ -36,7 +40,7 @@ #' #' @param .align_threads Number of threads for lineage alignment. #' -#' It must have columns in the immunarch compatible format \link{immunarch_data_format}, and also +#' It must have columns in the immunarch compatible format [immunarch_data_format], and also #' must contain 'Cluster' column, which is added by seqCluster() function, and 'Germline.sequence' #' column, which is added by repGermline() function. #' diff --git a/R/annotation.R b/R/annotation.R index ff30d962..3a57a4b5 100644 --- a/R/annotation.R +++ b/R/annotation.R @@ -9,17 +9,21 @@ if (getRversion() >= "2.15.1") { #' #' @concept annotation #' -#' @description The function automatically detects the database format and loads it into R. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' The function automatically detects the database format and loads it into R. #' Additionally, the function provides a general query interface to databases that allows #' filtering by species, chain types (i.e., locus) and pathology (i.e., antigen species). #' #' Currently we support three popular databases: #' -#' VDJDB - \url{https://github.com/antigenomics/vdjdb-db} +#' VDJDB - #' -#' McPAS-TCR - \url{http://friedmanlab.weizmann.ac.il/McPAS-TCR/} +#' McPAS-TCR - #' -#' TBAdb from PIRD - \url{https://db.cngb.org/pird/} +#' TBAdb from PIRD - #' #' @param .path Character. A path to the database file, e.g., "/Users/researcher/Downloads/McPAS-TCR.csv". #' @@ -111,15 +115,18 @@ dbLoad <- function(.path, .db, .species = NA, .chain = NA, .pathology = NA) { #' @concept annotation #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' Annotate clonotypes by matching them to known condition-associated immune receptors in a database. #' Before using this function, you must download or load the relevant database files. #' For more information, see the [online tutorial](https://immunarch.com/articles/web_only/v11_db.html). #' -#' @param .data The data to process. It can be a \link{data.frame}, a -#' \link{data.table}, or a list of these objects. +#' @param .data The data to process. It can be a [data.frame], a +#' [data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -127,7 +134,7 @@ dbLoad <- function(.path, .db, .species = NA, .chain = NA, .pathology = NA) { #' #' Note: each connection must represent a separate repertoire. #' -#' @param .db A data frame or a data table with an immune receptor database. See \link{dbLoad} on how to load databases into R. +#' @param .db A data frame or a data table with an immune receptor database. See [dbLoad] on how to load databases into R. #' #' @param .data.col Character vector. Vector of columns in the input repertoires to use for clonotype search. E.g., `"CDR3.aa"` or `c("CDR3.aa", "V.name")`. #' diff --git a/R/clonality.R b/R/clonality.R index f15c0882..edd91bbb 100644 --- a/R/clonality.R +++ b/R/clonality.R @@ -4,14 +4,18 @@ #' #' @aliases clonality clonal.prop clonal_proportion top_proportion rare_proportion clonal_space_homeostasis #' -#' @description \code{repClonality} function encompasses several methods to measure +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' `repClonality` function encompasses several methods to measure #' clonal proportions in a given repertoire. #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -19,22 +23,22 @@ #' #' Note: each connection must represent a separate repertoire. #' -#' @param .method A String with one of the following options: \code{"clonal.prop"}, -#' \code{"homeo"}, \code{"top"} or \code{"rare"}. +#' @param .method A String with one of the following options: `"clonal.prop"`, +#' `"homeo"`, `"top"` or `"rare"`. #' -#' Set \code{"clonal.prop"} to compute clonal proportions or in other words -#' percentage of clonotypes required to occupy specified by \code{.perc} percent +#' Set `"clonal.prop"` to compute clonal proportions or in other words +#' percentage of clonotypes required to occupy specified by `.perc` percent #' of the total immune repertoire. #' -#' Set \code{"homeo"} to analyse relative abundance (also known as clonal space homeostasis), which is defined as the +#' Set `"homeo"` to analyse relative abundance (also known as clonal space homeostasis), which is defined as the #' proportion of repertoire occupied by clonal groups with specific abundances.. #' -#' Set \code{"top"} to estimate relative abundance for the groups of top clonotypes in -#' repertoire, e.g., ten most abundant clonotypes. Use \code{".head"} to define index intervals, +#' Set `"top"` to estimate relative abundance for the groups of top clonotypes in +#' repertoire, e.g., ten most abundant clonotypes. Use `".head"` to define index intervals, #' such as 10, 100 and so on. #' -#' Set \code{"rare"} to estimate relative abundance for the groups of rare clonotypes -#' with low counts. Use \code{".bound"} to define the threshold of clonotype groups. +#' Set `"rare"` to estimate relative abundance for the groups of rare clonotypes +#' with low counts. Use `".bound"` to define the threshold of clonotype groups. #' #' @param .perc A single numerical value ranging from 0 to 100. #' @param .clone.types A named numerical vector with the threshold of the half-closed @@ -60,7 +64,7 @@ #' #' Otherwise, it returns a numeric matrix with clonality statistics for all input repertoires. #' -#' @seealso \link{repDiversity} +#' @seealso [repDiversity] #' #' @examples #' # Load the data diff --git a/R/clustering.R b/R/clustering.R index afbede35..ba5476e2 100644 --- a/R/clustering.R +++ b/R/clustering.R @@ -6,13 +6,17 @@ #' #' @importFrom stats kmeans as.dist cmdscale dist #' -#' @description Clusters the data with one of the following methods: +#' @description #' -#' - \code{immunr_hclust} clusters the data using the hierarchical clustering from \link[factoextra]{hcut}; +#' `r lifecycle::badge('deprecated')` #' -#' - \code{immunr_kmeans} clusters the data using the K-means algorithm from \link{kmeans}; +#' Clusters the data with one of the following methods: #' -#' - \code{immunr_dbscan} clusters the data using the DBSCAN algorithm from \link[fpc]{dbscan}. +#' - `immunr_hclust` clusters the data using the hierarchical clustering from [hcut][factoextra::hcut]; +#' +#' - `immunr_kmeans` clusters the data using the K-means algorithm from [kmeans]; +#' +#' - `immunr_dbscan` clusters the data using the DBSCAN algorithm from [dbscan][fpc::dbscan]. #' #' @usage #' immunr_hclust(.data, .k = 2, .k.max = nrow(.data) - 1, .method = "complete", .dist = TRUE) @@ -22,32 +26,32 @@ #' #' immunr_dbscan(.data, .eps, .dist = TRUE) #' -#' @param .data Matrix or data frame with features, distance matrix or output from \link{repOverlapAnalysis} or \link{geneUsageAnalysis} functions. +#' @param .data Matrix or data frame with features, distance matrix or output from [repOverlapAnalysis] or [geneUsageAnalysis] functions. #' -#' @param .k The number of clusters to create, defined as \code{k} to \link[factoextra]{hcut} or as \code{centers} to \link{kmeans}. +#' @param .k The number of clusters to create, defined as `k` to [hcut][factoextra::hcut] or as `centers` to [kmeans]. #' -#' @param .k.max Limits the maximum number of clusters. It is passed as \code{k.max} to [factoextra::fviz_nbclust] for \code{immunr_hclust} and \code{immunr_kmeans}. +#' @param .k.max Limits the maximum number of clusters. It is passed as `k.max` to [factoextra::fviz_nbclust] for `immunr_hclust` and `immunr_kmeans`. #' -#' @param .eps Local radius for expanding clusters, minimal distance between points to expand clusters. Passed as \code{eps} to \link[fpc]{dbscan}. +#' @param .eps Local radius for expanding clusters, minimal distance between points to expand clusters. Passed as `eps` to [dbscan][fpc::dbscan]. #' #' @param .method Passed to [factoextra::hcut] or as [factoextra::fviz_nbclust]. #' -#' In case of [factoextra::hcut] the agglomeration method is going to be used (argument \code{hc_method}). +#' In case of [factoextra::hcut] the agglomeration method is going to be used (argument `hc_method`). #' -#' In case of [factoextra::fviz_nbclust] it is the method to be used for estimating the optimal number of clusters (argument \code{method}). +#' In case of [factoextra::fviz_nbclust] it is the method to be used for estimating the optimal number of clusters (argument `method`). #' #' @param .dist If TRUE then ".data" is expected to be a distance matrix. If FALSE then the euclidean distance is computed for the input objects. #' #' @return -#' \code{immunr_hclust} - list with two elements. The first element is an output from [factoextra::hcut]. +#' `immunr_hclust` - list with two elements. The first element is an output from [factoextra::hcut]. #' The second element is an output from [factoextra::fviz_nbclust] #' -#' \code{immunr_kmeans} - list with three elements. The first element is an output from \link{kmeans}. +#' `immunr_kmeans` - list with three elements. The first element is an output from [kmeans]. #' The second element is an output from [factoextra::fviz_nbclust]. -#' The third element is the input dataset \code{.data}. +#' The third element is the input dataset `.data`. #' -#' \code{immunr_dbscan} - list with two elements. The first element is an output from [fpc::dbscan]. -#' The second element is the input dataset \code{.data}. +#' `immunr_dbscan` - list with two elements. The first element is an output from [fpc::dbscan]. +#' The second element is the input dataset `.data`. #' #' @examples #' data(immdata) diff --git a/R/dimensions.R b/R/dimensions.R index f92e88f0..c9ba8b38 100644 --- a/R/dimensions.R +++ b/R/dimensions.R @@ -17,16 +17,20 @@ default_scale_fun <- function(x) { #' #' @aliases immunr_pca immunr_mds immunr_tsne #' -#' @description Collects a set of principal variables, reducing the number of not important variables +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Collects a set of principal variables, reducing the number of not important variables #' to analyse. Dimensionality reduction makes data analysis algorithms work faster and #' sometimes more accurate, since it also reduces noise in the data. Currently available #' methods are: #' -#' - \code{immunr_pca} performs PCA (Principal Component Analysis) using \link{prcomp}; +#' - `immunr_pca` performs PCA (Principal Component Analysis) using [prcomp]; #' -#' - \code{immunr_mds} performs MDS (Multi-Dimensional Scaling) using \link[MASS]{isoMDS}; +#' - `immunr_mds` performs MDS (Multi-Dimensional Scaling) using [isoMDS][MASS::isoMDS]; #' -#' - \code{immunr_tsne} performs tSNE (t-Distributed Stochastic Neighbour Embedding) using \link[Rtsne]{Rtsne}. +#' - `immunr_tsne` performs tSNE (t-Distributed Stochastic Neighbour Embedding) using [Rtsne][Rtsne::Rtsne]. #' #' @usage #' @@ -36,12 +40,12 @@ default_scale_fun <- function(x) { #' #' immunr_tsne(.data, .perp = 1, .dist = TRUE, ...) #' -#' @param .data A matrix or a data frame with features, distance matrix or output from \link{repOverlapAnalysis} or \link{geneUsageAnalysis} functions. +#' @param .data A matrix or a data frame with features, distance matrix or output from [repOverlapAnalysis] or [geneUsageAnalysis] functions. #' #' @param .scale A function to apply to your data before passing it to any of #' dimensionality reduction algorithms. There is no scaling by default. #' -#' @param .perp The perplexity parameter for \link[Rtsne]{Rtsne}. Specifies the number +#' @param .perp The perplexity parameter for [Rtsne][Rtsne::Rtsne]. Specifies the number #' of neighbors each data point must have in the resulting plot. #' #' @param .raw If TRUE then returns the non-processed output from dimensionality reduction @@ -52,16 +56,16 @@ default_scale_fun <- function(x) { #' #' @param .dist If TRUE then assumes that ".data" is a distance matrix. #' -#' @param ... Other parameters passed to \link[Rtsne]{Rtsne}. +#' @param ... Other parameters passed to [Rtsne][Rtsne::Rtsne]. #' #' @return -#' \code{immunr_pca} - an output from \link{prcomp}. +#' `immunr_pca` - an output from [prcomp]. #' -#' \code{immunr_mds} - an output from \link[MASS]{isoMDS}. +#' `immunr_mds` - an output from [isoMDS][MASS::isoMDS]. #' -#' \code{immunr_tsne} - an output from \\link[Rtsne]{Rtsne}. +#' `immunr_tsne` - an output from \[Rtsne][Rtsne::Rtsne]. #' -#' @seealso \link{vis.immunr_pca} for visualisations. +#' @seealso [vis.immunr_pca] for visualisations. #' #' @examples #' data(immdata) diff --git a/R/distance.R b/R/distance.R index 55539483..031b0fbd 100644 --- a/R/distance.R +++ b/R/distance.R @@ -8,17 +8,21 @@ #' @importFrom tidyr unite #' @importFrom dplyr select_if group_keys group_map group_by group_by_at -#' @description Computing sequential distances between clonotypes from two repertoires: +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Computing sequential distances between clonotypes from two repertoires: #' #' @usage #' #' seqDist(.data, .col = 'CDR3.nt', .method = 'hamming', #' .group_by = c("V.name", "J.name"), .group_by_seqLength = TRUE, .trim_genes = TRUE, ...) #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' -#' Every object must have columns in the immunarch compatible format \link{immunarch_data_format} +#' Every object must have columns in the immunarch compatible format [immunarch_data_format] #' #' @param .col A string that specifies the column name to be processed. The default value is 'CDR3.nt'. #' @@ -32,27 +36,27 @@ #' #' @param ... Extra arguments for user-defined function. #' -#' The default value is \code{'hamming'} for Hamming distance which counts the number of character substitutions that turns b into a. +#' The default value is `'hamming'` for Hamming distance which counts the number of character substitutions that turns b into a. #' If a and b have different number of characters the distance is Inf. #' #' Other possible values are: #' -#' \code{'lv'} for Levenshtein distance which counts the number of deletions, insertions and substitutions necessary to turn b into a. +#' `'lv'` for Levenshtein distance which counts the number of deletions, insertions and substitutions necessary to turn b into a. #' -#' \code{'lcs'} for longest common substring is defined as the longest string can be obtained by pairing characters from a and b while keeping the order of characters intact. +#' `'lcs'` for longest common substring is defined as the longest string can be obtained by pairing characters from a and b while keeping the order of characters intact. #' -#' In case of user-defined function, it should take x and y parameters as input and return \link{dist} object. +#' In case of user-defined function, it should take x and y parameters as input and return [dist] object. #' #' @return #' -#' Named list of list with \link{dist} objects for given repertoires for each combination of .group_by variable(s) and/or sequence length of .col. +#' Named list of list with [dist] objects for given repertoires for each combination of .group_by variable(s) and/or sequence length of .col. #' #' @examples #' #' data(immdata) #' # Reducing data to save time on examples #' immdata$data <- purrr::map(immdata$data, ~ .x %>% head(10)) -#' # Computing hamming distance for the first two repertoires in \code{'immdata'} +#' # Computing hamming distance for the first two repertoires in `'immdata'` #' seqDist(immdata$data[1:2]) #' #' # Here we define a custom distance function diff --git a/R/diversity.R b/R/diversity.R index b0642094..00b57c18 100644 --- a/R/diversity.R +++ b/R/diversity.R @@ -17,17 +17,20 @@ if (getRversion() >= "2.15.1") { #' @importFrom tidyselect all_of #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' This is a utility function to estimate the diversity of species or objects in the given distribution. #' #' Note: functions will check if .data is a distribution of a random variable (sum == 1) or not. #' To force normalisation and / or to prevent this, set .do.norm to TRUE (do normalisation) #' or FALSE (don't do normalisation), respectively. #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -65,7 +68,7 @@ if (getRversion() >= "2.15.1") { #' chao1 returns 4 values: estimated number of species, standart deviation of #' this number and two 95% confidence intervals for the species number. #' -#' hill returns a vector of specified length \code{.max.q - .min.q} +#' hill returns a vector of specified length `.max.q - .min.q` #' #' @details #' - True diversity, or the effective number of types, refers to the number @@ -111,13 +114,13 @@ if (getRversion() >= "2.15.1") { #' on different step of the simulaiton process or a list with such matrices. #' #' -#' @seealso \link{repOverlap}, \link{entropy}, \link{repClonality} +#' @seealso [repOverlap], [entropy], [repClonality] #' Rarefaction wiki -#' \url{https://en.wikipedia.org/wiki/Rarefaction_(ecology)} +#' #' Hill numbers paper -#' \url{https://www.uvm.edu/~ngotelli/manuscriptpdfs/ChaoHill.pdf} +#' #' Diversity wiki -#' \url{https://en.wikipedia.org/wiki/Measurement_of_biodiversity} +#' #' #' #' @examples diff --git a/R/dynamics.R b/R/dynamics.R index 70152743..6b8750ed 100644 --- a/R/dynamics.R +++ b/R/dynamics.R @@ -8,14 +8,17 @@ #' @aliases trackClonotypes #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' Tracks the temporal dynamics of clonotypes in repertoires. For example, tracking across multiple #' time points after vaccination. #' -#' @param .data The data to process. It can be a \link{data.frame}, a +#' @param .data The data to process. It can be a [data.frame], a #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -25,8 +28,8 @@ #' #' @param .which An argument that regulates which clonotypes to choose for tracking. There are three options for this argument: #' -#' 1) passes a list with two elements \code{list(X, Y)}, where \code{X} is the name or the index of a target repertoire from ".data", and -#' \code{Y} is the number of the most abundant clonotypes to take from \code{X}. +#' 1) passes a list with two elements `list(X, Y)`, where `X` is the name or the index of a target repertoire from ".data", and +#' `Y` is the number of the most abundant clonotypes to take from `X`. #' #' 2) passes a character vector of sequences to take from all data frames; #' diff --git a/R/explore.R b/R/explore.R index efea02c9..aa63abf8 100644 --- a/R/explore.R +++ b/R/explore.R @@ -6,15 +6,19 @@ #' #' @aliases repExplore #' -#' @description The \code{repExplore} function calculates the basic statistics of +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' The `repExplore` function calculates the basic statistics of #' repertoire: the number of unique immune receptor clonotypes, their relative abundances, #' and sequence length distribution across the input dataset. #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -40,7 +44,7 @@ #' @param .col A string that specifies the column to be processed. Pass "nt" for #' nucleotide sequence or "aa" for amino acid sequence. #' -#' @param .coding If \code{TRUE}, then only coding sequences will be analysed. +#' @param .coding If `TRUE`, then only coding sequences will be analysed. #' #' @return #' If input data is a single immune repertoire, then the function returns a numeric vector @@ -48,7 +52,7 @@ #' #' Otherwise, it returns a numeric matrix with exploratory analysis statistics for all input repertoires. #' -#' @seealso \link{vis.immunr_exp_vol} +#' @seealso [vis.immunr_exp_vol] #' #' @examples #' data(immdata) diff --git a/R/filters.R b/R/filters.R index 81af95c5..9cae0759 100644 --- a/R/filters.R +++ b/R/filters.R @@ -7,6 +7,10 @@ #' @importFrom magrittr "%>%" "%<>%" #' @importFrom tidyselect starts_with #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' @param .data The data to be processed. Must be the list of 2 elements: #' a data table and a metadata table. #' @param .method Method of filtering. Implemented methods: diff --git a/R/gene_usage.R b/R/gene_usage.R index 25829704..9dc090a9 100644 --- a/R/gene_usage.R +++ b/R/gene_usage.R @@ -10,15 +10,18 @@ if (getRversion() >= "2.15.1") { #' @aliases geneUsage get_aliases get_genes #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' An utility function to analyse the immune receptor gene usage #' (IGHD, IGHJ, IDHV, IGIJ, IGKJ, IGKV, IGLJ, IGLV, TRAJ, TRAV, TRBD, etc.) #' and statistics. For gene details run `gene_stats()`. #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections,or a list @@ -28,7 +31,7 @@ if (getRversion() >= "2.15.1") { #' @param .gene A character vector of length one with the name of the gene you want #' to analyse of the specific species. If you provide a vector of different length, only the first element #' will be used. The string should also contain the species of interest, for example, valid ".gene" arguments -#' are "hs.trbv", "HomoSapiens.TRBJ" or "macmul.IGHV". For details run \code{gene_stats()}. +#' are "hs.trbv", "HomoSapiens.TRBJ" or "macmul.IGHV". For details run `gene_stats()`. #' @param .quant Selects the column with data to evaluate. #' Pass NA if you want to compute gene statistics at the clonotype level without re-weighting. #' Pass "count" to use the "Clones" column to weight genes by abundance of their corresponding clonotypes. @@ -195,7 +198,7 @@ geneUsage <- function(.data, # df, list, MonetDB #' @aliases gene_stats #' #' @return -#' \code{gene_stats} returns all segment gene statistics +#' `gene_stats` returns all segment gene statistics #' #' @examples #' gene_stats() diff --git a/R/gene_usage_analysis.R b/R/gene_usage_analysis.R index 03e9eebf..bbe8c9e5 100644 --- a/R/gene_usage_analysis.R +++ b/R/gene_usage_analysis.R @@ -6,17 +6,21 @@ #' #' @aliases geneUsageAnalysis #' -#' @description The \code{\link{geneUsageAnalysis}} function deploys several +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' The [geneUsageAnalysis()] function deploys several #' data analysis methods, including PCA, multidimensional scaling, #' Jensen-Shannon divergence, k-means, hierarchical clustering, DBscan, and different #' correlation coefficients. #' -#' @param .data The \code{\link{geneUsageAnalysis}} function runs on the output from -#' \code{\link{geneUsage}}. +#' @param .data The [geneUsageAnalysis()] function runs on the output from +#' [geneUsage()]. #' #' @param .method A string that defines the type of analysis to perform. Can be "pca", #' "mds", "js", "kmeans", "hclust", "dbscan" or "cor" if you want to calculate -#' correlation coefficient. In the latter case you have to provide \code{.cor} argument. +#' correlation coefficient. In the latter case you have to provide `.cor` argument. #' #' @param .base A numerical value that defines the logarithm base for Jensen-Shannon #' divergence. @@ -29,13 +33,13 @@ #' @param .laplace The numeric value, which is used as a pseudocount for Laplace #' smoothing. #' @param .verbose A logical value. -#' @param .k The number of clusters to create, passed as \code{k} to \link[factoextra]{hcut} or as \code{centers} to \link{kmeans}. +#' @param .k The number of clusters to create, passed as `k` to [hcut][factoextra::hcut] or as `centers` to [kmeans]. #' @param .eps A numerical value, DBscan epsylon parameter, see -#' \code{\link{immunr_dbscan}}. -#' @param .perp A numerical value, t-SNE perplexity, see \code{\link{immunr_tsne}}. -#' @param .theta A numerical value, t-SNE theta parameter, see \code{\link{immunr_tsne}}. +#' [immunr_dbscan()]. +#' @param .perp A numerical value, t-SNE perplexity, see [immunr_tsne()]. +#' @param .theta A numerical value, t-SNE theta parameter, see [immunr_tsne()]. #' -#' @return Depends on the last element in the \code{.method} string. See \link{immunr_tsne} for more info. +#' @return Depends on the last element in the `.method` string. See [immunr_tsne] for more info. #' #' @examples #' data(immdata) diff --git a/R/germline.R b/R/germline.R index e7da4863..d636492e 100644 --- a/R/germline.R +++ b/R/germline.R @@ -12,7 +12,11 @@ #' @importFrom parallel parApply detectCores makeCluster clusterExport stopCluster #' @importFrom ape as.DNAbin clustal #' -#' @description This function creates germlines for clonal lineages. B cell clonal lineage +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' This function creates germlines for clonal lineages. B cell clonal lineage #' represents a set of B cells that presumably have a common origin (arising from the same VDJ #' rearrangement event) and a common ancestor. Each clonal lineage has its own germline sequence #' that represents the ancestral sequence for each BCR in clonal lineage. In other words, @@ -24,10 +28,10 @@ #' #' repGermline(.data, .species, .min_nuc_outside_cdr3, .threads) #' -#' @param .data The data to be processed. Can be \link{data.frame}, [data.table::data.table] +#' @param .data The data to be processed. Can be [data.frame], [data.table::data.table] #' or a list of these objects. #' -#' It must have columns in the immunarch compatible format \link{immunarch_data_format}. +#' It must have columns in the immunarch compatible format [immunarch_data_format]. #' #' @param .species Species from which the data was acquired. Available options: #' "HomoSapiens" (default), "MusMusculus", "BosTaurus", "CamelusDromedarius", diff --git a/R/info_theory.R b/R/info_theory.R index c8fbfd31..9f52e946 100644 --- a/R/info_theory.R +++ b/R/info_theory.R @@ -4,7 +4,11 @@ #' #' @aliases entropy kl_div js_div cross_entropy #' -#' @description Compute information-based estimates and distances. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Compute information-based estimates and distances. #' #' @usage #' entropy(.data, .base = 2, .norm = FALSE, .do.norm = NA, .laplace = 1e-12) diff --git a/R/io.R b/R/io.R index 975eca74..f3577a15 100644 --- a/R/io.R +++ b/R/io.R @@ -24,9 +24,13 @@ if (getRversion() >= "2.15.1") { #' @importFrom utils read.table #' @importFrom data.table setDF #' -#' @description The \code{repLoad} function loads repertoire files +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' The `repLoad` function loads repertoire files #' into R workspace in the immunarch format where you can immediately use them for -#' the analysis. \code{repLoad} automatically detects the right format for +#' the analysis. `repLoad` automatically detects the right format for #' your files, so all you need is simply provide the path to your files. #' #' See "Details" for more information on supported formats. See "Examples" for @@ -36,15 +40,15 @@ if (getRversion() >= "2.15.1") { #' Input data can be one of the following: #' #' - a single repertoire file. -#' In this case \code{repLoad} returns an R \link{data.frame}; +#' In this case `repLoad` returns an R [data.frame]; #' #' - a vector of paths to repertoire files. #' Same as in the case with no metadata file presented in the next section below; #' #' - a path to the folder with repertoire files and, if available, metadata file "metadata.txt". -#' If the metadata file if presented, then the \code{repLoad} returns a list with two elements "data" and "meta". -#' "data" is an another list with repertoire R \link{data.frame}s. "meta" is a data frame with the metadata. -#' If the metadata file "metadata.txt" is not presented, then the \code{repLoad} creates a dummy metadata file with +#' If the metadata file if presented, then the `repLoad` returns a list with two elements "data" and "meta". +#' "data" is an another list with repertoire R [data.frame]s. "meta" is a data frame with the metadata. +#' If the metadata file "metadata.txt" is not presented, then the `repLoad` creates a dummy metadata file with #' sample names and returns a list with two elements "data" and "meta". #' If input data has multiple chains or cell types stored in the same file #' (for example, like in 10xGenomics repertoire files), such repertoire files will be splitted to different @@ -104,8 +108,8 @@ if (getRversion() >= "2.15.1") { #' #' - "meta" is a data frame with sample metadata. #' -#' @seealso \link{immunr_data_format} for immunarch data format; \link{repSave} for file saving; -#' \link{repOverlap}, \link{geneUsage} and \link{repDiversity} for starting with immune repertoires basic statistics. +#' @seealso [immunr_data_format] for immunarch data format; [repSave] for file saving; +#' [repOverlap], [geneUsage] and [repDiversity] for starting with immune repertoires basic statistics. #' #' @examples #' # To load the data from a single file (note that you don't need to specify the data format): @@ -432,11 +436,15 @@ repLoad <- function(.path, .mode = "paired", .coding = TRUE, ...) { #' @importFrom plyr mapvalues #' @importFrom purrr map #' -#' @description The \code{repSave} function is deigned to save your data to the disk +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' The `repSave` function is deigned to save your data to the disk #' in desirable format. Currently supports "immunarch" and "vdjtools" file formats. #' -#' @param .data An R dataframe, a list of R dataframes or a list with \code{data} and -#' \code{meta} where first element is a list of dataframes and the latter is a dataframe +#' @param .data An R dataframe, a list of R dataframes or a list with `data` and +#' `meta` where first element is a list of dataframes and the latter is a dataframe #' with metadata. #' @param .path A string with the path to the output directory. It should include file #' name if a single dataframe is provided to .data argument. diff --git a/R/kmers.R b/R/kmers.R index 5f6284b1..b76e6e6c 100644 --- a/R/kmers.R +++ b/R/kmers.R @@ -7,11 +7,16 @@ #' #' @aliases getKmers get.kmers makeKmerTable #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections,or a list @@ -89,12 +94,18 @@ getKmers <- function(.data, .k, .col = c("aa", "nt"), .coding = TRUE) { #' #' @aliases split_to_kmers kmer_profile #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' +#' #' @usage #' split_to_kmers(.data, .k) #' #' kmer_profile(.data, .method = c("freq", "prob", "wei", "self"), .remove.stop = TRUE) #' -#' @param .data Character vector or the output from \code{getKmers}. +#' @param .data Character vector or the output from `getKmers`. #' @param .k Integer. Size of k-mers. #' @param .method Character vector of length one. If "freq" then returns a position frequency matrix (PFM) - #' a matrix with occurences of each amino acid in each position. @@ -110,9 +121,9 @@ getKmers <- function(.data, .k, .col = c("aa", "nt"), .coding = TRUE) { #' @param .remove.stop Logical. If TRUE (by default) remove stop codons. #' #' @return -#' \code{split_to_kmers} - Data frame with two columns (k-mers and their counts). +#' `split_to_kmers` - Data frame with two columns (k-mers and their counts). #' -#' \code{kmer_profile} - a matrix with per-position amino acid statistics. +#' `kmer_profile` - a matrix with per-position amino acid statistics. #' #' @examples #' data(immdata) @@ -201,59 +212,3 @@ kmer_profile <- function(.data, .method = c("freq", "prob", "wei", "self"), .rem add_class(res, "immunr_kmer_profile_self") } } - - -####### -# WIP # -####### -# gibbs_sampling <- function (.data, .motif.len = 5, .niter = 500) { -# .score <- function (.seq, .i, .prof, .background) { -# kmer_aa = strsplit(substr(.seq, seq_i, seq_i + .motif.len - 1), "")[[1]] -# prod(sapply(1:.motif.len, function (kmer_pos) { -# sc = .prof[kmer_aa[kmer_pos], kmer_pos] / .background[kmer_aa[kmer_pos]] -# if (is.nan(sc)) { sc = 0 } -# sc -# })) -# } -# -# cat("Removed", sum(nchar(.data) < .motif.len), "sequences with the length less than the length of motifs.\n") -# seq_vec = .data[nchar(.data) >= .motif.len] -# background = table(unlist(strsplit(seq_vec, ""))) -# background = background / sum(background) -# -# # Vector of scores for each position in the each input sequence -# score_vec = lapply(seq_vec, function (seq_x) rep(1, nchar(seq_x) - .motif.len + 1) ) -# start_pos = sapply(nchar(seq_vec), function (max_pos) sample(1:(max_pos - .motif.len + 1), 1)) -# -# # In the loop: -# pb = set_pb(.niter) -# for (iter in 1:.niter) { -# # Get random kmers -# prev_start_pos = start_pos -# start_pos = sapply(nchar(seq_vec), function (max_pos) sample(1:(max_pos - .motif.len + 1), 1)) -# -# for (out_kmer_i in sample(1:length(seq_vec), length(seq_vec))) { -# max_pos = nchar(seq_vec[out_kmer_i]) - .motif.len + 1 -# kmers <- substr(seq_vec[-out_kmer_i], start_pos[-out_kmer_i], start_pos[-out_kmer_i] + .motif.len - 1) -# prof = kmer_profile(kmers[-out_kmer_i]) -# for (seq_i in 1:max_pos) { -# score_vec[[out_kmer_i]][seq_i] = .score(seq_vec[out_kmer_i], seq_i, prof, background) -# } -# if (sum(score_vec[[out_kmer_i]]) != 0) { -# poses = c(1:max_pos)[!is.na(score_vec[[out_kmer_i]])] -# start_pos[out_kmer_i] = sample(c(1:max_pos), 1, prob = score_vec[[out_kmer_i]][poses] / sum(score_vec[[out_kmer_i]][poses])) -# } -# } -# -# add_pb(pb) -# -# if (sum(prev_start_pos != start_pos) == 0) { -# break -# } -# } -# close(pb) -# -# data.frame(Motif = substr(seq_vec, start_pos, start_pos + .motif.len - 1), -# Start = start_pos, -# Score = sapply(1:length(score_vec), function (i) { score_vec[[i]][start_pos[i]] }), stringsAsFactors = FALSE) -# } diff --git a/R/overlap.R b/R/overlap.R index 2a2cfad5..4c33389c 100644 --- a/R/overlap.R +++ b/R/overlap.R @@ -6,15 +6,19 @@ #' @importFrom magrittr "%>%" #' @importFrom dtplyr lazy_dt #' -#' @description The \code{repOverlap} function is designed to analyse the overlap between +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' The `repOverlap` function is designed to analyse the overlap between #' two or more repertoires. It contains a number of methods to compare immune receptor #' sequences that are shared between individuals. #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -23,7 +27,7 @@ #' Note: each connection must represent a separate repertoire. #' #' @param .method A string that specifies the method of analysis or a combination of -#' methods. The \code{repOverlap} function supports following basic methods: +#' methods. The `repOverlap` function supports following basic methods: #' "public", "overlap", "jaccard", "tversky", "cosine", "morisita". #' If vector of multiple methods is given for this parameter, the first method will be used. #' @@ -83,7 +87,7 @@ #' #' If one of the incremental method is chosen, return list of overlap matrix. #' -#' @seealso \link{inc_overlap}, \link{vis} +#' @seealso [inc_overlap], [vis] #' #' @examples #' data(immdata) @@ -332,13 +336,17 @@ horn_index <- function(.x, .y) { #' #' @concept overlap #' -#' @description For reference please look up https://www.pnas.org/content/111/16/5980 (Fig. 4). +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' For reference please look up https://www.pnas.org/content/111/16/5980 (Fig. 4). #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -346,7 +354,7 @@ horn_index <- function(.x, .y) { #' #' Note: each connection must represent a separate repertoire. #' -#' @param .fun Function to compute overlaps. e.g., \code{morisita_index}. +#' @param .fun Function to compute overlaps. e.g., `morisita_index`. #' #' @param .step Either an integer or a numeric vector. #' @@ -354,7 +362,7 @@ horn_index <- function(.x, .y) { #' #' In the second case, the vector encodes all repertoire sampling depths. #' -#' @param .n.steps Integer. Number of steps if \code{.step} is a single integer. +#' @param .n.steps Integer. Number of steps if `.step` is a single integer. #' Skipped if ".step" is a numeric vector. #' #' @param .downsample If TRUE then performs downsampling to N clonotypes at each step instead of choosing the @@ -364,7 +372,7 @@ horn_index <- function(.x, .y) { #' #' @param .verbose.inc Logical. If TRUE then shows the output from the computation process. #' -#' @param ... Other arguments passed to \code{.fun}. +#' @param ... Other arguments passed to `.fun`. #' #' @return #' List with overlap matrices. diff --git a/R/overlap_analysis.R b/R/overlap_analysis.R index 90deea4b..51993f2a 100644 --- a/R/overlap_analysis.R +++ b/R/overlap_analysis.R @@ -2,12 +2,16 @@ #' #' @concept overlap #' -#' @description The \code{\link{repOverlapAnalysis}} function contains advanced data +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' The [repOverlapAnalysis()] function contains advanced data #' analysis methods. You can use several clustering and dimensionality reduction #' techniques in order to investigate further the difference between repertoires #' provided. #' -#' To cluster a subset of similar data with \code{\link{repOverlapAnalysis}} you can +#' To cluster a subset of similar data with [repOverlapAnalysis()] you can #' perform hierarchical clustering, k-means or dbscan ('hclust', 'kmeans', 'dbscan' #' respectively). #' @@ -16,21 +20,21 @@ #' respectively). #' #' @param .data Any distance matrix between pairs of repertoires. You can also pass your -#' output from \code{\link{repOverlap}}. +#' output from [repOverlap()]. #' @param .method A string that defines the type of analysis to perform. #' @param .scale A function to scale the data before passing it to the MDS algorithm. #' @param .raw A logical value. Set TRUE if you want to receive raw output of clustering #' or dimensionality reduction function of choice. Set FALSE if you want to receive -#' processed output that can be subjected to visualisation with \code{\link{vis}} function. +#' processed output that can be subjected to visualisation with [vis()] function. #' -#' @param .perp A numerical value, t-SNE parameter, see \code{\link{immunr_tsne}}. -#' @param .theta A numerical value, t-SNE parameter, see \code{\link{immunr_tsne}}. +#' @param .perp A numerical value, t-SNE parameter, see [immunr_tsne()]. +#' @param .theta A numerical value, t-SNE parameter, see [immunr_tsne()]. #' -#' @param .eps A numerical value, DBscan epsylon parameter, see \code{\link{immunr_dbscan}}. +#' @param .eps A numerical value, DBscan epsylon parameter, see [immunr_dbscan()]. #' -#' @param .k The number of clusters to create, passed as \code{k} to \link[factoextra]{hcut} or as \code{centers} to \link{kmeans}. +#' @param .k The number of clusters to create, passed as `k` to [hcut][factoextra::hcut] or as `centers` to [kmeans]. #' -#' @return Depends on the last element in the \code{.method} string. See \link{immunr_tsne} for more info. +#' @return Depends on the last element in the `.method` string. See [immunr_tsne] for more info. #' #' @examples #' data(immdata) diff --git a/R/phylip.R b/R/phylip.R index 60c819c3..4f9bb4e0 100644 --- a/R/phylip.R +++ b/R/phylip.R @@ -15,7 +15,11 @@ #' @importFrom uuid UUIDgenerate #' @importFrom data.table fread -#' @description This function uses the PHYLIP package to make phylogenetic analysis. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' This function uses the PHYLIP package to make phylogenetic analysis. #' For making trees it uses maximum parsimony methods. #' #' @usage diff --git a/R/preprocessing.R b/R/preprocessing.R index 2d01161e..18533c6b 100644 --- a/R/preprocessing.R +++ b/R/preprocessing.R @@ -8,7 +8,7 @@ #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list diff --git a/R/public.R b/R/public.R index a7dd4bee..b8113033 100644 --- a/R/public.R +++ b/R/public.R @@ -9,11 +9,16 @@ #' @importFrom data.table setcolorder ":=" as.data.table #' @importFrom dplyr full_join ungroup #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -123,7 +128,7 @@ publicRepertoire <- pubRep #' #' @concept pubrep #' -#' @param .data Public repertoire, an output from \link{pubRep}. +#' @param .data Public repertoire, an output from [pubRep]. #' #' @return #' Matrix with per-sample clonotype counts / proportions only. @@ -168,9 +173,13 @@ get_public_repertoire_names <- function(.pr) { #' #' @aliases pubRepFilter publicRepertoireFilter #' -#' @description Filter our clonotypes with low incidence in a specific group. +#' @description +#' +#' `r lifecycle::badge('deprecated')` #' -#' @param .pr Public repertoires, an output from \link{pubRep}. +#' Filter our clonotypes with low incidence in a specific group. +#' +#' @param .pr Public repertoires, an output from [pubRep]. #' @param .meta Metadata file. #' @param .by Named character vector. Names of the group to filter by. #' @param .min.samples Integer. Filters out clonotypes with the number of samples below than this number. @@ -241,7 +250,7 @@ publicRepertoireFilter <- pubRepFilter #' @param .pr1 First public repertoire. #' @param .pr2 Second public repertoire. #' @param .fun A function to apply to pairs of frequencies of same clonotypes from "pr1" and "pr2". -#' By default - \code{log(X) / log(Y)} where \code{X,Y} - frequencies of the same clonotype, +#' By default - `log(X) / log(Y)` where `X,Y` - frequencies of the same clonotype, #' found in both public repertoires. #' #' @return @@ -288,7 +297,12 @@ publicRepertoireApply <- pubRepApply #' @importFrom dplyr group_by mutate filter #' @importFrom stats na.omit #' -#' @param .data Public repertoire, an output from the \link{pubRep} function. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' +#' @param .data Public repertoire, an output from the [pubRep] function. #' @param .by Work in Progress. #' @param .meta Work in Progress. #' diff --git a/R/sampling.R b/R/sampling.R index d26868b5..a256be4a 100644 --- a/R/sampling.R +++ b/R/sampling.R @@ -24,11 +24,11 @@ #' @description #' Sample (downsample) repertoires using different approches. #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -49,19 +49,19 @@ #' @return Subsampled immune repertoire or a list of subsampled immune repertoires. #' #' @details -#' If \code{.method} is "downsample" then \code{repSample} chooses \code{.n} clones (not clonotypes!) from the input repertoires without any probabilistic simulation, +#' If `.method` is "downsample" then `repSample` chooses `.n` clones (not clonotypes!) from the input repertoires without any probabilistic simulation, #' but exactly computing each choosed clones. Such approach is is more consistent and biologically pleasant than -#' an output from the function if \code{.method} is "resample". +#' an output from the function if `.method` is "resample". #' -#' If \code{.method} is "resample" then \code{repSample} uses multinomial distribution to compute the number of occurences for each cloneset. -#' then it removes zero-number clonotypes and return the resulting data frame. Probabilities for \code{rmultinom} for each cloneset +#' If `.method` is "resample" then `repSample` uses multinomial distribution to compute the number of occurences for each cloneset. +#' then it removes zero-number clonotypes and return the resulting data frame. Probabilities for `rmultinom` for each cloneset #' is a percentage of this cloneset in the "Proportion" column. It's a some sort of simulation of how clonotypes are chosen from the organisms. #' -#' if \code{.method} is "sample" then \code{repSample} chooses \code{.n} clonotypes (not clones!) randomly. Depending on the -#' \code{.prob} argument, the function chooses clonotypes either according to their size (if \code{.prob} is TRUE, by default), -#' or each clonotype has an equal chance to be choosed (if \code{.prob} is FALSE). Note that sampling is done without replacing. +#' if `.method` is "sample" then `repSample` chooses `.n` clonotypes (not clones!) randomly. Depending on the +#' `.prob` argument, the function chooses clonotypes either according to their size (if `.prob` is TRUE, by default), +#' or each clonotype has an equal chance to be choosed (if `.prob` is FALSE). Note that sampling is done without replacing. #' -#' @seealso \link{rmultinom}, \link{clonal_proportion} +#' @seealso [rmultinom], [clonal_proportion] #' #' @examples #' data(immdata) diff --git a/R/seqCluster.R b/R/seqCluster.R index 1847aeef..050c49a6 100644 --- a/R/seqCluster.R +++ b/R/seqCluster.R @@ -10,18 +10,22 @@ #' @importFrom tibble rownames_to_column #' @importFrom glue glue #' -#' @description Graph clustering based on distances between sequences +#' @description +#' +#' `r lifecycle::badge("deprecated")` +#' +#' Graph clustering based on distances between sequences #' #' @usage #' #' seqCluster(.data, .dist, .perc_similarity, .nt_similarity, .fixed_threshold) #' -#' @param .data The data which was used to caluculate .dist object. Can be \link{data.frame}, +#' @param .data The data which was used to caluculate .dist object. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' -#' Every object must have columns in the immunarch compatible format \link{immunarch_data_format} +#' Every object must have columns in the immunarch compatible format [immunarch_data_format] #' -#' @param .dist List of distance objects produced with \link{seqDist} function. +#' @param .dist List of distance objects produced with [seqDist] function. #' #' @param .perc_similarity Numeric value between 0 and 1 specifying the maximum acceptable weight of an edge in a graph. #' This threshold depends on the length of sequences. @@ -34,12 +38,13 @@ #' Immdata data format object. Same as .data, but with extra 'Cluster' column with clusters assigned. #' #' @examples -#' +#' \dontrun{ #' data(immdata) #' # In this example, we will use only 2 samples with 500 clonotypes in each for time saving #' input_data <- lapply(immdata$data[1:2], head, 500) #' dist_result <- seqDist(input_data) #' cluster_result <- seqCluster(input_data, dist_result, .fixed_threshold = 1) +#' } #' @export seqCluster seqCluster <- function(.data, .dist, .perc_similarity, .nt_similarity, .fixed_threshold = 10) { diff --git a/R/shiny.R b/R/shiny.R index 7b2bd36b..a20e7d8f 100644 --- a/R/shiny.R +++ b/R/shiny.R @@ -11,7 +11,7 @@ if (getRversion() >= "2.15.1") { #' #' @importFrom graphics plot #' -#' @description The \code{fixVis} is a built-in software tool for the manipulation +#' @description The `fixVis` is a built-in software tool for the manipulation #' of plots, such as adjusting title text font and size, axes, and more. It is a powerful #' tool designed to produce publication-ready plots with minimal amount of coding. #' diff --git a/R/singlecell.R b/R/singlecell.R index 3f8ecd34..1bd14853 100644 --- a/R/singlecell.R +++ b/R/singlecell.R @@ -9,17 +9,21 @@ if (getRversion() >= "2.15.1") { #' #' @concept single_cell #' -#' @description Subsets the input immune repertoire by barcodes. Creates a vector of +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Subsets the input immune repertoire by barcodes. Creates a vector of #' barcodes to subset or a vector cluster IDs and corresponding barcodes to #' get a list of immune repertoires corresponding to cluster IDs. #' Columns with clonotype counts #' and proportions are changed accordingly to the filtered barcodes. #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list @@ -28,7 +32,7 @@ if (getRversion() >= "2.15.1") { #' Note: each connection must represent a separate repertoire. #' #' @param .barcodes Either a character vector with barcodes or a named character/factor vector with -#' barcodes as names and cluster IDs a vector elements. The output of Seurat's \code{Idents} function works. +#' barcodes as names and cluster IDs a vector elements. The output of Seurat's `Idents` function works. #' #' @param .force.list Logical. If TRUE then always returns a list, even if the result is one data frame. #' @@ -37,7 +41,7 @@ if (getRversion() >= "2.15.1") { #' with clonotype barcodes corresponding to the input barcodes. The output list names are cluster names #' in the ".barcode" argument (Seurat::Idents() case only). #' -#' @seealso \link{select_clusters} +#' @seealso [select_clusters] #' #' @examples #' \dontrun{ @@ -120,7 +124,11 @@ select_barcodes <- function(.data, .barcodes, .force.list = FALSE) { #' #' @concept single_cell #' -#' @description Given the vector of barcodes from Seurat, splits the input repertoires +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Given the vector of barcodes from Seurat, splits the input repertoires #' to separate subsets following the barcodes' assigned IDs. Useful in case you want to #' split immune repertoires by patients or clusters. #' @@ -128,7 +136,7 @@ select_barcodes <- function(.data, .barcodes, .force.list = FALSE) { #' immune repertoires, and "meta" being a metadata table. #' #' @param .clusters Factor vector with barcodes as vector names and cluster IDs as vector elements. -#' The output of the Seurat \code{Idents} function works. +#' The output of the Seurat `Idents` function works. #' #' @param .field A string specifying the name of the field in the input metadata. New immune #' repertoire subsets will have cluster IDs in this field. @@ -136,7 +144,7 @@ select_barcodes <- function(.data, .barcodes, .force.list = FALSE) { #' @return A list with two elements "data" and "meta" with updated immune repertoire tables and #' metadata. #' -#' @seealso \link{select_barcodes} +#' @seealso [select_barcodes] #' #' @examples #' \dontrun{ diff --git a/R/somatic_hypermutation.R b/R/somatic_hypermutation.R index 8d6bed7b..bb220256 100644 --- a/R/somatic_hypermutation.R +++ b/R/somatic_hypermutation.R @@ -11,7 +11,11 @@ #' @importFrom doParallel registerDoParallel stopImplicitCluster #' @importFrom ape as.DNAbin clustal #' -#' @description This function aligns V and J genes from the germline in each cluster +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' This function aligns V and J genes from the germline in each cluster #' with corresponding genes in each clonotype, saves the alignments for purpose of visualization, #' and calculates number of mutations for each clonotype. #' diff --git a/R/spectratyping.R b/R/spectratyping.R index e9b9debb..d387fe20 100644 --- a/R/spectratyping.R +++ b/R/spectratyping.R @@ -4,11 +4,16 @@ #' #' @importFrom dplyr summarise group_by #' -#' @param .data The data to be processed. Can be \link{data.frame}, +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' +#' @param .data The data to be processed. Can be [data.frame], #' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. -#' \link{immunarch_data_format} +#' [immunarch_data_format] #' #' Competent users may provide advanced data representations: #' DBI database connections, or a list diff --git a/man/apply_symm.Rd b/man/apply_symm.Rd index ab351614..bdb15938 100644 --- a/man/apply_symm.Rd +++ b/man/apply_symm.Rd @@ -21,7 +21,7 @@ apply_asymm(.datalist, .fun, ..., .diag = NA, .verbose = TRUE) \item{.verbose}{if TRUE then output a progress bar.} } \value{ -Matrix with values M[i,j] = fun(datalist[i], datalist[j]) +Matrix with values M\link{i,j} = fun(datalist\link{i}, datalist\link{j}) } \description{ Apply the given function to every pair in the given datalist. Function either diff --git a/man/bcrdata.Rd b/man/bcrdata.Rd index 5af8aee0..f641727f 100644 --- a/man/bcrdata.Rd +++ b/man/bcrdata.Rd @@ -9,9 +9,9 @@ A list of two elements. The first element ("data") is a list of 1 element named that contains immune repertoire data frame. The second element ("meta") is empty metadata table. \describe{ - \item{data}{List of immune repertoire data frames.} - \item{meta}{Metadata} - ... +\item{data}{List of immune repertoire data frames.} +\item{meta}{Metadata} +... } } \usage{ diff --git a/man/coding.Rd b/man/coding.Rd index 596efb92..5bcfb461 100644 --- a/man/coding.Rd +++ b/man/coding.Rd @@ -16,11 +16,11 @@ inframes(.data) outofframes(.data) } \arguments{ -\item{.data}{The data to be processed. Can be [data.frame], -[data.table], or a list of these objects. +\item{.data}{The data to be processed. Can be \link{data.frame}, +\link{data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. -[immunarch_data_format] +\link{immunarch_data_format} Competent users may provide advanced data representations: DBI database connections, Apache Spark DataFrame from "copy_to" or a list @@ -34,13 +34,13 @@ Filtered data frame. \description{ Filter out clonotypes with non-coding, coding, in-frame or out-of-frame CDR3 sequences: -`coding()` - remove all non-coding sequences (i.e., remove all sequences with stop codons and frame shifts); +\code{coding()} - remove all non-coding sequences (i.e., remove all sequences with stop codons and frame shifts); -`noncoding()` - remove all coding sequences (i.e., leave sequences with stop codons and frame shifts only); +\code{noncoding()} - remove all coding sequences (i.e., leave sequences with stop codons and frame shifts only); -`inframes()` - remove all out-of-frame sequences (i.e., remove all sequences with frame shifts); +\code{inframes()} - remove all out-of-frame sequences (i.e., remove all sequences with frame shifts); -`outofframes()` - remove all in-frame sequences (i.e., leave sequences with frame shifts only). +\code{outofframes()} - remove all in-frame sequences (i.e., leave sequences with frame shifts only). Note: the function will remove all clonotypes sequences with NAs in the CDR3 amino acid column. } diff --git a/man/dbAnnotate.Rd b/man/dbAnnotate.Rd index 4d1deff4..9f665944 100644 --- a/man/dbAnnotate.Rd +++ b/man/dbAnnotate.Rd @@ -21,19 +21,21 @@ Note: each connection must represent a separate repertoire.} \item{.db}{A data frame or a data table with an immune receptor database. See \link{dbLoad} on how to load databases into R.} -\item{.data.col}{Character vector. Vector of columns in the input repertoires to use for clonotype search. E.g., `"CDR3.aa"` or `c("CDR3.aa", "V.name")`.} +\item{.data.col}{Character vector. Vector of columns in the input repertoires to use for clonotype search. E.g., \code{"CDR3.aa"} or \code{c("CDR3.aa", "V.name")}.} \item{.db.col}{Character vector. Vector of columns in the database to use for clonotype search. The order must match the order of ".data.col". -E.g., if ".data.col" is `c("CDR3.aa", "V.name")`, then ".db.col" must have the exact order of columns. i.e., the first column must correspond +E.g., if ".data.col" is \code{c("CDR3.aa", "V.name")}, then ".db.col" must have the exact order of columns. i.e., the first column must correspond to CDR3 amino acid sequences, and the second column must correspond to V gene segment names.} } \value{ Data frame with input sequences and counts or proportions for each of the input repertoire. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Annotate clonotypes by matching them to known condition-associated immune receptors in a database. Before using this function, you must download or load the relevant database files. -For more information, see the [online tutorial](https://immunarch.com/articles/web_only/v11_db.html). +For more information, see the \href{https://immunarch.com/articles/web_only/v11_db.html}{online tutorial}. } \examples{ data(immdata) diff --git a/man/dbLoad.Rd b/man/dbLoad.Rd index 68dfda69..a4aaaaf6 100644 --- a/man/dbLoad.Rd +++ b/man/dbLoad.Rd @@ -28,6 +28,8 @@ Pass NA (by default) to load all available conditions.} Data frame with the input database records. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + The function automatically detects the database format and loads it into R. Additionally, the function provides a general query interface to databases that allows filtering by species, chain types (i.e., locus) and pathology (i.e., antigen species). diff --git a/man/entropy.Rd b/man/entropy.Rd index 35ee98c2..1e0c624c 100644 --- a/man/entropy.Rd +++ b/man/entropy.Rd @@ -37,6 +37,8 @@ cross_entropy(.alpha, .beta, .base = 2, .do.norm = NA, A numeric value. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Compute information-based estimates and distances. } \examples{ diff --git a/man/figures/lifecycle-deprecated.svg b/man/figures/lifecycle-deprecated.svg new file mode 100644 index 00000000..b61c57c3 --- /dev/null +++ b/man/figures/lifecycle-deprecated.svg @@ -0,0 +1,21 @@ + + lifecycle: deprecated + + + + + + + + + + + + + + + lifecycle + + deprecated + + diff --git a/man/figures/lifecycle-experimental.svg b/man/figures/lifecycle-experimental.svg new file mode 100644 index 00000000..5d88fc2c --- /dev/null +++ b/man/figures/lifecycle-experimental.svg @@ -0,0 +1,21 @@ + + lifecycle: experimental + + + + + + + + + + + + + + + lifecycle + + experimental + + diff --git a/man/figures/lifecycle-stable.svg b/man/figures/lifecycle-stable.svg new file mode 100644 index 00000000..9bf21e76 --- /dev/null +++ b/man/figures/lifecycle-stable.svg @@ -0,0 +1,29 @@ + + lifecycle: stable + + + + + + + + + + + + + + + + lifecycle + + + + stable + + + diff --git a/man/figures/lifecycle-superseded.svg b/man/figures/lifecycle-superseded.svg new file mode 100644 index 00000000..db8d757f --- /dev/null +++ b/man/figures/lifecycle-superseded.svg @@ -0,0 +1,21 @@ + + lifecycle: superseded + + + + + + + + + + + + + + + lifecycle + + superseded + + diff --git a/man/geneUsage.Rd b/man/geneUsage.Rd index 6ac9725f..fe830fe4 100644 --- a/man/geneUsage.Rd +++ b/man/geneUsage.Rd @@ -17,7 +17,7 @@ geneUsage( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -38,12 +38,10 @@ Pass NA if you want to compute gene statistics at the clonotype level without re Pass "count" to use the "Clones" column to weight genes by abundance of their corresponding clonotypes.} \item{.ambig}{An option to handle ambiguous gene assigments, e.g., "TRAV1,TRAV2". - - -- Pass "inc" to include all possible gene segments, so "TRAV1,TRAV2" is counted as a different gene segment. - -- Pass "exc" to exclude all ambiguous gene assignments, so "TRAV1,TRAV2" is excluded from the resultant gene table. - +\itemize{ +\item Pass "inc" to include all possible gene segments, so "TRAV1,TRAV2" is counted as a different gene segment. +\item Pass "exc" to exclude all ambiguous gene assignments, so "TRAV1,TRAV2" is excluded from the resultant gene table. +} We recommend to turn it on by passing "inc" (turned on by default). You can exclude data for the cases where @@ -58,9 +56,11 @@ or pick only first from the set. Set it to "exc", "inc" or "maj", respectively.} A data frame with rows corresponding to gene segments and columns corresponding to the input samples. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + An utility function to analyse the immune receptor gene usage (IGHD, IGHJ, IDHV, IGIJ, IGKJ, IGKV, IGLJ, IGLV, TRAJ, TRAV, TRBD, etc.) -and statistics. For gene details run `gene_stats()`. +and statistics. For gene details run \code{gene_stats()}. } \examples{ data(immdata) diff --git a/man/geneUsageAnalysis.Rd b/man/geneUsageAnalysis.Rd index 64dd023a..d456a579 100644 --- a/man/geneUsageAnalysis.Rd +++ b/man/geneUsageAnalysis.Rd @@ -20,8 +20,8 @@ geneUsageAnalysis( ) } \arguments{ -\item{.data}{The \code{\link{geneUsageAnalysis}} function runs on the output from -\code{\link{geneUsage}}.} +\item{.data}{The \code{\link[=geneUsageAnalysis]{geneUsageAnalysis()}} function runs on the output from +\code{\link[=geneUsage]{geneUsage()}}.} \item{.method}{A string that defines the type of analysis to perform. Can be "pca", "mds", "js", "kmeans", "hclust", "dbscan" or "cor" if you want to calculate @@ -44,20 +44,22 @@ smoothing.} \item{.verbose}{A logical value.} -\item{.k}{The number of clusters to create, passed as \code{k} to \link[factoextra]{hcut} or as \code{centers} to \link{kmeans}.} +\item{.k}{The number of clusters to create, passed as \code{k} to \link[factoextra:hcut]{hcut} or as \code{centers} to \link{kmeans}.} \item{.eps}{A numerical value, DBscan epsylon parameter, see -\code{\link{immunr_dbscan}}.} +\code{\link[=immunr_dbscan]{immunr_dbscan()}}.} -\item{.perp}{A numerical value, t-SNE perplexity, see \code{\link{immunr_tsne}}.} +\item{.perp}{A numerical value, t-SNE perplexity, see \code{\link[=immunr_tsne]{immunr_tsne()}}.} -\item{.theta}{A numerical value, t-SNE theta parameter, see \code{\link{immunr_tsne}}.} +\item{.theta}{A numerical value, t-SNE theta parameter, see \code{\link[=immunr_tsne]{immunr_tsne()}}.} } \value{ Depends on the last element in the \code{.method} string. See \link{immunr_tsne} for more info. } \description{ -The \code{\link{geneUsageAnalysis}} function deploys several +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + +The \code{\link[=geneUsageAnalysis]{geneUsageAnalysis()}} function deploys several data analysis methods, including PCA, multidimensional scaling, Jensen-Shannon divergence, k-means, hierarchical clustering, DBscan, and different correlation coefficients. diff --git a/man/getKmers.Rd b/man/getKmers.Rd index 2aedd9a2..1c34e395 100644 --- a/man/getKmers.Rd +++ b/man/getKmers.Rd @@ -10,7 +10,7 @@ getKmers(.data, .k, .col = c("aa", "nt"), .coding = TRUE) } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -32,7 +32,7 @@ pass "nt" for CDR3 nucleotide sequences.} Data frame with two columns (k-mers and their counts). } \description{ -Calculate the k-mer statistics of immune repertoires +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/get_immunarch_news.Rd b/man/get_immunarch_news.Rd index 3965fdc5..96040132 100644 --- a/man/get_immunarch_news.Rd +++ b/man/get_immunarch_news.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/zzz.R +% Please edit documentation in R/v1_migration_utils.R \name{get_immunarch_news} \alias{get_immunarch_news} \title{Get the Latest immunarch Update} @@ -7,8 +7,8 @@ get_immunarch_news(datepoint = "latest") } \arguments{ -\item{datepoint}{A string specifying the update date. Use `"latest"` for the most recent update -or supply a valid date key (e.g., `"Apr 2025"`).} +\item{datepoint}{A string specifying the update date. Use \code{"latest"} for the most recent update +or supply a valid date key (e.g., \code{"Apr 2025"}).} } \value{ A character string with the update details or a warning if the key is not found. @@ -17,10 +17,10 @@ A character string with the update details or a warning if the key is not found. Retrieves an update message for immunarch. } \details{ -If `datepoint` is set to `"latest"`, the function returns the most recent update. -Otherwise, specify the update date key (e.g., `"Apr 2025"`) to retrieve that particular update. +If \code{datepoint} is set to \code{"latest"}, the function returns the most recent update. +Otherwise, specify the update date key (e.g., \code{"Apr 2025"}) to retrieve that particular update. If no matching update is found, a warning is issued along with available update keys. } \seealso{ -[list_immunarch_news()] +\code{\link[=list_immunarch_news]{list_immunarch_news()}} } diff --git a/man/immdata.Rd b/man/immdata.Rd index 2b401d71..658a0973 100644 --- a/man/immdata.Rd +++ b/man/immdata.Rd @@ -8,9 +8,9 @@ A list of two elements. The first element ("data") is a list with data frames with clonotype tables. The second element ("meta") is a metadata table. \describe{ - \item{data}{List of immune repertoire data frames.} - \item{meta}{Metadata} - ... +\item{data}{List of immune repertoire data frames.} +\item{meta}{Metadata} +... } } \usage{ diff --git a/man/immunarch_v1_updates.Rd b/man/immunarch_v1_updates.Rd index 76e1719c..00b0c453 100644 --- a/man/immunarch_v1_updates.Rd +++ b/man/immunarch_v1_updates.Rd @@ -5,7 +5,7 @@ \alias{immunarch_v1_updates} \title{Some description} \format{ -An object of class \code{NULL} of length 0. +An object of class \code{list} of length 1. } \usage{ immunarch_v1_updates diff --git a/man/immunr_data_format.Rd b/man/immunr_data_format.Rd index e052e246..0d24fe99 100644 --- a/man/immunr_data_format.Rd +++ b/man/immunr_data_format.Rd @@ -6,34 +6,22 @@ \alias{immunarch_data_format} \title{Specification of the data format used by immunarch dataframes} \description{ -- "Clones" - number of barcodes (events, UMIs) or reads; - -- "Proportion" - proportion of barcodes (events, UMIs) or reads; - -- "CDR3.nt" - CDR3 nucleotide sequence; - -- "CDR3.aa" - CDR3 amino acid sequence; - -- "V.name" - names of aligned Variable gene segments; - -- "D.name" - names of aligned Diversity gene segments or NA; - -- "J.name" - names of aligned Joining gene segments; - -- "V.end" - last positions of aligned V gene segments (1-based); - -- "D.start" - positions of D'5 end of aligned D gene segments (1-based); - -- "D.end" - positions of D'3 end of aligned D gene segments (1-based); - -- "J.start" - first positions of aligned J gene segments (1-based); - -- "VJ.ins" - number of inserted nucleotides (N-nucleotides) at V-J junction (-1 for receptors with VDJ recombination); - -- "VD.ins" - number of inserted nucleotides (N-nucleotides) at V-D junction (-1 for receptors with VJ recombination); - -- "DJ.ins" - number of inserted nucleotides (N-nucleotides) at D-J junction (-1 for receptors with VJ recombination); - -- "Sequence" - full nucleotide sequence. +\itemize{ +\item "Clones" - number of barcodes (events, UMIs) or reads; +\item "Proportion" - proportion of barcodes (events, UMIs) or reads; +\item "CDR3.nt" - CDR3 nucleotide sequence; +\item "CDR3.aa" - CDR3 amino acid sequence; +\item "V.name" - names of aligned Variable gene segments; +\item "D.name" - names of aligned Diversity gene segments or NA; +\item "J.name" - names of aligned Joining gene segments; +\item "V.end" - last positions of aligned V gene segments (1-based); +\item "D.start" - positions of D'5 end of aligned D gene segments (1-based); +\item "D.end" - positions of D'3 end of aligned D gene segments (1-based); +\item "J.start" - first positions of aligned J gene segments (1-based); +\item "VJ.ins" - number of inserted nucleotides (N-nucleotides) at V-J junction (-1 for receptors with VDJ recombination); +\item "VD.ins" - number of inserted nucleotides (N-nucleotides) at V-D junction (-1 for receptors with VJ recombination); +\item "DJ.ins" - number of inserted nucleotides (N-nucleotides) at D-J junction (-1 for receptors with VJ recombination); +\item "Sequence" - full nucleotide sequence. +} } \concept{data} diff --git a/man/immunr_hclust.Rd b/man/immunr_hclust.Rd index a8f468f1..9f167951 100644 --- a/man/immunr_hclust.Rd +++ b/man/immunr_hclust.Rd @@ -16,39 +16,40 @@ immunr_dbscan(.data, .eps, .dist = TRUE) \arguments{ \item{.data}{Matrix or data frame with features, distance matrix or output from \link{repOverlapAnalysis} or \link{geneUsageAnalysis} functions.} -\item{.k}{The number of clusters to create, defined as \code{k} to \link[factoextra]{hcut} or as \code{centers} to \link{kmeans}.} +\item{.k}{The number of clusters to create, defined as \code{k} to \link[factoextra:hcut]{hcut} or as \code{centers} to \link{kmeans}.} -\item{.k.max}{Limits the maximum number of clusters. It is passed as \code{k.max} to [factoextra::fviz_nbclust] for \code{immunr_hclust} and \code{immunr_kmeans}.} +\item{.k.max}{Limits the maximum number of clusters. It is passed as \code{k.max} to \link[factoextra:fviz_nbclust]{factoextra::fviz_nbclust} for \code{immunr_hclust} and \code{immunr_kmeans}.} -\item{.method}{Passed to [factoextra::hcut] or as [factoextra::fviz_nbclust]. +\item{.method}{Passed to \link[factoextra:hcut]{factoextra::hcut} or as \link[factoextra:fviz_nbclust]{factoextra::fviz_nbclust}. -In case of [factoextra::hcut] the agglomeration method is going to be used (argument \code{hc_method}). +In case of \link[factoextra:hcut]{factoextra::hcut} the agglomeration method is going to be used (argument \code{hc_method}). -In case of [factoextra::fviz_nbclust] it is the method to be used for estimating the optimal number of clusters (argument \code{method}).} +In case of \link[factoextra:fviz_nbclust]{factoextra::fviz_nbclust} it is the method to be used for estimating the optimal number of clusters (argument \code{method}).} \item{.dist}{If TRUE then ".data" is expected to be a distance matrix. If FALSE then the euclidean distance is computed for the input objects.} -\item{.eps}{Local radius for expanding clusters, minimal distance between points to expand clusters. Passed as \code{eps} to \link[fpc]{dbscan}.} +\item{.eps}{Local radius for expanding clusters, minimal distance between points to expand clusters. Passed as \code{eps} to \link[fpc:dbscan]{dbscan}.} } \value{ -\code{immunr_hclust} - list with two elements. The first element is an output from [factoextra::hcut]. -The second element is an output from [factoextra::fviz_nbclust] +\code{immunr_hclust} - list with two elements. The first element is an output from \link[factoextra:hcut]{factoextra::hcut}. +The second element is an output from \link[factoextra:fviz_nbclust]{factoextra::fviz_nbclust} \code{immunr_kmeans} - list with three elements. The first element is an output from \link{kmeans}. -The second element is an output from [factoextra::fviz_nbclust]. +The second element is an output from \link[factoextra:fviz_nbclust]{factoextra::fviz_nbclust}. The third element is the input dataset \code{.data}. -\code{immunr_dbscan} - list with two elements. The first element is an output from [fpc::dbscan]. +\code{immunr_dbscan} - list with two elements. The first element is an output from \link[fpc:dbscan]{fpc::dbscan}. The second element is the input dataset \code{.data}. } \description{ -Clusters the data with one of the following methods: - -- \code{immunr_hclust} clusters the data using the hierarchical clustering from \link[factoextra]{hcut}; - -- \code{immunr_kmeans} clusters the data using the K-means algorithm from \link{kmeans}; +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -- \code{immunr_dbscan} clusters the data using the DBSCAN algorithm from \link[fpc]{dbscan}. +Clusters the data with one of the following methods: +\itemize{ +\item \code{immunr_hclust} clusters the data using the hierarchical clustering from \link[factoextra:hcut]{hcut}; +\item \code{immunr_kmeans} clusters the data using the K-means algorithm from \link{kmeans}; +\item \code{immunr_dbscan} clusters the data using the DBSCAN algorithm from \link[fpc:dbscan]{dbscan}. +} } \examples{ data(immdata) diff --git a/man/immunr_pca.Rd b/man/immunr_pca.Rd index 1703739e..264ac2bf 100644 --- a/man/immunr_pca.Rd +++ b/man/immunr_pca.Rd @@ -26,29 +26,30 @@ if you want to visualise results.} \item{.dist}{If TRUE then assumes that ".data" is a distance matrix.} -\item{.perp}{The perplexity parameter for \link[Rtsne]{Rtsne}. Specifies the number +\item{.perp}{The perplexity parameter for \link[Rtsne:Rtsne]{Rtsne}. Specifies the number of neighbors each data point must have in the resulting plot.} -\item{...}{Other parameters passed to \link[Rtsne]{Rtsne}.} +\item{...}{Other parameters passed to \link[Rtsne:Rtsne]{Rtsne}.} } \value{ \code{immunr_pca} - an output from \link{prcomp}. -\code{immunr_mds} - an output from \link[MASS]{isoMDS}. +\code{immunr_mds} - an output from \link[MASS:isoMDS]{isoMDS}. -\code{immunr_tsne} - an output from \\link[Rtsne]{Rtsne}. +\code{immunr_tsne} - an output from [Rtsne][Rtsne::Rtsne]. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Collects a set of principal variables, reducing the number of not important variables to analyse. Dimensionality reduction makes data analysis algorithms work faster and sometimes more accurate, since it also reduces noise in the data. Currently available methods are: - -- \code{immunr_pca} performs PCA (Principal Component Analysis) using \link{prcomp}; - -- \code{immunr_mds} performs MDS (Multi-Dimensional Scaling) using \link[MASS]{isoMDS}; - -- \code{immunr_tsne} performs tSNE (t-Distributed Stochastic Neighbour Embedding) using \link[Rtsne]{Rtsne}. +\itemize{ +\item \code{immunr_pca} performs PCA (Principal Component Analysis) using \link{prcomp}; +\item \code{immunr_mds} performs MDS (Multi-Dimensional Scaling) using \link[MASS:isoMDS]{isoMDS}; +\item \code{immunr_tsne} performs tSNE (t-Distributed Stochastic Neighbour Embedding) using \link[Rtsne:Rtsne]{Rtsne}. +} } \examples{ data(immdata) diff --git a/man/inc_overlap.Rd b/man/inc_overlap.Rd index 8d5c0043..b2f25451 100644 --- a/man/inc_overlap.Rd +++ b/man/inc_overlap.Rd @@ -17,7 +17,7 @@ inc_overlap( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -52,6 +52,8 @@ top N clonotypes.} List with overlap matrices. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + For reference please look up https://www.pnas.org/content/111/16/5980 (Fig. 4). } \examples{ diff --git a/man/list_immunarch_news.Rd b/man/list_immunarch_news.Rd index 366ca870..983fbe68 100644 --- a/man/list_immunarch_news.Rd +++ b/man/list_immunarch_news.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/zzz.R +% Please edit documentation in R/v1_migration_utils.R \name{list_immunarch_news} \alias{list_immunarch_news} \title{List Available immunarch Updates} @@ -13,5 +13,5 @@ A character vector containing all the date keys for the available updates. Returns the list of available update keys for immunarch v1. } \seealso{ -[get_immunarch_news()] +\code{\link[=get_immunarch_news]{get_immunarch_news()}} } diff --git a/man/matrixdiagcopy.Rd b/man/matrixdiagcopy.Rd index 86568927..27751646 100644 --- a/man/matrixdiagcopy.Rd +++ b/man/matrixdiagcopy.Rd @@ -19,7 +19,7 @@ Copy the upper matrix triangle to the lower one mat <- matrix(0, 3, 3) mat -mat[1, 3] <- 1 +mat\link{1, 3} <- 1 mat <- immunarch:::matrixdiagcopy(mat) mat } diff --git a/man/pubRep.Rd b/man/pubRep.Rd index d268a9a7..f0dc4ff0 100644 --- a/man/pubRep.Rd +++ b/man/pubRep.Rd @@ -17,7 +17,7 @@ pubRep( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -49,15 +49,14 @@ in the public repertoire table. Set NA (by default) to have the maximal amount o } \value{ Data table with columns for: - -- Clonotypes (e.g., CDR3 sequence, or two columns for CDR3 sequence and V gene) - -- Incidence of clonotypes - -- Per-sample proportions or counts +\itemize{ +\item Clonotypes (e.g., CDR3 sequence, or two columns for CDR3 sequence and V gene) +\item Incidence of clonotypes +\item Per-sample proportions or counts +} } \description{ -Create a repertoire of public clonotypes +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ # Subset the data to make the example faster to run diff --git a/man/pubRepApply.Rd b/man/pubRepApply.Rd index 5cfe9d5c..6890eff7 100644 --- a/man/pubRepApply.Rd +++ b/man/pubRepApply.Rd @@ -13,7 +13,7 @@ pubRepApply(.pr1, .pr2, .fun = function(x) log10(x[1])/log10(x[2])) \item{.pr2}{Second public repertoire.} \item{.fun}{A function to apply to pairs of frequencies of same clonotypes from "pr1" and "pr2". -By default - \code{log(X) / log(Y)} where \code{X,Y} - frequencies of the same clonotype, +By default - \code{log(X) / log(Y)} where \verb{X,Y} - frequencies of the same clonotype, found in both public repertoires.} } \value{ diff --git a/man/pubRepFilter.Rd b/man/pubRepFilter.Rd index d57ed369..5acb9dbc 100644 --- a/man/pubRepFilter.Rd +++ b/man/pubRepFilter.Rd @@ -20,6 +20,8 @@ pubRepFilter(.pr, .meta, .by, .min.samples = 1) Data frame with filtered clonotypes. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Filter our clonotypes with low incidence in a specific group. } \examples{ diff --git a/man/pubRepStatistics.Rd b/man/pubRepStatistics.Rd index 4ce5aeb1..c8f66f97 100644 --- a/man/pubRepStatistics.Rd +++ b/man/pubRepStatistics.Rd @@ -17,7 +17,7 @@ pubRepStatistics(.data, .by = NA, .meta = NA) Data frame with incidence statistics per sample. } \description{ -Statistics of number of public clonotypes for each possible combinations of repertoires +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/repAlignLineage.Rd b/man/repAlignLineage.Rd index 8f00427d..7d204ba1 100644 --- a/man/repAlignLineage.Rd +++ b/man/repAlignLineage.Rd @@ -7,7 +7,7 @@ repAlignLineage(.data, .min_lineage_sequences, .prepare_threads, .align_threads, .nofail) } \arguments{ -\item{.data}{The data to be processed. Can be \link{data.frame}, [data.table::data.table] +\item{.data}{The data to be processed. Can be \link{data.frame}, \link[data.table:data.table]{data.table::data.table} or a list of these objects.} \item{.min_lineage_sequences}{If number of sequences in the same clonal lineage and the same @@ -29,17 +29,23 @@ Used to avoid raising errors in examples on computers where Clustal W is not ins \value{ Dataframe or list of dataframes (if input is a list with multiple samples). The dataframe has these columns: -* Cluster: cluster name -* Germline: germline sequence -* Alignment: DNAbin object with alignment -* Sequences: nested dataframe containing all sequences for this combination - of cluster and germline; it has columns - * Sequence, CDR1.nt, CDR2.nt, CDR3.nt, FR1.nt, FR2.nt, FR3.nt, FR4.nt, V.allele, J.allele, - V.aa, J.aa: all values taken from the input dataframe - * Clone.ID: taken from the input dataframe, or created (filled with row numbers) if missing - * Clones: taken from the input dataframe, or created (filled with '1' values) if missing +\itemize{ +\item Cluster: cluster name +\item Germline: germline sequence +\item Alignment: DNAbin object with alignment +\item Sequences: nested dataframe containing all sequences for this combination +of cluster and germline; it has columns +\itemize{ +\item Sequence, CDR1.nt, CDR2.nt, CDR3.nt, FR1.nt, FR2.nt, FR3.nt, FR4.nt, V.allele, J.allele, +V.aa, J.aa: all values taken from the input dataframe +\item Clone.ID: taken from the input dataframe, or created (filled with row numbers) if missing +\item Clones: taken from the input dataframe, or created (filled with '1' values) if missing +} +} } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + This function aligns all sequences (incliding germline) that belong to one clonal lineage and one cluster. After clustering and building the clonal lineage and germline, the next step is to analyze the degree of mutation and maturity of each clonal lineage. This allows for diff --git a/man/repClonalFamily.Rd b/man/repClonalFamily.Rd index 1f1adb78..1ba573c3 100644 --- a/man/repClonalFamily.Rd +++ b/man/repClonalFamily.Rd @@ -25,21 +25,25 @@ Used to avoid raising errors in examples on computers where PHYLIP is not instal \value{ Dataframe or list of dataframes (if input is a list with multiple samples). The dataframe has these columns: -* Cluster: cluster name -* Germline.Input: germline sequence, like it was in the input; not aligned -* Germline.Output: germline sequence, parsed from PHYLIP dnapars function output; - it contains difference of germline from the common ancestor; "." characters mean - matching letters -* Common.Ancestor: common ancestor sequence, parsed from PHYLIP dnapars function output -* Trunk.Length: mean trunk length, representing the distance between the most recent - common ancestor and germline sequence as a measure of the maturity of a lineage -* Tree: output tree in "phylo" format, loaded from by PHYLIP dnapars function output -* TreeStats: nested dataframe containing data about tree nodes, needed for visualization -* Sequences: nested dataframe containing all sequences for this combination of cluster - and germline; it contains regions from original sequences, saved for - repSomaticHypermutation() calculation, and also data needed for visualizations +\itemize{ +\item Cluster: cluster name +\item Germline.Input: germline sequence, like it was in the input; not aligned +\item Germline.Output: germline sequence, parsed from PHYLIP dnapars function output; +it contains difference of germline from the common ancestor; "." characters mean +matching letters +\item Common.Ancestor: common ancestor sequence, parsed from PHYLIP dnapars function output +\item Trunk.Length: mean trunk length, representing the distance between the most recent +common ancestor and germline sequence as a measure of the maturity of a lineage +\item Tree: output tree in "phylo" format, loaded from by PHYLIP dnapars function output +\item TreeStats: nested dataframe containing data about tree nodes, needed for visualization +\item Sequences: nested dataframe containing all sequences for this combination of cluster +and germline; it contains regions from original sequences, saved for +repSomaticHypermutation() calculation, and also data needed for visualizations +} } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + This function uses the PHYLIP package to make phylogenetic analysis. For making trees it uses maximum parsimony methods. } diff --git a/man/repClonality.Rd b/man/repClonality.Rd index be0d009b..99a7949a 100644 --- a/man/repClonality.Rd +++ b/man/repClonality.Rd @@ -22,7 +22,7 @@ repClonality( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -67,6 +67,8 @@ with clonality statistics. Otherwise, it returns a numeric matrix with clonality statistics for all input repertoires. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + \code{repClonality} function encompasses several methods to measure clonal proportions in a given repertoire. } diff --git a/man/repDiversity.Rd b/man/repDiversity.Rd index 7254ca74..20726616 100644 --- a/man/repDiversity.Rd +++ b/man/repDiversity.Rd @@ -30,7 +30,7 @@ repDiversity( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -82,7 +82,7 @@ div, gini, gini.simp, inv.simp, raref return numeric vector of length 1 with value. chao1 returns 4 values: estimated number of species, standart deviation of -this number and two 95% confidence intervals for the species number. +this number and two 95\% confidence intervals for the species number. hill returns a vector of specified length \code{.max.q - .min.q} @@ -97,6 +97,8 @@ For rarefaction the function returns either a matrix with diversity estimatinos on different step of the simulaiton process or a list with such matrices. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + This is a utility function to estimate the diversity of species or objects in the given distribution. Note: functions will check if .data is a distribution of a random variable (sum == 1) or not. @@ -104,36 +106,30 @@ To force normalisation and / or to prevent this, set .do.norm to TRUE (do normal or FALSE (don't do normalisation), respectively. } \details{ -- True diversity, or the effective number of types, refers to the number +\itemize{ +\item True diversity, or the effective number of types, refers to the number of equally-abundant types needed for the average proportional abundance of the types to equal that observed in the dataset of interest where all types may not be equally abundant. - -- Inverse Simpson index is the effective number of types that is obtained when +\item Inverse Simpson index is the effective number of types that is obtained when the weighted arithmetic mean is used to quantify average proportional abundance of types in the dataset of interest. - -- The Gini coefficient measures the inequality among values +\item The Gini coefficient measures the inequality among values of a frequency distribution (for example levels of income). A Gini coefficient of zero expresses perfect equality, where all values are the same (for example, where everyone has the same income). A Gini coefficient of one (or 100 percents ) expresses maximal inequality among values (for example where only one person has all the income). - -- The Gini-Simpson index is the probability of interspecific encounter, i.e., probability that two entities +\item The Gini-Simpson index is the probability of interspecific encounter, i.e., probability that two entities represent different types. - -- Chao1 estimator is a nonparameteric asymptotic estimator of species richness (number of species in a population). - -- Rarefaction is a technique to assess species richness from the results of sampling through extrapolation. - -- Hill numbers are a mathematically unified family of diversity indices (differing among themselves +\item Chao1 estimator is a nonparameteric asymptotic estimator of species richness (number of species in a population). +\item Rarefaction is a technique to assess species richness from the results of sampling through extrapolation. +\item Hill numbers are a mathematically unified family of diversity indices (differing among themselves only by an exponent q). - -- d50 is a recently developed immune diversity estimate. It calculates the minimum number of distinct clonotypes +\item d50 is a recently developed immune diversity estimate. It calculates the minimum number of distinct clonotypes amounting to greater than or equal to 50 percent of a total of sequencing reads obtained following amplification and sequencing - -- dXX is a similar to d50 index where XX corresponds to desirable percent of total sequencing reads. +\item dXX is a similar to d50 index where XX corresponds to desirable percent of total sequencing reads. +} } \examples{ data(immdata) diff --git a/man/repExplore.Rd b/man/repExplore.Rd index 681a45ff..95d64565 100644 --- a/man/repExplore.Rd +++ b/man/repExplore.Rd @@ -13,7 +13,7 @@ repExplore( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -51,6 +51,8 @@ with exploratory analysis statistics. Otherwise, it returns a numeric matrix with exploratory analysis statistics for all input repertoires. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + The \code{repExplore} function calculates the basic statistics of repertoire: the number of unique immune receptor clonotypes, their relative abundances, and sequence length distribution across the input dataset. diff --git a/man/repFilter.Rd b/man/repFilter.Rd index aa54c7b3..461e945a 100644 --- a/man/repFilter.Rd +++ b/man/repFilter.Rd @@ -27,35 +27,39 @@ Default value: 'by.clonotype'.} \item{.query}{Filtering query. It's a named list of filters that will be applied to data. Possible values for names in this list are dependent on filter methods: -- by.meta: filters by metadata. Names in the named list are metadata column headers. -- by.repertoire: filters by the number of clonotypes or total number of clones in sample. +\itemize{ +\item by.meta: filters by metadata. Names in the named list are metadata column headers. +\item by.repertoire: filters by the number of clonotypes or total number of clones in sample. Possible names in the named list are "n_clonotypes" and "n_clones". -- by.clonotype: filters by data in all samples. Names in the named list are +\item by.clonotype: filters by data in all samples. Names in the named list are data column headers. Elements of the named list for each of the filters are filtering options. Possible values for filtering options: -- include("STR1", "STR2", ...): keeps only rows with matching values. +\item include("STR1", "STR2", ...): keeps only rows with matching values. Available for methods: "by.meta", "by.clonotype". -- exclude("STR1", "STR2", ...): removes rows with matching values. +\item exclude("STR1", "STR2", ...): removes rows with matching values. Available for methods: "by.meta", "by.clonotype". -- lessthan(value): keeps rows/samples with numeric values less than specified. +\item lessthan(value): keeps rows/samples with numeric values less than specified. Available for methods: "by.meta", "by.repertoire", "by.clonotype". -- morethan(value): keeps rows/samples with numeric values more than specified. +\item morethan(value): keeps rows/samples with numeric values more than specified. Available for methods: "by.meta", "by.repertoire", "by.clonotype". -- interval(from, to): keeps rows/samples with numeric values that fits in this interval. +\item interval(from, to): keeps rows/samples with numeric values that fits in this interval. from is inclusive, to is exclusive. Available for methods: "by.meta", "by.repertoire", "by.clonotype". -Default value: 'list(CDR3.aa = exclude("partial", "out_of_frame"))'.} +Default value: 'list(CDR3.aa = exclude("partial", "out_of_frame"))'. +}} \item{.match}{Matching method for "include" and "exclude" options in query. Possible values: -- exact: matches only the exact specified string; -- startswith: matches all strings starting with the specified substring; -- substring: matches all strings containing the specified substring. -Default value: 'exact'.} +\itemize{ +\item exact: matches only the exact specified string; +\item startswith: matches all strings starting with the specified substring; +\item substring: matches all strings containing the specified substring. +Default value: 'exact'. +}} } \description{ -Main function for data filtering +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/repGermline.Rd b/man/repGermline.Rd index 529a12be..b1d129eb 100644 --- a/man/repGermline.Rd +++ b/man/repGermline.Rd @@ -7,7 +7,7 @@ repGermline(.data, .species, .min_nuc_outside_cdr3, .threads) } \arguments{ -\item{.data}{The data to be processed. Can be \link{data.frame}, [data.table::data.table] +\item{.data}{The data to be processed. Can be \link{data.frame}, \link[data.table:data.table]{data.table::data.table} or a list of these objects. It must have columns in the immunarch compatible format \link{immunarch_data_format}.} @@ -26,12 +26,16 @@ outside of CDR3 to be considered good for further alignment.} } \value{ Data with added columns: -* Sequence (FR1+CDR1+FR2+CDR2+FR3+CDR3+FR4 in nucleotides; the column will be replaced if exists) -* V.allele, J.allele (chosen alleles of V and J genes), -* V.aa, J.aa (V and J sequences from original clonotype, outside CDR3, converted to amino acids) -* Germline.sequence (combined germline nucleotide sequence) +\itemize{ +\item Sequence (FR1+CDR1+FR2+CDR2+FR3+CDR3+FR4 in nucleotides; the column will be replaced if exists) +\item V.allele, J.allele (chosen alleles of V and J genes), +\item V.aa, J.aa (V and J sequences from original clonotype, outside CDR3, converted to amino acids) +\item Germline.sequence (combined germline nucleotide sequence) +} } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + This function creates germlines for clonal lineages. B cell clonal lineage represents a set of B cells that presumably have a common origin (arising from the same VDJ rearrangement event) and a common ancestor. Each clonal lineage has its own germline sequence diff --git a/man/repLoad.Rd b/man/repLoad.Rd index 6d9eeaf8..cf25b39a 100644 --- a/man/repLoad.Rd +++ b/man/repLoad.Rd @@ -9,14 +9,12 @@ repLoad(.path, .mode = "paired", .coding = TRUE, ...) \arguments{ \item{.path}{A character string specifying the path to the input data. Input data can be one of the following: - -- a single repertoire file. +\itemize{ +\item a single repertoire file. In this case \code{repLoad} returns an R \link{data.frame}; - -- a vector of paths to repertoire files. +\item a vector of paths to repertoire files. Same as in the case with no metadata file presented in the next section below; - -- a path to the folder with repertoire files and, if available, metadata file "metadata.txt". +\item a path to the folder with repertoire files and, if available, metadata file "metadata.txt". If the metadata file if presented, then the \code{repLoad} returns a list with two elements "data" and "meta". "data" is an another list with repertoire R \link{data.frame}s. "meta" is a data frame with the metadata. If the metadata file "metadata.txt" is not presented, then the \code{repLoad} creates a dummy metadata file with @@ -24,7 +22,8 @@ sample names and returns a list with two elements "data" and "meta". If input data has multiple chains or cell types stored in the same file (for example, like in 10xGenomics repertoire files), such repertoire files will be splitted to different R data frames with only one type of chain and cell presented. The metadata file will have additional columns specifying -cell and chain types for different samples.} +cell and chain types for different samples. +}} \item{.mode}{Either "single" for single chain data or "paired" for paired chain data. @@ -38,12 +37,14 @@ By default, 10X Genomics data will be loaded as paired chain data, and other fil } \value{ A list with two named elements: - - - "data" is a list of input samples; - - - "meta" is a data frame with sample metadata. +\itemize{ +\item "data" is a list of input samples; +\item "meta" is a data frame with sample metadata. +} } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + The \code{repLoad} function loads repertoire files into R workspace in the immunarch format where you can immediately use them for the analysis. \code{repLoad} automatically detects the right format for @@ -58,35 +59,26 @@ It can have any number of additional columns with arbitrary names. The first column should contain base names of files without extensions in your folder. Example: \tabular{llll}{ - Sample \tab Sex \tab Age \tab Status\cr - immunoseq_1 \tab M \tab 1 \tab C\cr - immunoseq_2 \tab M \tab 2 \tab C\cr - immunoseq_3 \tab FALSE \tab 3 \tab A +Sample \tab Sex \tab Age \tab Status\cr +immunoseq_1 \tab M \tab 1 \tab C\cr +immunoseq_2 \tab M \tab 2 \tab C\cr +immunoseq_3 \tab FALSE \tab 3 \tab A } Currently, Immunarch support the following formats: - -- "immunoseq" - ImmunoSEQ of any version. http://www.adaptivebiotech.com/immunoseq - -- "mitcr" - MiTCR. https://github.com/milaboratory/mitcr - -- "mixcr" - MiXCR (the "all" files) of any version. https://github.com/milaboratory/mixcr - -- "migec" - MiGEC. http://migec.readthedocs.io/en/latest/ - -- "migmap" - For parsing IgBLAST results postprocessed with MigMap. https://github.com/mikessh/migmap - -- "tcr" - tcR, our previous package. https://imminfo.github.io/tcr/ - -- "vdjtools" - VDJtools of any version. http://vdjtools-doc.readthedocs.io/en/latest/ - -- "imgt" - IMGT HighV-QUEST. http://www.imgt.org/HighV-QUEST/ - -- "airr" - adaptive immune receptor repertoire (AIRR) data format. http://docs.airr-community.org/en/latest/datarep/overview.html - -- "10x" - 10XGenomics clonotype annotations tables. https://support.10xgenomics.com/single-cell-vdj/software/pipelines/latest/output/annotation - -- "archer" - ArcherDX clonotype tables. https://archerdx.com/ +\itemize{ +\item "immunoseq" - ImmunoSEQ of any version. http://www.adaptivebiotech.com/immunoseq +\item "mitcr" - MiTCR. https://github.com/milaboratory/mitcr +\item "mixcr" - MiXCR (the "all" files) of any version. https://github.com/milaboratory/mixcr +\item "migec" - MiGEC. http://migec.readthedocs.io/en/latest/ +\item "migmap" - For parsing IgBLAST results postprocessed with MigMap. https://github.com/mikessh/migmap +\item "tcr" - tcR, our previous package. https://imminfo.github.io/tcr/ +\item "vdjtools" - VDJtools of any version. http://vdjtools-doc.readthedocs.io/en/latest/ +\item "imgt" - IMGT HighV-QUEST. http://www.imgt.org/HighV-QUEST/ +\item "airr" - adaptive immune receptor repertoire (AIRR) data format. http://docs.airr-community.org/en/latest/datarep/overview.html +\item "10x" - 10XGenomics clonotype annotations tables. https://support.10xgenomics.com/single-cell-vdj/software/pipelines/latest/output/annotation +\item "archer" - ArcherDX clonotype tables. https://archerdx.com/ +} } \examples{ # To load the data from a single file (note that you don't need to specify the data format): diff --git a/man/repOverlap.Rd b/man/repOverlap.Rd index bed5ae5d..e173c351 100644 --- a/man/repOverlap.Rd +++ b/man/repOverlap.Rd @@ -22,7 +22,7 @@ repOverlap( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -75,6 +75,8 @@ If only two repertoires were provided, return value is single numeric value. If one of the incremental method is chosen, return list of overlap matrix. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + The \code{repOverlap} function is designed to analyse the overlap between two or more repertoires. It contains a number of methods to compare immune receptor sequences that are shared between individuals. diff --git a/man/repOverlapAnalysis.Rd b/man/repOverlapAnalysis.Rd index 40db2ad8..096765e6 100644 --- a/man/repOverlapAnalysis.Rd +++ b/man/repOverlapAnalysis.Rd @@ -17,7 +17,7 @@ repOverlapAnalysis( } \arguments{ \item{.data}{Any distance matrix between pairs of repertoires. You can also pass your -output from \code{\link{repOverlap}}.} +output from \code{\link[=repOverlap]{repOverlap()}}.} \item{.method}{A string that defines the type of analysis to perform.} @@ -25,26 +25,28 @@ output from \code{\link{repOverlap}}.} \item{.raw}{A logical value. Set TRUE if you want to receive raw output of clustering or dimensionality reduction function of choice. Set FALSE if you want to receive -processed output that can be subjected to visualisation with \code{\link{vis}} function.} +processed output that can be subjected to visualisation with \code{\link[=vis]{vis()}} function.} -\item{.perp}{A numerical value, t-SNE parameter, see \code{\link{immunr_tsne}}.} +\item{.perp}{A numerical value, t-SNE parameter, see \code{\link[=immunr_tsne]{immunr_tsne()}}.} -\item{.theta}{A numerical value, t-SNE parameter, see \code{\link{immunr_tsne}}.} +\item{.theta}{A numerical value, t-SNE parameter, see \code{\link[=immunr_tsne]{immunr_tsne()}}.} -\item{.eps}{A numerical value, DBscan epsylon parameter, see \code{\link{immunr_dbscan}}.} +\item{.eps}{A numerical value, DBscan epsylon parameter, see \code{\link[=immunr_dbscan]{immunr_dbscan()}}.} -\item{.k}{The number of clusters to create, passed as \code{k} to \link[factoextra]{hcut} or as \code{centers} to \link{kmeans}.} +\item{.k}{The number of clusters to create, passed as \code{k} to \link[factoextra:hcut]{hcut} or as \code{centers} to \link{kmeans}.} } \value{ Depends on the last element in the \code{.method} string. See \link{immunr_tsne} for more info. } \description{ -The \code{\link{repOverlapAnalysis}} function contains advanced data +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + +The \code{\link[=repOverlapAnalysis]{repOverlapAnalysis()}} function contains advanced data analysis methods. You can use several clustering and dimensionality reduction techniques in order to investigate further the difference between repertoires provided. -To cluster a subset of similar data with \code{\link{repOverlapAnalysis}} you can +To cluster a subset of similar data with \code{\link[=repOverlapAnalysis]{repOverlapAnalysis()}} you can perform hierarchical clustering, k-means or dbscan ('hclust', 'kmeans', 'dbscan' respectively). diff --git a/man/repSample.Rd b/man/repSample.Rd index c607814d..673fa89e 100644 --- a/man/repSample.Rd +++ b/man/repSample.Rd @@ -13,7 +13,7 @@ repSample( } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} diff --git a/man/repSave.Rd b/man/repSave.Rd index 539fb9c4..c6052fb6 100644 --- a/man/repSave.Rd +++ b/man/repSave.Rd @@ -23,6 +23,8 @@ name if a single dataframe is provided to .data argument.} No return value. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + The \code{repSave} function is deigned to save your data to the disk in desirable format. Currently supports "immunarch" and "vdjtools" file formats. } diff --git a/man/repSomaticHypermutation.Rd b/man/repSomaticHypermutation.Rd index e6d8e767..e4e9bd11 100644 --- a/man/repSomaticHypermutation.Rd +++ b/man/repSomaticHypermutation.Rd @@ -21,16 +21,20 @@ The dataframe has all the columns from repClonalFamily() output dataframe, with column unnested: the resulting dataframe has one line per clonotype. Clone.ID column contains original IDs for clonotypes, and can be used as dataframe key. New columns are added: -* Germline.Alignment.V: contains V gene alignment of current clonotype with the germline -* Germline.Alignment.J: contains J gene alignment of current clonotype with the germline -* Substitutions: contains number of substitutions in the alignment (summary for V and J) -* Insertions: contains number of insertions in the clonotype relative to germline - (summary for V and J) -* Deletions: contains number of deletions in the clonotype relative to germline - (summary for V and J) -* Mutations: contains total number of mutations in the alignment (summary for V and J) +\itemize{ +\item Germline.Alignment.V: contains V gene alignment of current clonotype with the germline +\item Germline.Alignment.J: contains J gene alignment of current clonotype with the germline +\item Substitutions: contains number of substitutions in the alignment (summary for V and J) +\item Insertions: contains number of insertions in the clonotype relative to germline +(summary for V and J) +\item Deletions: contains number of deletions in the clonotype relative to germline +(summary for V and J) +\item Mutations: contains total number of mutations in the alignment (summary for V and J) +} } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + This function aligns V and J genes from the germline in each cluster with corresponding genes in each clonotype, saves the alignments for purpose of visualization, and calculates number of mutations for each clonotype. diff --git a/man/scdata.Rd b/man/scdata.Rd index 14d06d90..56bb170e 100644 --- a/man/scdata.Rd +++ b/man/scdata.Rd @@ -11,9 +11,9 @@ A list of four elements: "bc_patients" is a list of barcodes corresponding to specific patients. "bc_clusters" is a list of barcodes corresponding to specific cell clusters. \describe{ - \item{data}{List of immune repertoire data frames.} - \item{meta}{Metadata} - ... +\item{data}{List of immune repertoire data frames.} +\item{meta}{Metadata} +... } } \usage{ diff --git a/man/select_barcodes.Rd b/man/select_barcodes.Rd index 07bfdb1c..500dd115 100644 --- a/man/select_barcodes.Rd +++ b/man/select_barcodes.Rd @@ -8,7 +8,7 @@ select_barcodes(.data, .barcodes, .force.list = FALSE) } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -31,6 +31,8 @@ with clonotype barcodes corresponding to the input barcodes. The output list nam in the ".barcode" argument (Seurat::Idents() case only). } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Subsets the input immune repertoire by barcodes. Creates a vector of barcodes to subset or a vector cluster IDs and corresponding barcodes to get a list of immune repertoires corresponding to cluster IDs. diff --git a/man/select_clusters.Rd b/man/select_clusters.Rd index bbae94a7..d018c477 100644 --- a/man/select_clusters.Rd +++ b/man/select_clusters.Rd @@ -21,6 +21,8 @@ A list with two elements "data" and "meta" with updated immune repertoire tables metadata. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Given the vector of barcodes from Seurat, splits the input repertoires to separate subsets following the barcodes' assigned IDs. Useful in case you want to split immune repertoires by patients or clusters. diff --git a/man/seqCluster.Rd b/man/seqCluster.Rd index 53348193..f6a6a24a 100644 --- a/man/seqCluster.Rd +++ b/man/seqCluster.Rd @@ -8,7 +8,7 @@ seqCluster(.data, .dist, .perc_similarity, .nt_similarity, .fixed_threshold) } \arguments{ \item{.data}{The data which was used to caluculate .dist object. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format \link{immunarch_data_format}} @@ -26,14 +26,17 @@ the threshold of allowing a 1 in n nucleotides mismatch in sequencies.} Immdata data format object. Same as .data, but with extra 'Cluster' column with clusters assigned. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Graph clustering based on distances between sequences } \examples{ - +\dontrun{ data(immdata) # In this example, we will use only 2 samples with 500 clonotypes in each for time saving input_data <- lapply(immdata$data[1:2], head, 500) dist_result <- seqDist(input_data) cluster_result <- seqCluster(input_data, dist_result, .fixed_threshold = 1) } +} \concept{seq_cluster} diff --git a/man/seqDist.Rd b/man/seqDist.Rd index 6d6aae8d..76c8523e 100644 --- a/man/seqDist.Rd +++ b/man/seqDist.Rd @@ -9,7 +9,7 @@ seqDist(.data, .col = 'CDR3.nt', .method = 'hamming', } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format \link{immunarch_data_format}} @@ -40,6 +40,8 @@ In case of user-defined function, it should take x and y parameters as input and Named list of list with \link{dist} objects for given repertoires for each combination of .group_by variable(s) and/or sequence length of .col. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Computing sequential distances between clonotypes from two repertoires: } \examples{ @@ -47,7 +49,7 @@ Computing sequential distances between clonotypes from two repertoires: data(immdata) # Reducing data to save time on examples immdata$data <- purrr::map(immdata$data, ~ .x \%>\% head(10)) -# Computing hamming distance for the first two repertoires in \code{'immdata'} +# Computing hamming distance for the first two repertoires in `'immdata'` seqDist(immdata$data[1:2]) # Here we define a custom distance function diff --git a/man/spectratype.Rd b/man/spectratype.Rd index f099b0ba..fa7e3ecd 100644 --- a/man/spectratype.Rd +++ b/man/spectratype.Rd @@ -8,7 +8,7 @@ spectratype(.data, .quant = c("id", "count"), .col = "nt") } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -33,7 +33,7 @@ Clonal counts of equal clonotypes will be summed up.} Data frame with distributions of clonotypes per CDR3 length. } \description{ -Immune repertoire spectratyping +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ # Load the data diff --git a/man/split_to_kmers.Rd b/man/split_to_kmers.Rd index c456ce7b..02702dca 100644 --- a/man/split_to_kmers.Rd +++ b/man/split_to_kmers.Rd @@ -34,7 +34,7 @@ For more information see https://en.wikipedia.org/wiki/Position_weight_matrix.} \code{kmer_profile} - a matrix with per-position amino acid statistics. } \description{ -Analysis immune repertoire kmer statistics: sequence profiles, etc. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/top.Rd b/man/top.Rd index 2acc8014..54ca1083 100644 --- a/man/top.Rd +++ b/man/top.Rd @@ -7,8 +7,8 @@ top(.data, .n = 10) } \arguments{ -\item{.data}{The data to be processed. Can be [data.frame], -[data.table::data.table], or a list of these objects. +\item{.data}{The data to be processed. Can be \link{data.frame}, +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -22,7 +22,7 @@ Note: each connection must represent a separate repertoire.} \item{.n}{Numeric. Number of the most abundant clonotypes to return.} } \value{ -Data frame with the `.n` most abundant clonotypes only. +Data frame with the \code{.n} most abundant clonotypes only. } \description{ Get the N most abundant clonotypes diff --git a/man/trackClonotypes.Rd b/man/trackClonotypes.Rd index 45211505..a259b176 100644 --- a/man/trackClonotypes.Rd +++ b/man/trackClonotypes.Rd @@ -8,7 +8,7 @@ trackClonotypes(.data, .which = list(1, 15), .col = "aa", .norm = TRUE) } \arguments{ \item{.data}{The data to process. It can be a \link{data.frame}, a -[data.table::data.table], or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} @@ -20,13 +20,12 @@ of these objects. They are supported with the same limitations as basic objects. Note: each connection must represent a separate repertoire.} \item{.which}{An argument that regulates which clonotypes to choose for tracking. There are three options for this argument: - -1) passes a list with two elements \code{list(X, Y)}, where \code{X} is the name or the index of a target repertoire from ".data", and +\enumerate{ +\item passes a list with two elements \code{list(X, Y)}, where \code{X} is the name or the index of a target repertoire from ".data", and \code{Y} is the number of the most abundant clonotypes to take from \code{X}. - -2) passes a character vector of sequences to take from all data frames; - -3) passes a data frame (data table, database) with one or more columns - first for sequences, and other for gene segments (if applicable). +\item passes a character vector of sequences to take from all data frames; +\item passes a data frame (data table, database) with one or more columns - first for sequences, and other for gene segments (if applicable). +} See the "Examples" below with examples for each option.} @@ -43,6 +42,8 @@ in the function output.} Data frame with input sequences and counts or proportions for each of the input repertoire. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Tracks the temporal dynamics of clonotypes in repertoires. For example, tracking across multiple time points after vaccination. diff --git a/man/vis.Rd b/man/vis.Rd index a1f6a824..418b9805 100644 --- a/man/vis.Rd +++ b/man/vis.Rd @@ -26,54 +26,50 @@ See "Details" for the list of available visualisations. List of available visualisations for different kinds of data. Basic analysis: - -- Exploratory analysis results (from \link{repExplore}) - see \link{vis.immunr_exp_vol}; - -- Clonality statistics (from \link{repClonality}) - see \link{vis.immunr_homeo}. +\itemize{ +\item Exploratory analysis results (from \link{repExplore}) - see \link{vis.immunr_exp_vol}; +\item Clonality statistics (from \link{repClonality}) - see \link{vis.immunr_homeo}. +} Overlaps and public clonotypes: - -- Overlaps (from \link{repOverlap}) using heatmaps, circos plots, polar area plots - see \link{vis.immunr_ov_matrix}; - -- Overlap clustering (from \link{repOverlapAnalysis}) - see \link{vis.immunr_hclust}; - -- Repertoire incremental overlaps (from \link{repOverlap}) - see \link{vis.immunr_inc_overlap}; - -- Public repertoire abundance (from \link{pubRep}) - vis \link{vis.immunr_public_repertoire}. +\itemize{ +\item Overlaps (from \link{repOverlap}) using heatmaps, circos plots, polar area plots - see \link{vis.immunr_ov_matrix}; +\item Overlap clustering (from \link{repOverlapAnalysis}) - see \link{vis.immunr_hclust}; +\item Repertoire incremental overlaps (from \link{repOverlap}) - see \link{vis.immunr_inc_overlap}; +\item Public repertoire abundance (from \link{pubRep}) - vis \link{vis.immunr_public_repertoire}. +} Gene usage: - -- Gene usage statistics (from \link{geneUsage}) using bar plots, box plots - see \link{vis.immunr_gene_usage}; - -- Gene usage distances (from \link{geneUsageAnalysis}) using heatmaps, circos plots, polar area plots - see \link{vis.immunr_ov_matrix}; - -- Gene usage clustering (from \link{geneUsageAnalysis}) - see \link{vis.immunr_hclust}. +\itemize{ +\item Gene usage statistics (from \link{geneUsage}) using bar plots, box plots - see \link{vis.immunr_gene_usage}; +\item Gene usage distances (from \link{geneUsageAnalysis}) using heatmaps, circos plots, polar area plots - see \link{vis.immunr_ov_matrix}; +\item Gene usage clustering (from \link{geneUsageAnalysis}) - see \link{vis.immunr_hclust}. +} Diversity estimation: - -- Diversity estimations (from \link{repDiversity}) - see \link{vis.immunr_chao1}. +\itemize{ +\item Diversity estimations (from \link{repDiversity}) - see \link{vis.immunr_chao1}. +} BCR analysis: - -- Clonal tree (from \link{repClonalFamily}) - see \link{vis.clonal_family} and \link{vis.clonal_family_tree}. +\itemize{ +\item Clonal tree (from \link{repClonalFamily}) - see \link{vis.clonal_family} and \link{vis.clonal_family_tree}. +} Advanced analysis: - -- Repertoire dynamics (from \link{trackClonotypes}) - see \link{vis.immunr_dynamics}; - -- Sequence logo plots of amino acid distributions (from \link{kmer_profile}) - see \link{vis_seqlogo}; - -- Kmers distributions (from \link{getKmers}) - see \link{vis.immunr_kmer_table}; - -- Mutation networks (from mutationNetwork) - Work In Progress on vis.immunr_mutation_network; - -- CDR3 amino acid properties, e.g., biophysical (from cdrProp) - Work In Progress on vis.immunr_cdr_prop. +\itemize{ +\item Repertoire dynamics (from \link{trackClonotypes}) - see \link{vis.immunr_dynamics}; +\item Sequence logo plots of amino acid distributions (from \link{kmer_profile}) - see \link{vis_seqlogo}; +\item Kmers distributions (from \link{getKmers}) - see \link{vis.immunr_kmer_table}; +\item Mutation networks (from mutationNetwork) - Work In Progress on vis.immunr_mutation_network; +\item CDR3 amino acid properties, e.g., biophysical (from cdrProp) - Work In Progress on vis.immunr_cdr_prop. +} Additionaly, we provide a wrapper functions for visualisations of common data types: - -- Any data frames or matrices using heatmaps - see \link{vis_heatmap} and \link{vis_heatmap2}; - -- Any data frames or matrices using circos plots - see \link{vis_circos}. +\itemize{ +\item Any data frames or matrices using heatmaps - see \link{vis_heatmap} and \link{vis_heatmap2}; +\item Any data frames or matrices using circos plots - see \link{vis_circos}. +} } \examples{ # Load the test data diff --git a/man/vis.clonal_family.Rd b/man/vis.clonal_family.Rd index 46023f18..1a9045f0 100644 --- a/man/vis.clonal_family.Rd +++ b/man/vis.clonal_family.Rd @@ -7,7 +7,7 @@ \method{vis}{clonal_family}(.data, ...) } \arguments{ -\item{.data}{Clonal families from 1 or multiple samples: \code{\link{repClonalFamily}} output.} +\item{.data}{Clonal families from 1 or multiple samples: \code{\link[=repClonalFamily]{repClonalFamily()}} output.} \item{...}{Not used here.} } diff --git a/man/vis.clonal_family_tree.Rd b/man/vis.clonal_family_tree.Rd index 78d515e2..50048c34 100644 --- a/man/vis.clonal_family_tree.Rd +++ b/man/vis.clonal_family_tree.Rd @@ -7,7 +7,7 @@ \method{vis}{clonal_family_tree}(.data, ...) } \arguments{ -\item{.data}{Single clonal family tree data from 1 cluster: 1 element from TreeStats column from \code{\link{repClonalFamily}} output.} +\item{.data}{Single clonal family tree data from 1 cluster: 1 element from TreeStats column from \code{\link[=repClonalFamily]{repClonalFamily()}} output.} \item{...}{Not used here.} } diff --git a/man/vis.immunr_chao1.Rd b/man/vis.immunr_chao1.Rd index 5155da64..efb9f105 100644 --- a/man/vis.immunr_chao1.Rd +++ b/man/vis.immunr_chao1.Rd @@ -23,7 +23,7 @@ ) } \arguments{ -\item{.data}{Output from \code{\link{repDiversity}}.} +\item{.data}{Output from \code{\link[=repDiversity]{repDiversity()}}.} \item{.by}{Pass NA if you want to plot samples without grouping. @@ -56,16 +56,16 @@ Disabled if no group passed to the ".by" argument.} A ggplot2 object. } \description{ -An utility function to visualise the output from \code{\link{repDiversity}}. +An utility function to visualise the output from \code{\link[=repDiversity]{repDiversity()}}. } \details{ If data is grouped, then statistical tests for comparing means of groups will be performed, unless \code{.test = FALSE} is supplied. In case there are only two groups, the Wilcoxon rank sum test (https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) is performed -(R function \code{\link{wilcox.test}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. -In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link{kruskal.test}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. +(R function \code{\link[=wilcox.test]{wilcox.test()}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. +In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal\%E2\%80\%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link[=kruskal.test]{kruskal.test()}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. A significant Kruskal-Wallis test indicates that at least one sample stochastically dominates one other sample. Adjusted for multiple comparisons P-values are plotted on the top of groups. -P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm%E2%80%93Bonferroni_method) (also known as Holm-Bonferroni correction). +P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm\%E2\%80\%93Bonferroni_method) (also known as Holm-Bonferroni correction). You can execute the command \code{?p.adjust} in the R console to see more. } \examples{ diff --git a/man/vis.immunr_clonal_prop.Rd b/man/vis.immunr_clonal_prop.Rd index 122ed6c2..99c2def4 100644 --- a/man/vis.immunr_clonal_prop.Rd +++ b/man/vis.immunr_clonal_prop.Rd @@ -20,7 +20,7 @@ ) } \arguments{ -\item{.data}{Output from \code{\link{repClonality}}.} +\item{.data}{Output from \code{\link[=repClonality]{repClonality()}}.} \item{.by}{Pass NA if you want to plot samples without grouping. @@ -53,16 +53,16 @@ Disabled if no group passed to the ".by" argument.} A ggplot2 object. } \description{ -An utility function to visualise the output from \code{\link{repClonality}}. +An utility function to visualise the output from \code{\link[=repClonality]{repClonality()}}. } \details{ If data is grouped, then statistical tests for comparing means of groups will be performed, unless \code{.test = FALSE} is supplied. In case there are only two groups, the Wilcoxon rank sum test (https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) is performed -(R function \code{\link{wilcox.test}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. -In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link{kruskal.test}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. +(R function \code{\link[=wilcox.test]{wilcox.test()}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. +In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal\%E2\%80\%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link[=kruskal.test]{kruskal.test()}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. A significant Kruskal-Wallis test indicates that at least one sample stochastically dominates one other sample. Adjusted for multiple comparisons P-values are plotted on the top of groups. -P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm%E2%80%93Bonferroni_method) (also known as Holm-Bonferroni correction). +P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm\%E2\%80\%93Bonferroni_method) (also known as Holm-Bonferroni correction). You can execute the command \code{?p.adjust} in the R console to see more. } \examples{ diff --git a/man/vis.immunr_exp_vol.Rd b/man/vis.immunr_exp_vol.Rd index 44b4b941..e293d429 100644 --- a/man/vis.immunr_exp_vol.Rd +++ b/man/vis.immunr_exp_vol.Rd @@ -20,7 +20,7 @@ ) } \arguments{ -\item{.data}{Output from \code{\link{repExplore}}.} +\item{.data}{Output from \code{\link[=repExplore]{repExplore()}}.} \item{.by}{Pass NA if you want to plot samples without grouping. @@ -53,16 +53,16 @@ Disabled if no group passed to the ".by" argument.} A ggplot2 object. } \description{ -An utility function to visualise the output from \code{\link{repExplore}}. +An utility function to visualise the output from \code{\link[=repExplore]{repExplore()}}. } \details{ If data is grouped, then statistical tests for comparing means of groups will be performed, unless \code{.test = FALSE} is supplied. In case there are only two groups, the Wilcoxon rank sum test (https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) is performed -(R function \code{\link{wilcox.test}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. -In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link{kruskal.test}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. +(R function \code{\link[=wilcox.test]{wilcox.test()}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. +In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal\%E2\%80\%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link[=kruskal.test]{kruskal.test()}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. A significant Kruskal-Wallis test indicates that at least one sample stochastically dominates one other sample. Adjusted for multiple comparisons P-values are plotted on the top of groups. -P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm%E2%80%93Bonferroni_method) (also known as Holm-Bonferroni correction). +P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm\%E2\%80\%93Bonferroni_method) (also known as Holm-Bonferroni correction). You can execute the command \code{?p.adjust} in the R console to see more. } \examples{ diff --git a/man/vis.immunr_gene_usage.Rd b/man/vis.immunr_gene_usage.Rd index f2d36902..b66c92a2 100644 --- a/man/vis.immunr_gene_usage.Rd +++ b/man/vis.immunr_gene_usage.Rd @@ -10,26 +10,21 @@ \item{.data}{Output from the \link{geneUsage} function.} \item{.plot}{String specifying the plot type: - -- "hist" for histograms using \link{vis_hist}; - -- "heatmap" for heatmaps using \link{vis_heatmap}; - -- "heatmap2" for heatmaps using \link{vis_heatmap2}; - -- "circos" for circos plots using \link{vis_circos}.} +\itemize{ +\item "hist" for histograms using \link{vis_hist}; +\item "heatmap" for heatmaps using \link{vis_heatmap}; +\item "heatmap2" for heatmaps using \link{vis_heatmap2}; +\item "circos" for circos plots using \link{vis_circos}. +}} \item{...}{Other arguments passed to corresponding functions depending on the plot type: - -- "hist" - passes arguments to \link{vis_hist}; - -- "box" - passes arguments to \link{vis_box}; - -- "heatmap" - passes arguments to \link{vis_heatmap}; - -- "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; - -- "circos" - passes arguments to \link{vis_circos} and [circlize::chordDiagram] from the "circlize" package.} +\itemize{ +\item "hist" - passes arguments to \link{vis_hist}; +\item "box" - passes arguments to \link{vis_box}; +\item "heatmap" - passes arguments to \link{vis_heatmap}; +\item "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; +\item "circos" - passes arguments to \link{vis_circos} and \link[circlize:chordDiagram]{circlize::chordDiagram} from the "circlize" package. +}} } \value{ A ggplot2 object, pheatmap or circlize object. diff --git a/man/vis.immunr_hclust.Rd b/man/vis.immunr_hclust.Rd index 0ffa7a6b..f0afb565 100644 --- a/man/vis.immunr_hclust.Rd +++ b/man/vis.immunr_hclust.Rd @@ -9,7 +9,7 @@ \arguments{ \item{.data}{Clustering results from \link{repOverlapAnalysis} or \link{geneUsageAnalysis}.} -\item{.rect}{Passed to [factoextra::fviz_dend] - whether to add a rectangle around groups.} +\item{.rect}{Passed to \link[factoextra:fviz_dend]{factoextra::fviz_dend} - whether to add a rectangle around groups.} \item{.plot}{A character vector of length one or two specifying which plots to visualise. If "clust" then plot only the clustering. If "best" then plot the number of optimal clusters. diff --git a/man/vis.immunr_kmeans.Rd b/man/vis.immunr_kmeans.Rd index 38a444ff..8b126de2 100644 --- a/man/vis.immunr_kmeans.Rd +++ b/man/vis.immunr_kmeans.Rd @@ -19,15 +19,15 @@ \arguments{ \item{.data}{Clustering results from \link{repOverlapAnalysis} or \link{geneUsageAnalysis}.} -\item{.point}{If TRUE then plot sample points. Passed to [factoextra::fviz_cluster].} +\item{.point}{If TRUE then plot sample points. Passed to \link[factoextra:fviz_cluster]{factoextra::fviz_cluster}.} -\item{.text}{If TRUE then plot text labels. Passed to [factoextra::fviz_cluster].} +\item{.text}{If TRUE then plot text labels. Passed to \link[factoextra:fviz_cluster]{factoextra::fviz_cluster}.} -\item{.ellipse}{If TRUE then plot ellipses around all samples. Passed to "ellipse" from [factoextra::fviz_cluster].} +\item{.ellipse}{If TRUE then plot ellipses around all samples. Passed to "ellipse" from \link[factoextra:fviz_cluster]{factoextra::fviz_cluster}.} -\item{.point.size}{Size of points, passed to "pointsize" from [factoextra::fviz_cluster].} +\item{.point.size}{Size of points, passed to "pointsize" from \link[factoextra:fviz_cluster]{factoextra::fviz_cluster}.} -\item{.text.size}{Size of text labels, passed to labelsize from [factoextra::fviz_cluster].} +\item{.text.size}{Size of text labels, passed to labelsize from \link[factoextra:fviz_cluster]{factoextra::fviz_cluster}.} \item{.plot}{A character vector of length one or two specifying which plots to visualise. If "clust" then plot only the clustering. If "best" then plot the number of optimal clusters. diff --git a/man/vis.immunr_mds.Rd b/man/vis.immunr_mds.Rd index b84a2126..ba9de7f6 100644 --- a/man/vis.immunr_mds.Rd +++ b/man/vis.immunr_mds.Rd @@ -55,12 +55,11 @@ PCA / MDS / tSNE visualisation (mainly overlap / gene usage) } \details{ Other visualisation methods: - -- PCA - \link{vis.immunr_pca} - -- MDS - \link{vis.immunr_mds} - -- tSNE - \link{vis.immunr_tsne} +\itemize{ +\item PCA - \link{vis.immunr_pca} +\item MDS - \link{vis.immunr_mds} +\item tSNE - \link{vis.immunr_tsne} +} } \examples{ data(immdata) diff --git a/man/vis.immunr_ov_matrix.Rd b/man/vis.immunr_ov_matrix.Rd index c4835776..55b705ea 100644 --- a/man/vis.immunr_ov_matrix.Rd +++ b/man/vis.immunr_ov_matrix.Rd @@ -11,20 +11,18 @@ \item{.data}{Output from \link{repOverlap} or \link{geneUsageAnalysis}.} \item{.plot}{A string specifying the plot type: - -- "heatmap" for heatmaps using \link{vis_heatmap}; - -- "heatmap2" for heatmaps using \link{vis_heatmap2}; - -- "circos" for circos plots using \link{vis_circos};} +\itemize{ +\item "heatmap" for heatmaps using \link{vis_heatmap}; +\item "heatmap2" for heatmaps using \link{vis_heatmap2}; +\item "circos" for circos plots using \link{vis_circos}; +}} \item{...}{Other arguments are passed through to the underlying plotting function: - -- "heatmap" - passes arguments to \link{vis_heatmap}; - -- "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; - -- "circos" - passes arguments to \link{vis_circos} and [circlize::chordDiagram] from the "circlize" package;} +\itemize{ +\item "heatmap" - passes arguments to \link{vis_heatmap}; +\item "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; +\item "circos" - passes arguments to \link{vis_circos} and \link[circlize:chordDiagram]{circlize::chordDiagram} from the "circlize" package; +}} } \value{ A ggplot2, pheatmap or circlize object. diff --git a/man/vis.immunr_public_repertoire.Rd b/man/vis.immunr_public_repertoire.Rd index d9c4a599..46bb421e 100644 --- a/man/vis.immunr_public_repertoire.Rd +++ b/man/vis.immunr_public_repertoire.Rd @@ -10,12 +10,12 @@ \item{.data}{Public repertoire, an output from \link{pubRep}.} \item{.plot}{A string specifying the plot type: - -- "freq" for visualisation of the distribution of occurrences of clonotypes +\itemize{ +\item "freq" for visualisation of the distribution of occurrences of clonotypes and their frequencies using \link{vis_public_frequencies}. - -- "clonotypes" for visualisation of public clonotype frequenciy correlations between pairs of -samples using \link{vis_public_clonotypes}} +\item "clonotypes" for visualisation of public clonotype frequenciy correlations between pairs of +samples using \link{vis_public_clonotypes} +}} \item{...}{Further arguments passed \link{vis_public_frequencies} or \link{vis_public_clonotypes}, depending on the ".plot" argument.} diff --git a/man/vis.immunr_public_statistics.Rd b/man/vis.immunr_public_statistics.Rd index 70518ed0..929a165e 100644 --- a/man/vis.immunr_public_statistics.Rd +++ b/man/vis.immunr_public_statistics.Rd @@ -9,7 +9,7 @@ \arguments{ \item{.data}{Public repertoire - an output from the \link{pubRep} function.} -\item{...}{Other arguments passsed directly to [UpSetR::upset].} +\item{...}{Other arguments passsed directly to \link[UpSetR:upset]{UpSetR::upset}.} } \value{ A ggplot2 object. diff --git a/man/vis_box.Rd b/man/vis_box.Rd index 5ac3f444..9d99d139 100644 --- a/man/vis_box.Rd +++ b/man/vis_box.Rd @@ -38,7 +38,7 @@ pass NA to ".meta".} \item{.meta}{A metadata object. An R dataframe with sample names and their properties, such as age, serostatus or hla.} -\item{.melt}{If TRUE then apply [reshape2::melt] to the ".data" before plotting. +\item{.melt}{If TRUE then apply \link[reshape2:melt]{reshape2::melt} to the ".data" before plotting. In this case ".data" is supposed to be a data frame with the first character column reserved for names of genes and other numeric columns reserved to counts or frequencies of genes. Each numeric column should be associated with a specific repertoire sample.} diff --git a/man/vis_circos.Rd b/man/vis_circos.Rd index d037775a..a39c2245 100644 --- a/man/vis_circos.Rd +++ b/man/vis_circos.Rd @@ -11,13 +11,13 @@ vis_circos(.data, .title = NULL, ...) \item{.title}{The The text for the title of the plot.} -\item{...}{Other arguments passed to [circlize::chordDiagram] from the 'circlize' package.} +\item{...}{Other arguments passed to \link[circlize:chordDiagram]{circlize::chordDiagram} from the 'circlize' package.} } \value{ A circlize object. } \description{ -Visualise matrices with the [circlize::chordDiagram] function +Visualise matrices with the \link[circlize:chordDiagram]{circlize::chordDiagram} function from the circlize package. } \examples{ diff --git a/man/vis_heatmap2.Rd b/man/vis_heatmap2.Rd index d7abf116..a6eb3aa4 100644 --- a/man/vis_heatmap2.Rd +++ b/man/vis_heatmap2.Rd @@ -22,18 +22,18 @@ such as age, serostatus or hla.} \item{.by}{Set NA if you want to plot samples without grouping.} -\item{.title}{The text for the plot's title (same as the "main" argument in \link[pheatmap]{pheatmap}).} +\item{.title}{The text for the plot's title (same as the "main" argument in \link[pheatmap:pheatmap]{pheatmap}).} -\item{.color}{A vector specifying the colors (same as the "color" argument in \link[pheatmap]{pheatmap}). +\item{.color}{A vector specifying the colors (same as the "color" argument in \link[pheatmap:pheatmap]{pheatmap}). Pass NA to use the default pheatmap colors.} -\item{...}{Other arguments for the \link[pheatmap]{pheatmap} function.} +\item{...}{Other arguments for the \link[pheatmap:pheatmap]{pheatmap} function.} } \value{ A pheatmap object. } \description{ -Visualise matrices with the functions based on the \link[pheatmap]{pheatmap} +Visualise matrices with the functions based on the \link[pheatmap:pheatmap]{pheatmap} package with minimum amount of arguments. } \examples{ diff --git a/man/vis_hist.Rd b/man/vis_hist.Rd index 6e38be93..46d3201f 100644 --- a/man/vis_hist.Rd +++ b/man/vis_hist.Rd @@ -52,7 +52,7 @@ to automatically detect the optimal number of columns.} \item{.labs}{A character vector of length two with names for x-axis and y-axis, respectively.} -\item{.melt}{If TRUE then apply [reshape2::melt] to the ".data" before plotting. +\item{.melt}{If TRUE then apply \link[reshape2:melt]{reshape2::melt} to the ".data" before plotting. In this case ".data" is supposed to be a data frame with the first character column reserved for names of genes and other numeric columns reserved to counts or frequencies of genes. Each numeric column should be associated with a specific repertoire sample.} @@ -73,11 +73,11 @@ Visualisation of distributions using ggplot2-based histograms. \details{ If data is grouped, then statistical tests for comparing means of groups will be performed, unless \code{.test = FALSE} is supplied. In case there are only two groups, the Wilcoxon rank sum test (https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) is performed -(R function \code{\link{wilcox.test}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. -In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link{kruskal.test}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. +(R function \code{\link[=wilcox.test]{wilcox.test()}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. +In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal\%E2\%80\%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link[=kruskal.test]{kruskal.test()}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. A significant Kruskal-Wallis test indicates that at least one sample stochastically dominates one other sample. Adjusted for multiple comparisons P-values are plotted on the top of groups. -P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm%E2%80%93Bonferroni_method) (also known as Holm-Bonferroni correction). +P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm\%E2\%80\%93Bonferroni_method) (also known as Holm-Bonferroni correction). You can execute the command \code{?p.adjust} in the R console to see more. } \examples{ diff --git a/man/vis_immunr_kmer_profile_main.Rd b/man/vis_immunr_kmer_profile_main.Rd index a3bb6472..befdaf29 100644 --- a/man/vis_immunr_kmer_profile_main.Rd +++ b/man/vis_immunr_kmer_profile_main.Rd @@ -10,10 +10,10 @@ vis_immunr_kmer_profile_main(.data, .plot, ...) \item{.data}{Kmer data, an output from \link{kmer_profile}.} \item{.plot}{String specifying the plot type: - -- "seqlogo" for traditional sequence logo plots using \link{vis_seqlogo}; - -- "textlogo" for modified approach to sequence logo plots via text labels using \link{vis_textlogo};} +\itemize{ +\item "seqlogo" for traditional sequence logo plots using \link{vis_seqlogo}; +\item "textlogo" for modified approach to sequence logo plots via text labels using \link{vis_textlogo}; +}} \item{...}{Other arguments passed to \link{vis_textlogo} or \link{vis_seqlogo}, depending on the ".plot" argument.} diff --git a/man/vis_textlogo.Rd b/man/vis_textlogo.Rd index 8c1390df..6e67796d 100644 --- a/man/vis_textlogo.Rd +++ b/man/vis_textlogo.Rd @@ -20,7 +20,7 @@ to plot points on the straight vertical line for each position.} \item{...}{Not used here.} -\item{.scheme}{Character. An argument passed to [ggseqlogo::geom_logo] specifying how to colour symbols.} +\item{.scheme}{Character. An argument passed to \link[ggseqlogo:geom_logo]{ggseqlogo::geom_logo} specifying how to colour symbols.} } \value{ A ggplot2 object. @@ -28,10 +28,10 @@ A ggplot2 object. \description{ Plot sequence logo plots for visualising of amino acid motif sequences / profiles. -`vis_textlogo` plots sequences in a text format - each letter has the same height. Useful when there +\code{vis_textlogo} plots sequences in a text format - each letter has the same height. Useful when there are no big differences between occurences of amino acids in the motif. -`vis_seqlogo` is a traditional sequence logo plots. Useful when there are one or two amino acids +\code{vis_seqlogo} is a traditional sequence logo plots. Useful when there are one or two amino acids with clear differences in their occurrences. } \examples{ From 7a7f74e8234e252cdeaafcd23f15d9bc4902bb89 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Sat, 16 Aug 2025 13:52:08 +0200 Subject: [PATCH 05/36] chore: version bump; remove or move packages from dependencies --- DESCRIPTION | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f2834a58..ae86e30b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,19 +1,15 @@ Package: immunarch Type: Package -Title: Bioinformatics Analysis of T-Cell and B-Cell Immune Repertoires -Version: 0.9.2 +Title: Data-Driven Immune Repertoire Insights for Immunotherapy and Vaccine Design +Version: 0.9.1.9001 Authors@R: c( person("Vadim I.", "Nazarov", , "support@immunomind.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-3659-2709")), person("Vasily O.", "Tsvetkov", , role = "aut"), - person("Siarhei", "Fiadziushchanka", , role = "aut"), - person("Eugene", "Rumynskiy", , role = "aut"), person("Aleksandr A.", "Popov", , role = "aut"), person("Ivan", "Balashov", , role = "aut"), person("Maria", "Samokhina", , role = "aut"), - person("Anna", "Lorenc", , role = "ctb"), person("Daniel J.", "Moore", , role = "ctb"), - person("Victor", "Greiff", , role = "ctb"), person("ImmunoMind", role = c("cph", "fnd")) ) Contact: support@immunomind.com @@ -28,7 +24,15 @@ Description: A comprehensive framework for bioinformatics exploratory analysis o License: Apache License (== 2.0) URL: https://immunarch.com/, https://github.com/immunomind/immunarch BugReports: https://github.com/immunomind/immunarch/issues +Depends: + R (>= 4.1.0), + ggplot2 (>= 3.1.0), + immundata (>= 0.0.2.9002), + patchwork Imports: + dplyr (>= 0.8.0), + dtplyr (>= 1.0.0), + data.table (>= 1.12.6), cli, pheatmap (>= 1.0.12), reshape2 (>= 1.4.2), @@ -41,7 +45,7 @@ Imports: magrittr, methods, scales, - rlang (>= 0.4), + rlang, plyr, purrr, stringdist, @@ -57,15 +61,14 @@ Imports: utils, glue, uuid, - stringi -Depends: - R (>= 4.0.0), - ggplot2 (>= 3.1.0), - dplyr (>= 0.8.0), - dtplyr (>= 1.0.0), - data.table (>= 1.12.6), - patchwork + stringi, + checkmate, + duckplyr, + dbplyr, + lifecycle LinkingTo: Rcpp +Remotes: + immunomind/immundata-rlang Suggests: knitr (>= 1.8), roxygen2 (>= 3.0.0), @@ -84,8 +87,11 @@ Suggests: ggrepel (>= 0.8.0), shiny (>= 1.4.0), shinythemes -VignetteBuilder: knitr +VignetteBuilder: + knitr + quarto Encoding: UTF-8 RoxygenNote: 7.3.2 LazyData: true LazyDataCompression: xz +Roxygen: list(markdown = TRUE) From c2142e0836f680f9b266a91a3536e2499dc8f057 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Sat, 16 Aug 2025 13:54:28 +0200 Subject: [PATCH 06/36] docs: move old vignettes to a separate folder --- vignettes/.gitignore | 1 + vignettes/{v2_data.Rmd => data.Rmd} | 0 .../{v1_introduction.Rmd => introduction.Rmd} | 0 .../{web_only => web_only_v0}/BCRpipeline.Rmd | 0 .../{web_only => web_only_v0}/clustering.Rmd | 0 .../{web_only => web_only_v0}/community.Rmd | 0 .../{web_only => web_only_v0}/load_10x.Rmd | 0 .../{web_only => web_only_v0}/load_mixcr.Rmd | 0 .../repFilter_v3.Rmd | 0 .../{web_only => web_only_v0}/v10_prop.Rmd | 0 .../{web_only => web_only_v0}/v11_db.Rmd | 0 .../v21_singlecell.Rmd | 0 .../v3_basic_analysis.Rmd | 0 .../{web_only => web_only_v0}/v4_overlap.Rmd | 0 .../v5_gene_usage.Rmd | 0 .../v6_diversity.Rmd | 0 .../{web_only => web_only_v0}/v7_fixvis.Rmd | 0 .../{web_only => web_only_v0}/v8_tracking.Rmd | 0 .../{web_only => web_only_v0}/v9_kmers.Rmd | 0 vignettes/web_only_v1/receptor_track.Rmd | 60 +++++++++++++++++++ 20 files changed, 61 insertions(+) create mode 100644 vignettes/.gitignore rename vignettes/{v2_data.Rmd => data.Rmd} (100%) rename vignettes/{v1_introduction.Rmd => introduction.Rmd} (100%) rename vignettes/{web_only => web_only_v0}/BCRpipeline.Rmd (100%) rename vignettes/{web_only => web_only_v0}/clustering.Rmd (100%) rename vignettes/{web_only => web_only_v0}/community.Rmd (100%) rename vignettes/{web_only => web_only_v0}/load_10x.Rmd (100%) rename vignettes/{web_only => web_only_v0}/load_mixcr.Rmd (100%) rename vignettes/{web_only => web_only_v0}/repFilter_v3.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v10_prop.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v11_db.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v21_singlecell.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v3_basic_analysis.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v4_overlap.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v5_gene_usage.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v6_diversity.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v7_fixvis.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v8_tracking.Rmd (100%) rename vignettes/{web_only => web_only_v0}/v9_kmers.Rmd (100%) create mode 100644 vignettes/web_only_v1/receptor_track.Rmd diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 00000000..633fb800 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1 @@ +*_files diff --git a/vignettes/v2_data.Rmd b/vignettes/data.Rmd similarity index 100% rename from vignettes/v2_data.Rmd rename to vignettes/data.Rmd diff --git a/vignettes/v1_introduction.Rmd b/vignettes/introduction.Rmd similarity index 100% rename from vignettes/v1_introduction.Rmd rename to vignettes/introduction.Rmd diff --git a/vignettes/web_only/BCRpipeline.Rmd b/vignettes/web_only_v0/BCRpipeline.Rmd similarity index 100% rename from vignettes/web_only/BCRpipeline.Rmd rename to vignettes/web_only_v0/BCRpipeline.Rmd diff --git a/vignettes/web_only/clustering.Rmd b/vignettes/web_only_v0/clustering.Rmd similarity index 100% rename from vignettes/web_only/clustering.Rmd rename to vignettes/web_only_v0/clustering.Rmd diff --git a/vignettes/web_only/community.Rmd b/vignettes/web_only_v0/community.Rmd similarity index 100% rename from vignettes/web_only/community.Rmd rename to vignettes/web_only_v0/community.Rmd diff --git a/vignettes/web_only/load_10x.Rmd b/vignettes/web_only_v0/load_10x.Rmd similarity index 100% rename from vignettes/web_only/load_10x.Rmd rename to vignettes/web_only_v0/load_10x.Rmd diff --git a/vignettes/web_only/load_mixcr.Rmd b/vignettes/web_only_v0/load_mixcr.Rmd similarity index 100% rename from vignettes/web_only/load_mixcr.Rmd rename to vignettes/web_only_v0/load_mixcr.Rmd diff --git a/vignettes/web_only/repFilter_v3.Rmd b/vignettes/web_only_v0/repFilter_v3.Rmd similarity index 100% rename from vignettes/web_only/repFilter_v3.Rmd rename to vignettes/web_only_v0/repFilter_v3.Rmd diff --git a/vignettes/web_only/v10_prop.Rmd b/vignettes/web_only_v0/v10_prop.Rmd similarity index 100% rename from vignettes/web_only/v10_prop.Rmd rename to vignettes/web_only_v0/v10_prop.Rmd diff --git a/vignettes/web_only/v11_db.Rmd b/vignettes/web_only_v0/v11_db.Rmd similarity index 100% rename from vignettes/web_only/v11_db.Rmd rename to vignettes/web_only_v0/v11_db.Rmd diff --git a/vignettes/web_only/v21_singlecell.Rmd b/vignettes/web_only_v0/v21_singlecell.Rmd similarity index 100% rename from vignettes/web_only/v21_singlecell.Rmd rename to vignettes/web_only_v0/v21_singlecell.Rmd diff --git a/vignettes/web_only/v3_basic_analysis.Rmd b/vignettes/web_only_v0/v3_basic_analysis.Rmd similarity index 100% rename from vignettes/web_only/v3_basic_analysis.Rmd rename to vignettes/web_only_v0/v3_basic_analysis.Rmd diff --git a/vignettes/web_only/v4_overlap.Rmd b/vignettes/web_only_v0/v4_overlap.Rmd similarity index 100% rename from vignettes/web_only/v4_overlap.Rmd rename to vignettes/web_only_v0/v4_overlap.Rmd diff --git a/vignettes/web_only/v5_gene_usage.Rmd b/vignettes/web_only_v0/v5_gene_usage.Rmd similarity index 100% rename from vignettes/web_only/v5_gene_usage.Rmd rename to vignettes/web_only_v0/v5_gene_usage.Rmd diff --git a/vignettes/web_only/v6_diversity.Rmd b/vignettes/web_only_v0/v6_diversity.Rmd similarity index 100% rename from vignettes/web_only/v6_diversity.Rmd rename to vignettes/web_only_v0/v6_diversity.Rmd diff --git a/vignettes/web_only/v7_fixvis.Rmd b/vignettes/web_only_v0/v7_fixvis.Rmd similarity index 100% rename from vignettes/web_only/v7_fixvis.Rmd rename to vignettes/web_only_v0/v7_fixvis.Rmd diff --git a/vignettes/web_only/v8_tracking.Rmd b/vignettes/web_only_v0/v8_tracking.Rmd similarity index 100% rename from vignettes/web_only/v8_tracking.Rmd rename to vignettes/web_only_v0/v8_tracking.Rmd diff --git a/vignettes/web_only/v9_kmers.Rmd b/vignettes/web_only_v0/v9_kmers.Rmd similarity index 100% rename from vignettes/web_only/v9_kmers.Rmd rename to vignettes/web_only_v0/v9_kmers.Rmd diff --git a/vignettes/web_only_v1/receptor_track.Rmd b/vignettes/web_only_v1/receptor_track.Rmd new file mode 100644 index 00000000..3e16932b --- /dev/null +++ b/vignettes/web_only_v1/receptor_track.Rmd @@ -0,0 +1,60 @@ +--- +title: "Tracking receptors across immune space and time" +author: "Vadim I. Nazarov" +date: "`r Sys.Date()`" +output: + html_document: + fig_height: 8 + fig_width: 10 + theme: spacelab + toc: yes + pdf_document: + toc: yes + word_document: + toc: yes +--- + + + + + + +```{r setup, include=FALSE, echo=FALSE} +# knitr::knit_hooks$set(optipng = knitr::hook_optipng) +# knitr::opts_chunk$set(optipng = '-o7') + +knitr::opts_chunk$set(echo = TRUE) +knitr::opts_chunk$set(fig.align = "center") +knitr::opts_chunk$set(fig.width = 12) +knitr::opts_chunk$set(fig.height = 6) + +library(immunarch) +data(immdata) +read_repertoires from system.file. +``` + +# Background + +what it is + +relevance for immunotherapy + +# Tracking receptors + +# Visualising + +# Clustering + +# Input / output +#' 1a) List of CDR3 - vector + col to match (screw that, just pass a data frame) +#' 1b) List of CDR3 + other columns +#' 1c) List of CDR3 alpha + CDR3 beta (+ other columns) +#' 2a) Find abundance of found receptors in an ordered repertoires +#' 2b) Find abundance of receptors close by distance in an ordered repertoires +#' 3a) Visualise via alluvial +#' 3b) Compute PCA on abundances and visualise +#' From 3f233edcf1c6e160d3658001d798e25caecf08fe Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:20:31 +0200 Subject: [PATCH 07/36] feat: airr_clonality --- R/v1_airr_clonality.R | 272 ++++++++++++++++++++++++++++++++++++++++++ man/airr_clonality.Rd | 146 +++++++++++++++++++++++ 2 files changed, 418 insertions(+) create mode 100644 R/v1_airr_clonality.R create mode 100644 man/airr_clonality.Rd diff --git a/R/v1_airr_clonality.R b/R/v1_airr_clonality.R new file mode 100644 index 00000000..98c6f3ec --- /dev/null +++ b/R/v1_airr_clonality.R @@ -0,0 +1,272 @@ +#' @title Clonality — receptor overabundance statistics for immune repertoires +#' +#' @description +#' `r lifecycle::badge("experimental")` +#' +#' A family of functions to quantify **receptor overabundance** per repertoire. +#' +#' ## Available functions: +#' +#' @param idata An `ImmunData` object. +#' @inheritParams airr_clonality_line +#' @inheritParams airr_clonality_rank +#' @inheritParams airr_clonality_prop +#' @inheritParams im_common_args +#' +#' @seealso [immundata::ImmunData] +#' +#' @name airr_clonality +#' @concept Clonality +NULL + + +#' @keywords internal +airr_clonality_line_impl <- function(idata, limit = 100000) { + checkmate::check_numeric(limit, lower = 10, len = 1) + + n_repertoires <- idata$repertoires |> + distinct(!!immundata::imd_schema_sym("repertoire")) |> + pull() |> + length() + + idata$annotations |> + select(all_of(c( + immundata::imd_schema("repertoire"), + immundata::imd_schema("receptor"), + immundata::imd_schema("count") + ))) |> + distinct(!!immundata::imd_schema_sym("repertoire"), + !!immundata::imd_schema_sym("receptor"), + .keep_all = TRUE + ) |> + arrange(desc(!!immundata::imd_schema_sym("count"))) |> + slice_head(n = limit * n_repertoires) |> # Optimization before compute - does it make sense, though? + compute() |> # TODO: If we remove compute, the output breaks. Open an issue in duckplr - something wrong with row_number + mutate-by + mutate( + index = row_number(), + .by = immundata::imd_schema("repertoire") + ) |> + filter(index <= limit) |> + select(-!!immundata::imd_schema_sym("receptor")) |> + left_join( + idata$repertoires |> select(-any_of(c( + immundata::imd_schema("n_barcodes"), + immundata::imd_schema("n_receptors") + ))), + by = immundata::imd_schema("repertoire") + ) |> + arrange(index) |> + collect() +} + + +#' @description `airr_clonality_line` — build ranked abundance lines: for each +#' repertoire, take the top `limit` receptors by `count` and attach repertoire +#' metadata. Useful for per-repertoire rank–abundance plots. +#' +#' @param limit Positive integer ≥ 10: maximum number of top receptors to keep +#' **per repertoire** (default `100000`). +#' +#' @return +#' +#' ## `airr_clonality_line` +#' A tibble with columns: +#' * `repertoire_id` — repertoire identifier +#' * `index` — rank within repertoire (1 = most abundant) +#' * `count` — receptor count used for ranking +#' * plus any repertoire metadata columns carried from `idata$repertoires` +#' +#' @examples +#' # +#' # airr_clonality_line +#' # +#' top_line <- airr_clonality_line(immdata, limit = 1000) +#' +#' @rdname airr_clonality +#' @concept Clonality +#' @export +airr_clonality_line <- register_immunarch_method(airr_clonality_line_impl, "airr_clonality", "line") + + +#' @keywords internal +airr_clonality_rank_impl <- function(idata, + bins = c(10, 30, 100, 300, 1000, 10000, 100000), + output = c("stat", "annot")) { + checkmate::check_numeric(bins, lower = 1) + + output <- match.arg(output) + + bins <- sort(bins, decreasing = FALSE) + + sql_expr <- paste0( + "CASE ", + paste0(map_chr( + bins, + ~ cli::format_inline("WHEN ROW_NUMBER() OVER (PARTITION BY {immundata::imd_schema('repertoire')} ORDER BY {immundata::imd_schema('proportion')} DESC) <= {.x} THEN {.x}") + ), collapse = " "), " ELSE NULL END" + ) + + clonality_df <- idata$annotations |> + select(all_of(c( + immundata::imd_schema("repertoire"), + immundata::imd_schema("receptor"), + immundata::imd_schema("proportion") + ))) |> + distinct(!!immundata::imd_schema_sym("repertoire"), + !!immundata::imd_schema_sym("receptor"), + .keep_all = TRUE + ) |> + arrange() |> + as_tbl() |> + mutate(clonal_rank_bin = dbplyr::sql(sql_expr)) |> + as_duckdb_tibble() |> + compute() + + if (output == "stat") { + clonality_df |> + summarise( + .by = c(immundata::imd_schema("repertoire"), "clonal_rank_bin"), + occupied_prop = sum(!!immundata::imd_schema_sym("proportion"), na.rm = TRUE) + ) |> + right_join(idata$repertoires, by = immundata::imd_schema("repertoire")) + } else { + ImmunData$new( + schema = idata$schema_receptor, + annotations = idata$annotations |> + left_join(clonality_df, + by = immundata::imd_schema("receptor") + ) + ) + } +} + + +#' @description `airr_clonality_rank` — aggregate clonal space by **rank bins**. +#' Receptors are ordered by `proportion` within each repertoire; each receptor +#' is assigned to the smallest threshold in `bins` that contains its rank. +#' +#' @param bins Integer vector of rank thresholds (e.g., `c(10, 100, 1000)`). +#' For each repertoire, receptors with ranks `<= bins[i]` contribute to bin +#' `bins[i]`. Bins are sorted ascending internally. +#' @param output One of `"stat"` (default) to return per-repertoire bin +#' aggregates, or `"annot"` to return an `ImmunData` with an added +#' `clonal_rank_bin` column in `annotations`. +#' +#' @return +#' +#' ## `airr_clonality_rank` +#' If `output = "stat"`: a tibble with +#' * `repertoire_id` +#' * `clonal_rank_bin` — the rank threshold (e.g., `10`, `100`, …) +#' * `occupied_prop` — sum of `proportion` within the bin +#' * plus repertoire metadata columns from `idata$repertoires` +#' +#' If `output = "annot"`: an `ImmunData` object where `annotations` includes +#' `clonal_rank_bin`. +#' +#' @examples +#' # +#' # airr_clonality_rank +#' # +#' rank_stat <- airr_clonality_rank(immdata, bins = c(10, 100), output = "stat") +#' rank_annot <- airr_clonality_rank(immdata, bins = c(10, 100), output = "annot") +#' +#' @rdname airr_clonality +#' @concept Clonality +#' @export +airr_clonality_rank <- register_immunarch_method(airr_clonality_rank_impl, "airr_clonality", "rank") + + +#' @keywords internal +airr_clonality_prop_impl <- function( + idata, bins = c( + Hyperexpanded = 1e-2, + Large = 1e-3, + Medium = 1e-4, + Small = 1e-5, + Rare = 1e-6 + ), + output = c("stat", "annot")) { + checkmate::check_numeric(bins, lower = 0, min.len = 1) + + output <- match.arg(output) + + bins <- sort(bins, decreasing = TRUE) + + sql_expr <- paste0( + "CASE ", + paste0(map2_chr( + bins, names(bins), + ~ sprintf("WHEN %s >= %s THEN '%s'", immundata::imd_schema("proportion"), .x, .y) + ), collapse = " "), " ELSE 'Ultra-rare' END" + ) + + clonality_df <- idata$annotations |> + select(all_of(c( + immundata::imd_schema("repertoire"), + immundata::imd_schema("receptor"), + immundata::imd_schema("proportion") + ))) |> + distinct(!!immundata::imd_schema_sym("repertoire"), + !!immundata::imd_schema_sym("receptor"), + .keep_all = TRUE + ) |> + duckplyr::as_tbl() |> + mutate(clonal_prop_bin = dbplyr::sql(sql_expr)) |> + duckplyr::as_duckdb_tibble() |> + compute() + + if (output == "stat") { + clonality_df |> + summarise( + .by = c(immundata::imd_schema("repertoire"), "clonal_prop_bin"), + occupied_prop = sum(!!immundata::imd_schema_sym("proportion"), na.rm = TRUE) + ) |> + right_join(idata$repertoires, by = immundata::imd_schema("repertoire")) + } else { + ImmunData$new( + schema = idata$schema_receptor, + annotations = idata$annotations |> + left_join(clonality_df, + by = immundata::imd_schema("receptor") + ) + ) + } +} + + +#' @description `airr_clonality_prop` — aggregate clonal space by **proportion bins**. +#' Each receptor is assigned to a named bin according to its `proportion` +#' (e.g., `Hyperexpanded ≥ 1e-2`, `Large ≥ 1e-3`, …). Thresholds are matched in +#' descending order; unmatched receptors fall into `"Ultra-rare"`. +#' +#' @param bins A **named** numeric vector of thresholds (e.g., +#' `c(Hyperexpanded = 1e-2, Large = 1e-3, ...)`). Names become bin labels and +#' must be non-empty. Internally sorted in descending order. +#' @param output One of `"stat"` (default) to return per-repertoire bin +#' aggregates, or `"annot"` to return an `ImmunData` with an added +#' `clonal_prop_bin` column in `annotations`. +#' +#' @return +#' +#' ## `airr_clonality_prop` +#' If `output = "stat"`: a tibble with +#' * `repertoire_id` +#' * `clonal_prop_bin` — factor-like label from `names(bins)` or `"Ultra-rare"` +#' * `occupied_prop` — sum of `proportion` within the bin +#' * plus repertoire metadata columns from `idata$repertoires` +#' +#' If `output = "annot"`: an `ImmunData` object where `annotations` includes +#' `clonal_prop_bin`. +#' +#' @examples +#' # +#' # airr_clonality_prop +#' # +#' prop_stat <- airr_clonality_prop(immdata, output = "stat") +#' prop_annot <- airr_clonality_prop(immdata, output = "annot") +#' +#' @rdname airr_clonality +#' @concept Clonality +#' @export +airr_clonality_prop <- register_immunarch_method(airr_clonality_prop_impl, "airr_clonality", "prop") diff --git a/man/airr_clonality.Rd b/man/airr_clonality.Rd new file mode 100644 index 00000000..b29e8929 --- /dev/null +++ b/man/airr_clonality.Rd @@ -0,0 +1,146 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/v1_airr_clonality.R +\name{airr_clonality} +\alias{airr_clonality} +\alias{airr_clonality_line} +\alias{airr_clonality_rank} +\alias{airr_clonality_prop} +\title{Clonality — receptor overabundance statistics for immune repertoires} +\usage{ +airr_clonality_line( + idata, + limit = 1e+05, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_clonality_rank( + idata, + bins = c(10, 30, 100, 300, 1000, 10000, 1e+05), + output = c("stat", "annot"), + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_clonality_prop( + idata, + bins = c(Hyperexpanded = 0.01, Large = 0.001, Medium = 1e-04, Small = 1e-05, Rare = + 1e-06), + output = c("stat", "annot"), + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) +} +\arguments{ +\item{idata}{An \code{ImmunData} object.} + +\item{limit}{Positive integer ≥ 10: maximum number of top receptors to keep +\strong{per repertoire} (default \code{100000}).} + +\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. +For \code{format="analysis"}, metadata is joined to the long table; for +\code{format="ml"}, it’s joined after pivoting to wide. Defaults to +\code{getOption("immundata.autojoin", FALSE)}.} + +\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet +columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} + +\item{features}{Character vector of \strong{feature keys} to keep when +\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key +looks like \verb{family.method|facet1=...;facet2=...} (e.g., +\code{airr_stats.genes|v_call=TRBV7-2}).} + +\item{bins}{A \strong{named} numeric vector of thresholds (e.g., +\code{c(Hyperexpanded = 1e-2, Large = 1e-3, ...)}). Names become bin labels and +must be non-empty. Internally sorted in descending order.} + +\item{output}{One of \code{"stat"} (default) to return per-repertoire bin +aggregates, or \code{"annot"} to return an \code{ImmunData} with an added +\code{clonal_prop_bin} column in \code{annotations}.} +} +\value{ +\subsection{\code{airr_clonality_line}}{ + +A tibble with columns: +\itemize{ +\item \code{repertoire_id} — repertoire identifier +\item \code{index} — rank within repertoire (1 = most abundant) +\item \code{count} — receptor count used for ranking +\item plus any repertoire metadata columns carried from \code{idata$repertoires} +} +} + +\subsection{\code{airr_clonality_rank}}{ + +If \code{output = "stat"}: a tibble with +\itemize{ +\item \code{repertoire_id} +\item \code{clonal_rank_bin} — the rank threshold (e.g., \code{10}, \code{100}, …) +\item \code{occupied_prop} — sum of \code{proportion} within the bin +\item plus repertoire metadata columns from \code{idata$repertoires} +} + +If \code{output = "annot"}: an \code{ImmunData} object where \code{annotations} includes +\code{clonal_rank_bin}. +} + +\subsection{\code{airr_clonality_prop}}{ + +If \code{output = "stat"}: a tibble with +\itemize{ +\item \code{repertoire_id} +\item \code{clonal_prop_bin} — factor-like label from \code{names(bins)} or \code{"Ultra-rare"} +\item \code{occupied_prop} — sum of \code{proportion} within the bin +\item plus repertoire metadata columns from \code{idata$repertoires} +} + +If \code{output = "annot"}: an \code{ImmunData} object where \code{annotations} includes +\code{clonal_prop_bin}. +} +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A family of functions to quantify \strong{receptor overabundance} per repertoire. +\subsection{Available functions:}{ +} + +\code{airr_clonality_line} — build ranked abundance lines: for each +repertoire, take the top \code{limit} receptors by \code{count} and attach repertoire +metadata. Useful for per-repertoire rank–abundance plots. + +\code{airr_clonality_rank} — aggregate clonal space by \strong{rank bins}. +Receptors are ordered by \code{proportion} within each repertoire; each receptor +is assigned to the smallest threshold in \code{bins} that contains its rank. + +\code{airr_clonality_prop} — aggregate clonal space by \strong{proportion bins}. +Each receptor is assigned to a named bin according to its \code{proportion} +(e.g., \verb{Hyperexpanded ≥ 1e-2}, \verb{Large ≥ 1e-3}, …). Thresholds are matched in +descending order; unmatched receptors fall into \code{"Ultra-rare"}. +} +\examples{ +# +# airr_clonality_line +# +top_line <- airr_clonality_line(immdata, limit = 1000) + +# +# airr_clonality_rank +# +rank_stat <- airr_clonality_rank(immdata, bins = c(10, 100), output = "stat") +rank_annot <- airr_clonality_rank(immdata, bins = c(10, 100), output = "annot") + +# +# airr_clonality_prop +# +prop_stat <- airr_clonality_prop(immdata, output = "stat") +prop_annot <- airr_clonality_prop(immdata, output = "annot") + +} +\seealso{ +\link[immundata:ImmunData]{immundata::ImmunData} +} +\concept{Clonality} From 1d08a035049f2dbf1d0f67347292ae6a03a1c39d Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:20:40 +0200 Subject: [PATCH 08/36] feat: airr_stats --- R/v1_airr_stats.R | 193 ++++++++++++++++++++++++++++++++++++++++++++++ man/airr_stats.Rd | 150 +++++++++++++++++++++++++++++++++++ 2 files changed, 343 insertions(+) create mode 100644 R/v1_airr_stats.R create mode 100644 man/airr_stats.Rd diff --git a/R/v1_airr_stats.R b/R/v1_airr_stats.R new file mode 100644 index 00000000..6fe73118 --- /dev/null +++ b/R/v1_airr_stats.R @@ -0,0 +1,193 @@ +#' @title Compute key immune repertoire statistics +#' +#' @description +#' `r lifecycle::badge("experimental")` +#' +#' A family of functions that extract **core descriptive statistics** from an `ImmunData` object. +#' +#' ## Available functions: +#' +#' @param idata An `ImmunData` object. +#' @inheritParams airr_stats_chains +#' @inheritParams airr_stats_lengths +#' @inheritParams airr_stats_genes +#' @inheritParams im_common_args +#' +#' @seealso [immundata::ImmunData] +#' +#' @name airr_stats +#' @concept Key AIRR statistics +NULL + + +#' @keywords internal +airr_stats_chains_impl <- function(idata, locus_col = NA) { + checkmate::assert_character(locus_col, null.ok = TRUE) + + if (is.na(locus_col)) { + locus_col <- immundata::imd_schema("locus") + + if (!locus_col %in% colnames(idata$annotations)) { + locus_col <- NULL + } + } else if (!is.null(locus_col)) { + if (!locus_col %in% colnames(idata$annotations)) { + cli::cli_alert_warning("No locus column {.code locus_col} found.") + } + } + + repertoire_id_col <- immundata::imd_schema("repertoire") + + by_cols <- c(repertoire_id_col, locus_col) + + chain_stats <- idata$annotations |> + summarise( + .by = all_of(by_cols), + n_chains = n() + ) + + chain_stats <- idata$repertoires |> + left_join(chain_stats, by = repertoire_id_col) |> + collect() + + if (!is.null(locus_col)) { + chain_stats |> mutate(locus = NA) + } else { + chain_stats |> rename(locus = locus_col) + } +} + + +#' @description `airr_stats_chains` --- count V(D)J *chains* per repertoire (optionally split by locus). WHY USEFUL / APPLICATION? +#' +#' @param locus_col Column in `idata$annotations` that stores the locus (e.g. `"locus"`). If `NULL` or missing, the result is not split by locus. +#' +#' @return +#' +#' ## `airr_stats_chains` +#' Returns a tibble with columns: +#' * `repertoire_id` -- repertoire identifier +#' * `locus` -- TRA, TRB, IGH … (present only if `locus_col` is supplied) +#' * `n_chains` -- number of chains +#' +#' @examples +#' # +#' # airr_stats_chains +#' # +#' airr_stats_chains(immdata) +#' +#' @rdname airr_stats +#' @concept Key AIRR statistics +#' @export +airr_stats_chains <- register_immunarch_method(airr_stats_chains_impl, "airr_stats", "chains") + + +#' @keywords internal +airr_stats_lengths_impl <- function(idata, seq_col = "cdr3_aa") { + length_tbl <- idata$annotations |> + distinct(!!rlang::sym(seq_col)) |> + mutate(seq_len = dd$length(!!rlang::sym(seq_col))) + + idata$annotations |> + select(all_of(c(idata$schema_repertoire, seq_col))) |> + left_join(length_tbl, by = seq_col) |> + summarise(.by = all_of(c(idata$schema_repertoire, "seq_len")), n = n()) |> + collect() +} + + +#' @description `airr_stats_lengths` --- count the number of sequence lengths per repertoire. WHY USEFUL / APPLICATION? +#' +#' @param seq_col Character vector with names of the columns containing sequences. +#' +#' @return +#' +#' ## `airr_stats_lengths` +#' Returns a tibble with columns: +#' * `repertoire_id` -- repertoire identifier +#' * `seq_len` -- lengths of sequences +#' * `n` -- number of receptors +#' +#' @examples +#' # +#' # airr_stats_lengths +#' # +#' airr_stats_lengths(immdata) +#' +#' @rdname airr_stats +#' @concept Key AIRR statistics +#' @export +airr_stats_lengths <- register_immunarch_method(airr_stats_lengths_impl, "airr_stats", "lengths") + + +#' @keywords internal +airr_stats_genes_impl <- function(idata, gene_col = "v_call", level = c("receptor", "barcode"), by = c(NA, "locus")) { + checkmate::assert_logical(gene_col %in% colnames(idata$annotations)) + level <- match.arg(level) + by <- match.arg(by) + if (!is.na(by)) { + checkmate::assert_logical(by %in% colnames(idata$annotations)) + } + + receptors <- idata$annotations |> + distinct(!!rlang::sym(immundata::imd_schema("receptor")), !!rlang::sym(immundata::imd_schema("repertoire")), .keep_all = TRUE) + + if (level == "receptor") { + genes <- receptors |> + summarise(.by = all_of(c(gene_col, immundata::imd_schema("repertoire"))), n = n()) + } else { + genes <- receptors |> + summarise(.by = all_of(c(gene_col, immundata::imd_schema("repertoire"))), n = sum(!!rlang::sym(immundata::imd_schema("count")))) + } + + genes |> + arrange(!!rlang::sym(immundata::imd_schema("repertoire")), desc(n)) |> + collect() +} + +#' @description `airr_stats_genes` — count V(D)J gene segments per repertoire, +#' optionally split by locus and using either receptor counts or barcode/UMI +#' counts as the measure. WHY USEFUL / APPLICATION? +#' +#' @param gene_col A single column name in `idata$annotations` with gene segment +#' calls (e.g., `"v_call"`, `"d_call"`, `"j_call"`, `"c_call"`). Default is +#' `"v_call"`. +#' @param level One of `"receptor"` or `"barcode"`. If `"receptor"` (default), +#' the function counts **unique receptors** (one per receptor ID) that carry +#' a given gene segment. If `"barcode"`, the function **sums counts** (e.g., +#' cells/UMIs) per gene segment using the column defined by +#' `immundata::imd_schema("count")`. +#' @param by Either `NULL` (no split) or `"locus"`. When `"locus"`, the result +#' is further split by the locus column if present (as given by +#' `immundata::imd_schema("locus")`); otherwise a warning is emitted and the +#' split is ignored. +#' +#' @return +#' +#' ## `airr_stats_genes` +#' A tibble with columns: +#' * `repertoire_id` — repertoire identifier +#' * *(optional)* `locus` — TRA, TRB, IGH … (present only when `by = "locus"` +#' and the locus column exists) +#' * `` — the gene segment value (e.g., V gene) +#' * `n` — the measure: +#' - if `level = "receptor"`: number of receptors carrying the gene segment +#' - if `level = "barcode"`: sum of counts across receptors for the segment +#' +#' @examples +#' # +#' # airr_stats_genes +#' # +#' # V gene usage by receptor count +#' airr_stats_genes(immdata, gene_col = "v_call", level = "receptor") +#' +#' # V gene usage by summed cell/UMI counts (if a count column is present) +#' airr_stats_genes(immdata, gene_col = "v_call", level = "barcode") +#' +#' # Split by locus (TRA/TRB/… if locus column exists) +#' airr_stats_genes(immdata, gene_col = "v_call", level = "receptor", by = "locus") +#' +#' @rdname airr_stats +#' @concept Key AIRR statistics +#' @export +airr_stats_genes <- register_immunarch_method(airr_stats_genes_impl, "airr_stats", "genes") diff --git a/man/airr_stats.Rd b/man/airr_stats.Rd new file mode 100644 index 00000000..fd3db029 --- /dev/null +++ b/man/airr_stats.Rd @@ -0,0 +1,150 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/v1_airr_stats.R +\name{airr_stats} +\alias{airr_stats} +\alias{airr_stats_chains} +\alias{airr_stats_lengths} +\alias{airr_stats_genes} +\title{Compute key immune repertoire statistics} +\usage{ +airr_stats_chains( + idata, + locus_col = NA, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_stats_lengths( + idata, + seq_col = "cdr3_aa", + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_stats_genes( + idata, + gene_col = "v_call", + level = c("receptor", "barcode"), + by = c(NA, "locus"), + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) +} +\arguments{ +\item{idata}{An \code{ImmunData} object.} + +\item{locus_col}{Column in \code{idata$annotations} that stores the locus (e.g. \code{"locus"}). If \code{NULL} or missing, the result is not split by locus.} + +\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. +For \code{format="analysis"}, metadata is joined to the long table; for +\code{format="ml"}, it’s joined after pivoting to wide. Defaults to +\code{getOption("immundata.autojoin", FALSE)}.} + +\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet +columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} + +\item{features}{Character vector of \strong{feature keys} to keep when +\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key +looks like \verb{family.method|facet1=...;facet2=...} (e.g., +\code{airr_stats.genes|v_call=TRBV7-2}).} + +\item{seq_col}{Character vector with names of the columns containing sequences.} + +\item{gene_col}{A single column name in \code{idata$annotations} with gene segment +calls (e.g., \code{"v_call"}, \code{"d_call"}, \code{"j_call"}, \code{"c_call"}). Default is +\code{"v_call"}.} + +\item{level}{One of \code{"receptor"} or \code{"barcode"}. If \code{"receptor"} (default), +the function counts \strong{unique receptors} (one per receptor ID) that carry +a given gene segment. If \code{"barcode"}, the function \strong{sums counts} (e.g., +cells/UMIs) per gene segment using the column defined by +\code{immundata::imd_schema("count")}.} + +\item{by}{Either \code{NULL} (no split) or \code{"locus"}. When \code{"locus"}, the result +is further split by the locus column if present (as given by +\code{immundata::imd_schema("locus")}); otherwise a warning is emitted and the +split is ignored.} +} +\value{ +\subsection{\code{airr_stats_chains}}{ + +Returns a tibble with columns: +\itemize{ +\item \code{repertoire_id} -- repertoire identifier +\item \code{locus} -- TRA, TRB, IGH … (present only if \code{locus_col} is supplied) +\item \code{n_chains} -- number of chains +} +} + +\subsection{\code{airr_stats_lengths}}{ + +Returns a tibble with columns: +\itemize{ +\item \code{repertoire_id} -- repertoire identifier +\item \code{seq_len} -- lengths of sequences +\item \code{n} -- number of receptors +} +} + +\subsection{\code{airr_stats_genes}}{ + +A tibble with columns: +\itemize{ +\item \code{repertoire_id} — repertoire identifier +\item \emph{(optional)} \code{locus} — TRA, TRB, IGH … (present only when \code{by = "locus"} +and the locus column exists) +\item \verb{} — the gene segment value (e.g., V gene) +\item \code{n} — the measure: +\itemize{ +\item if \code{level = "receptor"}: number of receptors carrying the gene segment +\item if \code{level = "barcode"}: sum of counts across receptors for the segment +} +} +} +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A family of functions that extract \strong{core descriptive statistics} from an \code{ImmunData} object. +\subsection{Available functions:}{ +} + +\code{airr_stats_chains} --- count V(D)J \emph{chains} per repertoire (optionally split by locus). WHY USEFUL / APPLICATION? + +\code{airr_stats_lengths} --- count the number of sequence lengths per repertoire. WHY USEFUL / APPLICATION? + +\code{airr_stats_genes} — count V(D)J gene segments per repertoire, +optionally split by locus and using either receptor counts or barcode/UMI +counts as the measure. WHY USEFUL / APPLICATION? +} +\examples{ +# +# airr_stats_chains +# +airr_stats_chains(immdata) + +# +# airr_stats_lengths +# +airr_stats_lengths(immdata) + +# +# airr_stats_genes +# +# V gene usage by receptor count +airr_stats_genes(immdata, gene_col = "v_call", level = "receptor") + +# V gene usage by summed cell/UMI counts (if a count column is present) +airr_stats_genes(immdata, gene_col = "v_call", level = "barcode") + +# Split by locus (TRA/TRB/… if locus column exists) +airr_stats_genes(immdata, gene_col = "v_call", level = "receptor", by = "locus") + +} +\seealso{ +\link[immundata:ImmunData]{immundata::ImmunData} +} +\concept{Key AIRR statistics} From 9ee4351d51ca83b37d81b79a296c93e8d612cd70 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:20:51 +0200 Subject: [PATCH 09/36] feat: airr_diversity --- R/v1_airr_diversity.R | 250 ++++++++++++++++++++++++++++++++++++++++++ man/airr_diversity.Rd | 184 +++++++++++++++++++++++++++++++ 2 files changed, 434 insertions(+) create mode 100644 R/v1_airr_diversity.R create mode 100644 man/airr_diversity.Rd diff --git a/R/v1_airr_diversity.R b/R/v1_airr_diversity.R new file mode 100644 index 00000000..a499b331 --- /dev/null +++ b/R/v1_airr_diversity.R @@ -0,0 +1,250 @@ +#' @title Diversity — estimating the heterogeneity of immune repertoires +#' +#' @description +#' `r lifecycle::badge("experimental")` +#' +#' A family of functions to quantify **receptor diversity** per repertoire. +#' +#' ## Available functions: +#' +#' @param idata An `ImmunData` object. +#' @inheritParams airr_diversity_dxx +#' @inheritParams airr_diversity_shannon +#' @inheritParams airr_diversity_pielou +#' @inheritParams airr_diversity_hill +#' @inheritParams airr_diversity_index +#' @inheritParams im_common_args +#' +#' @seealso [immundata::ImmunData] +#' +#' @name airr_diversity +#' @concept Diversity +NULL + + +#' @keywords internal +airr_diversity_dxx_impl <- function(idata, perc = 50) { + checkmate::assert_numeric(perc, null.ok = TRUE) +} + + +#' @description `airr_diversity_dxx` — **coverage diversity**: minimal number of +#' top receptors needed to reach `perc%` of clonal space (by `proportion`). +#' Great for spotting dominance/overexpansion and for quick, interpretable dashboards +#' (e.g., D50 = receptors to cover half of the repertoire). +#' +#' @param perc A number or numeric vector in `(0, 100]` (default `50`), e.g. +#' `50` for D50, `20` for D20. +#' +#' @return +#' +#' ## `airr_diversity_dxx` +#' A tibble with: +#' * `repertoire_id` +#' * `perc` +#' * `dxx` — minimal count of top receptors to reach `perc%` +#' * plus repertoire metadata from `idata$repertoires` +#' +#' @examples +#' # +#' # airr_diversity_dxx +#' # +#' d50 <- airr_diversity_dxx(immdata, perc = 50) +#' d_multi <- airr_diversity_dxx(immdata, perc = c(20, 50, 80)) +#' +#' @rdname airr_diversity +#' @concept Diversity +#' @export +airr_diversity_dxx <- register_immunarch_method(airr_diversity_dxx_impl, "airr_diversity", "dxx") + + +#' @keywords internal +airr_diversity_shannon_impl <- function(idata) { + idata$annotations |> + select( + !!immundata::imd_schema_sym("receptor"), + !!immundata::imd_schema_sym("repertoire"), + !!immundata::imd_schema_sym("proportion") + ) |> + distinct(!!immundata::imd_schema_sym("receptor"), + !!immundata::imd_schema_sym("repertoire"), + .keep_all = TRUE + ) |> + summarise( + .by = !!immundata::imd_schema_sym("repertoire"), + shannon = -sum(!!immundata::imd_schema_sym("proportion") * dd$log2(!!immundata::imd_schema_sym("proportion"))) + ) +} + + +#' @description `airr_diversity_shannon` — Shannon entropy (base 2) per repertoire +#' computed from `proportion`. Ideal when you want a single evenness-aware +#' diversity score; pair with Pielou/Hill for samples with very different richness. +#' +#' @return +#' +#' ## `airr_diversity_shannon` +#' A tibble with: +#' * `repertoire_id` +#' * `shannon` — entropy in bits +#' +#' @examples +#' # +#' # airr_diversity_shannon +#' # +#' sh <- airr_diversity_shannon(immdata) +#' +#' @rdname airr_diversity +#' @concept Diversity +#' @export +airr_diversity_shannon <- register_immunarch_method(airr_diversity_shannon_impl, "airr_diversity", "shannon") + + +#' @keywords internal +airr_diversity_pielou_impl <- function(idata) { + shannon_values <- airr_diversity_shannon(idata) + + idata$repertoires |> + left_join(shannon_values, + by = imd_schema("repertoire") + ) |> + mutate(richness = dd$log2(!!immundata::imd_schema_sym("n_receptors")), pielou = shannon / richness) +} + + +#' @description `airr_diversity_pielou` — Pielou’s evenness `H / log2(S)` with +#' richness `S`. Best when you need a **size-normalized** evenness score that’s +#' comparable across repertoires with different receptor counts. +#' +#' @return +#' +#' ## `airr_diversity_pielou` +#' A tibble with: +#' * `repertoire_id` +#' * `shannon` +#' * `n_receptors` +#' * `pielou` — evenness in `[0, 1]` (NA if `S ≤ 1`) +#' +#' @examples +#' # +#' # airr_diversity_pielou +#' # +#' pj <- airr_diversity_pielou(immdata) +#' +#' @rdname airr_diversity +#' @concept Diversity +#' @export +airr_diversity_pielou <- register_immunarch_method(airr_diversity_pielou_impl, "airr_diversity", "pielou") + + +#' @keywords internal +airr_diversity_index_impl <- function(idata) { + airr_diversity_hill(idata, q = 1) +} + + +#' @description `airr_diversity_index` — convenience alias for Hill number with +#' `q = 1` (`exp(Shannon)` using natural log). A solid **default single metric** +#' that’s relatively robust to rare-count noise and easy to compare across samples. +#' +#' @return +#' +#' ## `airr_diversity_index` +#' A tibble with: +#' * `repertoire_id` +#' * `q = 1` +#' * `hill_number` +#' * plus repertoire metadata from `idata$repertoires` +#' +#' @examples +#' # +#' # airr_diversity_index +#' # +#' idx <- airr_diversity_index(immdata) +#' +#' @rdname airr_diversity +#' @concept Diversity +#' @export +airr_diversity_index <- register_immunarch_method(airr_diversity_index_impl, "airr_diversity", "index") + + +#' @keywords internal +airr_diversity_hill_impl <- function(idata, q = 0:5) { + checkmate::check_numeric(q, lower = 0, sorted = TRUE) + + receptors <- idata$annotations |> + select( + !!immundata::imd_schema_sym("receptor"), + !!immundata::imd_schema_sym("repertoire"), + !!immundata::imd_schema_sym("proportion") + ) |> + distinct(!!immundata::imd_schema_sym("receptor"), + !!immundata::imd_schema_sym("repertoire"), + .keep_all = TRUE + ) + + result <- NULL + + # TODO: Join by value of q-s and run? if_else in case of different q-s + for (q_val in q) { + if (q_val == 0) { + q_val_tbl <- idata$repertoires |> + summarise( + .by = !!immundata::imd_schema_sym("repertoire"), + q = 0, + hill_number = as.numeric(!!immundata::imd_schema_sym("n_receptors")) + ) + } else if (q_val == 1) { + q_val_tbl <- receptors |> + summarise( + .by = !!immundata::imd_schema_sym("repertoire"), + q = q_val, + hill_number = dd$exp(-sum(!!immundata::imd_schema_sym("proportion") * dd$ln(!!immundata::imd_schema_sym("proportion")))) + ) + } else { + q_val_tbl <- receptors |> + summarise( + .by = !!immundata::imd_schema_sym("repertoire"), + q = q_val, + hill_number = dd$pow(sum(dd$pow(!!immundata::imd_schema_sym("proportion"), q_val)), 1 / (1 - q_val)) + ) + } + + if (is.null(result)) { + result <- q_val_tbl + } else { + result <- result |> union_all(q_val_tbl) + } + } + + idata$repertoires |> left_join(result, by = imd_schema("repertoire")) +} + + +#' @description `airr_diversity_hill` — Hill numbers (“true diversity”) for +#' orders `q ∈ {0, 1, 2, …}`: `q=0` richness, `q=1` exp(Shannon), `q>1` +#' emphasizes abundant receptors. Perfect when you want a **diversity profile** +#' that tunes sensitivity to rare vs. abundant clonotypes. +#' +#' @inheritParams im_common_args +#' @param q A scalar or vector of non-negative orders. Defaults to `0:5`. +#' +#' @return +#' +#' ## `airr_diversity_hill` +#' A tibble with: +#' * `repertoire_id` +#' * `q` — Hill order +#' * `hill_number` — true diversity of order `q` +#' * plus repertoire metadata from `idata$repertoires` +#' +#' @examples +#' # +#' # airr_diversity_hill +#' # +#' hill <- airr_diversity_hill(immdata, q = c(0, 1, 2)) +#' +#' @rdname airr_diversity +#' @concept Diversity +#' @export +airr_diversity_hill <- register_immunarch_method(airr_diversity_hill_impl, "airr_diversity", "hill") diff --git a/man/airr_diversity.Rd b/man/airr_diversity.Rd new file mode 100644 index 00000000..84c7fa63 --- /dev/null +++ b/man/airr_diversity.Rd @@ -0,0 +1,184 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/v1_airr_diversity.R +\name{airr_diversity} +\alias{airr_diversity} +\alias{airr_diversity_dxx} +\alias{airr_diversity_shannon} +\alias{airr_diversity_pielou} +\alias{airr_diversity_index} +\alias{airr_diversity_hill} +\title{Diversity — estimating the heterogeneity of immune repertoires} +\usage{ +airr_diversity_dxx( + idata, + perc = 50, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_diversity_shannon( + idata, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_diversity_pielou( + idata, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_diversity_index( + idata, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_diversity_hill( + idata, + q = 0:5, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) +} +\arguments{ +\item{idata}{An \code{ImmunData} object.} + +\item{perc}{A number or numeric vector in \verb{(0, 100]} (default \code{50}), e.g. +\code{50} for D50, \code{20} for D20.} + +\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. +For \code{format="analysis"}, metadata is joined to the long table; for +\code{format="ml"}, it’s joined after pivoting to wide. Defaults to +\code{getOption("immundata.autojoin", FALSE)}.} + +\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet +columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} + +\item{features}{Character vector of \strong{feature keys} to keep when +\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key +looks like \verb{family.method|facet1=...;facet2=...} (e.g., +\code{airr_stats.genes|v_call=TRBV7-2}).} + +\item{q}{A scalar or vector of non-negative orders. Defaults to \code{0:5}.} +} +\value{ +\subsection{\code{airr_diversity_dxx}}{ + +A tibble with: +\itemize{ +\item \code{repertoire_id} +\item \code{perc} +\item \code{dxx} — minimal count of top receptors to reach \verb{perc\%} +\item plus repertoire metadata from \code{idata$repertoires} +} +} + +\subsection{\code{airr_diversity_shannon}}{ + +A tibble with: +\itemize{ +\item \code{repertoire_id} +\item \code{shannon} — entropy in bits +} +} + +\subsection{\code{airr_diversity_pielou}}{ + +A tibble with: +\itemize{ +\item \code{repertoire_id} +\item \code{shannon} +\item \code{n_receptors} +\item \code{pielou} — evenness in \verb{[0, 1]} (NA if \verb{S ≤ 1}) +} +} + +\subsection{\code{airr_diversity_index}}{ + +A tibble with: +\itemize{ +\item \code{repertoire_id} +\item \code{q = 1} +\item \code{hill_number} +\item plus repertoire metadata from \code{idata$repertoires} +} +} + +\subsection{\code{airr_diversity_hill}}{ + +A tibble with: +\itemize{ +\item \code{repertoire_id} +\item \code{q} — Hill order +\item \code{hill_number} — true diversity of order \code{q} +\item plus repertoire metadata from \code{idata$repertoires} +} +} +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A family of functions to quantify \strong{receptor diversity} per repertoire. +\subsection{Available functions:}{ +} + +\code{airr_diversity_dxx} — \strong{coverage diversity}: minimal number of +top receptors needed to reach \verb{perc\%} of clonal space (by \code{proportion}). +Great for spotting dominance/overexpansion and for quick, interpretable dashboards +(e.g., D50 = receptors to cover half of the repertoire). + +\code{airr_diversity_shannon} — Shannon entropy (base 2) per repertoire +computed from \code{proportion}. Ideal when you want a single evenness-aware +diversity score; pair with Pielou/Hill for samples with very different richness. + +\code{airr_diversity_pielou} — Pielou’s evenness \code{H / log2(S)} with +richness \code{S}. Best when you need a \strong{size-normalized} evenness score that’s +comparable across repertoires with different receptor counts. + +\code{airr_diversity_index} — convenience alias for Hill number with +\code{q = 1} (\code{exp(Shannon)} using natural log). A solid \strong{default single metric} +that’s relatively robust to rare-count noise and easy to compare across samples. + +\code{airr_diversity_hill} — Hill numbers (“true diversity”) for +orders \verb{q ∈ \{0, 1, 2, …\}}: \code{q=0} richness, \code{q=1} exp(Shannon), \code{q>1} +emphasizes abundant receptors. Perfect when you want a \strong{diversity profile} +that tunes sensitivity to rare vs. abundant clonotypes. +} +\examples{ +# +# airr_diversity_dxx +# +d50 <- airr_diversity_dxx(immdata, perc = 50) +d_multi <- airr_diversity_dxx(immdata, perc = c(20, 50, 80)) + +# +# airr_diversity_shannon +# +sh <- airr_diversity_shannon(immdata) + +# +# airr_diversity_pielou +# +pj <- airr_diversity_pielou(immdata) + +# +# airr_diversity_index +# +idx <- airr_diversity_index(immdata) + +# +# airr_diversity_hill +# +hill <- airr_diversity_hill(immdata, q = c(0, 1, 2)) + +} +\seealso{ +\link[immundata:ImmunData]{immundata::ImmunData} +} +\concept{Diversity} From 100fad1f37635de51ea888c362c6bac265330a01 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:21:20 +0200 Subject: [PATCH 10/36] chore: ignore + remove knitr --- .Rbuildignore | 1 + DESCRIPTION | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.Rbuildignore b/.Rbuildignore index 88bf0c9b..06c1fb56 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -23,3 +23,4 @@ ^.RDataFiles$ ^.idea$ ^cran-comments\.md$ +^vignettes/*_files$ diff --git a/DESCRIPTION b/DESCRIPTION index ae86e30b..36fe9b58 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -88,7 +88,6 @@ Suggests: shiny (>= 1.4.0), shinythemes VignetteBuilder: - knitr quarto Encoding: UTF-8 RoxygenNote: 7.3.2 From 478402f48336699e05527f6d517f9613ed64c2e6 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:21:59 +0200 Subject: [PATCH 11/36] refactor: markdown docs for vis --- R/v0-vis.R | 208 ++++++++++++++++++++++++++--------------------------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/R/v0-vis.R b/R/v0-vis.R index ec621680..d58bb315 100644 --- a/R/v0-vis.R +++ b/R/v0-vis.R @@ -155,13 +155,13 @@ theme_cleveland2 <- function(rotate = TRUE) { #' @importFrom tidyr drop_na #' #' @description Output from every function in immunarch can be visualised with a -#' single function - \code{vis}. The \code{vis} automatically detects +#' single function - `vis`. The `vis` automatically detects #' the type of the data and draws a proper visualisation. For example, output -#' from the \code{repOverlap} function will be identified as repertoire overlap values +#' from the `repOverlap` function will be identified as repertoire overlap values #' and respective visualisation will be chosen without any additional arguments. #' See "Details" for the list of available visualisations. #' -#' @param .data Pass the output from any immunarch analysis tool to \code{vis()}. +#' @param .data Pass the output from any immunarch analysis tool to `vis()`. #' @param ... Any other arguments, see the "Details" section for specific visualisation functions. #' #' @details @@ -169,43 +169,43 @@ theme_cleveland2 <- function(rotate = TRUE) { #' #' Basic analysis: #' -#' - Exploratory analysis results (from \link{repExplore}) - see \link{vis.immunr_exp_vol}; +#' - Exploratory analysis results (from [repExplore]) - see [vis.immunr_exp_vol]; #' -#' - Clonality statistics (from \link{repClonality}) - see \link{vis.immunr_homeo}. +#' - Clonality statistics (from [repClonality]) - see [vis.immunr_homeo]. #' #' Overlaps and public clonotypes: #' -#' - Overlaps (from \link{repOverlap}) using heatmaps, circos plots, polar area plots - see \link{vis.immunr_ov_matrix}; +#' - Overlaps (from [repOverlap]) using heatmaps, circos plots, polar area plots - see [vis.immunr_ov_matrix]; #' -#' - Overlap clustering (from \link{repOverlapAnalysis}) - see \link{vis.immunr_hclust}; +#' - Overlap clustering (from [repOverlapAnalysis]) - see [vis.immunr_hclust]; #' -#' - Repertoire incremental overlaps (from \link{repOverlap}) - see \link{vis.immunr_inc_overlap}; +#' - Repertoire incremental overlaps (from [repOverlap]) - see [vis.immunr_inc_overlap]; #' -#' - Public repertoire abundance (from \link{pubRep}) - vis \link{vis.immunr_public_repertoire}. +#' - Public repertoire abundance (from [pubRep]) - vis [vis.immunr_public_repertoire]. #' #' Gene usage: #' -#' - Gene usage statistics (from \link{geneUsage}) using bar plots, box plots - see \link{vis.immunr_gene_usage}; +#' - Gene usage statistics (from [geneUsage]) using bar plots, box plots - see [vis.immunr_gene_usage]; #' -#' - Gene usage distances (from \link{geneUsageAnalysis}) using heatmaps, circos plots, polar area plots - see \link{vis.immunr_ov_matrix}; +#' - Gene usage distances (from [geneUsageAnalysis]) using heatmaps, circos plots, polar area plots - see [vis.immunr_ov_matrix]; #' -#' - Gene usage clustering (from \link{geneUsageAnalysis}) - see \link{vis.immunr_hclust}. +#' - Gene usage clustering (from [geneUsageAnalysis]) - see [vis.immunr_hclust]. #' #' Diversity estimation: #' -#' - Diversity estimations (from \link{repDiversity}) - see \link{vis.immunr_chao1}. +#' - Diversity estimations (from [repDiversity]) - see [vis.immunr_chao1]. #' #' BCR analysis: #' -#' - Clonal tree (from \link{repClonalFamily}) - see \link{vis.clonal_family} and \link{vis.clonal_family_tree}. +#' - Clonal tree (from [repClonalFamily]) - see [vis.clonal_family] and [vis.clonal_family_tree]. #' #' Advanced analysis: #' -#' - Repertoire dynamics (from \link{trackClonotypes}) - see \link{vis.immunr_dynamics}; +#' - Repertoire dynamics (from [trackClonotypes]) - see [vis.immunr_dynamics]; #' -#' - Sequence logo plots of amino acid distributions (from \link{kmer_profile}) - see \link{vis_seqlogo}; +#' - Sequence logo plots of amino acid distributions (from [kmer_profile]) - see [vis_seqlogo]; #' -#' - Kmers distributions (from \link{getKmers}) - see \link{vis.immunr_kmer_table}; +#' - Kmers distributions (from [getKmers]) - see [vis.immunr_kmer_table]; #' #' - Mutation networks (from mutationNetwork) - Work In Progress on vis.immunr_mutation_network; #' @@ -213,14 +213,14 @@ theme_cleveland2 <- function(rotate = TRUE) { #' #' Additionaly, we provide a wrapper functions for visualisations of common data types: #' -#' - Any data frames or matrices using heatmaps - see \link{vis_heatmap} and \link{vis_heatmap2}; +#' - Any data frames or matrices using heatmaps - see [vis_heatmap] and [vis_heatmap2]; #' -#' - Any data frames or matrices using circos plots - see \link{vis_circos}. +#' - Any data frames or matrices using circos plots - see [vis_circos]. #' #' @return #' A ggplot2, pheatmap or circlize object. #' -#' @seealso \link{fixVis} for precise manipulation of plots. +#' @seealso [fixVis] for precise manipulation of plots. #' #' @examples #' # Load the test data @@ -255,23 +255,23 @@ vis <- function(.data, ...) { #' @description Visualises matrices with overlap values or gene usage distances among samples. #' For details see the links below. #' -#' @param .data Output from \link{repOverlap} or \link{geneUsageAnalysis}. +#' @param .data Output from [repOverlap] or [geneUsageAnalysis]. #' #' @param .plot A string specifying the plot type: #' -#' - "heatmap" for heatmaps using \link{vis_heatmap}; +#' - "heatmap" for heatmaps using [vis_heatmap]; #' -#' - "heatmap2" for heatmaps using \link{vis_heatmap2}; +#' - "heatmap2" for heatmaps using [vis_heatmap2]; #' -#' - "circos" for circos plots using \link{vis_circos}; +#' - "circos" for circos plots using [vis_circos]; #' #' @param ... Other arguments are passed through to the underlying plotting function: #' -#' - "heatmap" - passes arguments to \link{vis_heatmap}; +#' - "heatmap" - passes arguments to [vis_heatmap]; #' -#' - "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; +#' - "heatmap2" - passes arguments to [vis_heatmap2] and [heatmap] from the "pheatmap" package; #' -#' - "circos" - passes arguments to \link{vis_circos} and [circlize::chordDiagram] from the "circlize" package; +#' - "circos" - passes arguments to [vis_circos] and [circlize::chordDiagram] from the "circlize" package; #' #' @return #' A ggplot2, pheatmap or circlize object. @@ -364,7 +364,7 @@ vis.immunr_gu_matrix <- function(.data, .plot = c("heatmap", "heatmap2", "circos #' @return #' A ggplot2 object. #' -#' @seealso \link{vis}, \link{repOverlap}. +#' @seealso [vis], [repOverlap]. #' #' @examples #' data(immdata) @@ -454,7 +454,7 @@ vis_heatmap <- function(.data, .text = TRUE, .scientific = FALSE, .signif.digits #' #' @name vis_heatmap2 #' -#' @description Visualise matrices with the functions based on the \link[pheatmap]{pheatmap} +#' @description Visualise matrices with the functions based on the [pheatmap][pheatmap::pheatmap] #' package with minimum amount of arguments. #' #' @param .data Input matrix. Column names and row names (if presented) will be used as names for labs. @@ -464,17 +464,17 @@ vis_heatmap <- function(.data, .text = TRUE, .scientific = FALSE, .signif.digits #' #' @param .by Set NA if you want to plot samples without grouping. #' -#' @param .title The text for the plot's title (same as the "main" argument in \link[pheatmap]{pheatmap}). +#' @param .title The text for the plot's title (same as the "main" argument in [pheatmap][pheatmap::pheatmap]). #' -#' @param .color A vector specifying the colors (same as the "color" argument in \link[pheatmap]{pheatmap}). +#' @param .color A vector specifying the colors (same as the "color" argument in [pheatmap][pheatmap::pheatmap]). #' Pass NA to use the default pheatmap colors. #' -#' @param ... Other arguments for the \link[pheatmap]{pheatmap} function. +#' @param ... Other arguments for the [pheatmap][pheatmap::pheatmap] function. #' #' @return #' A pheatmap object. #' -#' @seealso \link{vis}, \link{repOverlap} +#' @seealso [vis], [repOverlap] #' #' @examples #' data(immdata) @@ -520,7 +520,7 @@ vis_heatmap2 <- function(.data, .meta = NA, .by = NA, .title = NA, .color = colo #' @return #' A circlize object. #' -#' @seealso \link{vis}, \link{repOverlap}. +#' @seealso [vis], [repOverlap]. #' #' @examples #' data(immdata) @@ -628,7 +628,7 @@ vis_circos <- function(.data, .title = NULL, ...) { #' #' @name vis.immunr_inc_overlap #' -#' @param .data Output from the \link{repOverlap} function that uses "top" methods. +#' @param .data Output from the [repOverlap] function that uses "top" methods. #' #' @param .target Index of a repertoire to plot. Omitted if .grid is TRUE. #' @@ -641,7 +641,7 @@ vis_circos <- function(.data, .title = NULL, ...) { #' @return #' A ggplot2 object. #' -#' @seealso \link{repOverlap} +#' @seealso [repOverlap] #' #' @examples #' data(immdata) @@ -724,15 +724,15 @@ vis.immunr_inc_overlap <- function(.data, .target = 1, .grid = FALSE, .ncol = 2, #' #' @name vis.immunr_public_repertoire #' -#' @param .data Public repertoire, an output from \link{pubRep}. +#' @param .data Public repertoire, an output from [pubRep]. #' @param .plot A string specifying the plot type: #' #' - "freq" for visualisation of the distribution of occurrences of clonotypes -#' and their frequencies using \link{vis_public_frequencies}. +#' and their frequencies using [vis_public_frequencies]. #' #' - "clonotypes" for visualisation of public clonotype frequenciy correlations between pairs of -#' samples using \link{vis_public_clonotypes} -#' @param ... Further arguments passed \link{vis_public_frequencies} or \link{vis_public_clonotypes}, +#' samples using [vis_public_clonotypes] +#' @param ... Further arguments passed [vis_public_frequencies] or [vis_public_clonotypes], #' depending on the ".plot" argument. #' #' @return @@ -767,7 +767,7 @@ vis.immunr_public_repertoire <- function(.data, .plot = c("freq", "clonotypes"), #' #' @description Visualise public clonotype frequencies. #' -#' @param .data Public repertoire - an output from the \link{pubRep} function. +#' @param .data Public repertoire - an output from the [pubRep] function. #' #' @param ... Other arguments passsed directly to [UpSetR::upset]. #' @@ -800,7 +800,7 @@ vis.immunr_public_statistics <- function(.data, ...) { #' #' @description Visualise public clonotype frequencies. #' -#' @param .data Public repertoire - an output from the \link{pubRep} function. +#' @param .data Public repertoire - an output from the [pubRep] function. #' @param .by Pass NA if you want to plot samples without grouping. #' #' You can pass a character vector with one or several column names from ".meta" @@ -896,7 +896,7 @@ vis_public_frequencies <- function(.data, .by = NA, .meta = NA, #' #' @description Visualise correlation of public clonotype frequencies in pairs of repertoires. #' -#' @param .data Public repertoire data - an output from the \link{pubRep} function. +#' @param .data Public repertoire data - an output from the [pubRep] function. #' #' @param .x.rep Either indices of samples or character vector of sample names #' for the x-axis. Must be of the same length as ".y.rep". @@ -925,7 +925,7 @@ vis_public_frequencies <- function(.data, .by = NA, .meta = NA, #' @return #' A ggplot2 object. #' -#' @seealso \link{pubRep}, \link{vis.immunr_public_repertoire} +#' @seealso [pubRep], [vis.immunr_public_repertoire] #' #' @examples #' data(immdata) @@ -1099,29 +1099,29 @@ vis_public_clonotypes <- function(.data, .x.rep = NA, .y.rep = NA, #' #' @description Visualise distributions of genes using heatmaps or other plots. #' -#' @param .data Output from the \link{geneUsage} function. +#' @param .data Output from the [geneUsage] function. #' #' @param .plot String specifying the plot type: #' -#' - "hist" for histograms using \link{vis_hist}; +#' - "hist" for histograms using [vis_hist]; #' -#' - "heatmap" for heatmaps using \link{vis_heatmap}; +#' - "heatmap" for heatmaps using [vis_heatmap]; #' -#' - "heatmap2" for heatmaps using \link{vis_heatmap2}; +#' - "heatmap2" for heatmaps using [vis_heatmap2]; #' -#' - "circos" for circos plots using \link{vis_circos}. +#' - "circos" for circos plots using [vis_circos]. #' #' @param ... Other arguments passed to corresponding functions depending on the plot type: #' -#' - "hist" - passes arguments to \link{vis_hist}; +#' - "hist" - passes arguments to [vis_hist]; #' -#' - "box" - passes arguments to \link{vis_box}; +#' - "box" - passes arguments to [vis_box]; #' -#' - "heatmap" - passes arguments to \link{vis_heatmap}; +#' - "heatmap" - passes arguments to [vis_heatmap]; #' -#' - "heatmap2" - passes arguments to \link{vis_heatmap2} and \link{heatmap} from the "pheatmap" package; +#' - "heatmap2" - passes arguments to [vis_heatmap2] and [heatmap] from the "pheatmap" package; #' -#' - "circos" - passes arguments to \link{vis_circos} and [circlize::chordDiagram] from the "circlize" package. +#' - "circos" - passes arguments to [vis_circos] and [circlize::chordDiagram] from the "circlize" package. #' #' @return #' A ggplot2 object, pheatmap or circlize object. @@ -1135,7 +1135,7 @@ vis_public_clonotypes <- function(.data, .x.rep = NA, .y.rep = NA, #' gu <- geneUsage(immdata$data) #' vis(gu, .by = "Status", .meta = immdata$meta) #' vis(gu, "box", .by = "Status", .meta = immdata$meta) -#' @seealso \link{geneUsage} +#' @seealso [geneUsage] #' #' @export vis.immunr_gene_usage <- function(.data, .plot = c("hist", "box", "heatmap", "heatmap2", "circos"), ...) { @@ -1217,19 +1217,19 @@ vis.immunr_gene_usage <- function(.data, .plot = c("hist", "box", "heatmap", "he #' @param ... Is not used here. #' #' @details -#' If data is grouped, then statistical tests for comparing means of groups will be performed, unless \code{.test = FALSE} is supplied. +#' If data is grouped, then statistical tests for comparing means of groups will be performed, unless `.test = FALSE` is supplied. #' In case there are only two groups, the Wilcoxon rank sum test (https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) is performed -#' (R function \code{\link{wilcox.test}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. -#' In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link{kruskal.test}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. +#' (R function [wilcox.test()] with an argument `exact = FALSE`) for testing if there is a difference in mean rank values between two groups. +#' In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function [kruskal.test()]), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. #' A significant Kruskal-Wallis test indicates that at least one sample stochastically dominates one other sample. #' Adjusted for multiple comparisons P-values are plotted on the top of groups. #' P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm%E2%80%93Bonferroni_method) (also known as Holm-Bonferroni correction). -#' You can execute the command \code{?p.adjust} in the R console to see more. +#' You can execute the command `?p.adjust` in the R console to see more. #' #' @return #' A ggplot2 object. #' -#' @seealso \link{vis.immunr_gene_usage}, \link{geneUsage} +#' @seealso [vis.immunr_gene_usage], [geneUsage] #' #' @examples #' data(immdata) @@ -1402,7 +1402,7 @@ vis_hist <- function(.data, .by = NA, .meta = NA, .title = "Gene usage", .ncol = #' @return #' A ggplot2 object. #' -#' @seealso \link{vis.immunr_gene_usage}, \link{geneUsage} +#' @seealso [vis.immunr_gene_usage], [geneUsage] #' #' @examples #' vis_box(data.frame(Sample = sample(c("A", "B", "C"), 100, TRUE), Value = rnorm(100)), .melt = FALSE) @@ -1546,11 +1546,11 @@ vis_box <- function(.data, .by = NA, .meta = NA, .melt = TRUE, #' #' @description #' Visualisation of the results of hierarchical clustering. -#' For other clustering visualisations see \link{vis.immunr_kmeans}. +#' For other clustering visualisations see [vis.immunr_kmeans]. #' #' @aliases vis.immunr_hclust #' -#' @param .data Clustering results from \link{repOverlapAnalysis} or \link{geneUsageAnalysis}. +#' @param .data Clustering results from [repOverlapAnalysis] or [geneUsageAnalysis]. #' @param .rect Passed to [factoextra::fviz_dend] - whether to add a rectangle around groups. #' @param .plot A character vector of length one or two specifying which plots to visualise. #' If "clust" then plot only the clustering. If "best" then plot the number of optimal clusters. @@ -1560,7 +1560,7 @@ vis_box <- function(.data, .by = NA, .meta = NA, .melt = TRUE, #' @return #' Ggplot2 objects inside the patchwork container. #' -#' @seealso \link{vis}, \link{repOverlapAnalysis}, \link{geneUsageAnalysis} +#' @seealso [vis], [repOverlapAnalysis], [geneUsageAnalysis] #' #' @examples #' data(immdata) @@ -1601,11 +1601,11 @@ vis.immunr_hclust <- function(.data, .rect = FALSE, .plot = c("clust", "best"), #' #' @description #' Visualisation of the results of K-means and DBSCAN clustering. -#' For hierarhical clustering visualisations see \link{vis.immunr_hclust}. +#' For hierarhical clustering visualisations see [vis.immunr_hclust]. #' #' @aliases vis.immunr_kmeans vis.immunr_dbscan #' -#' @param .data Clustering results from \link{repOverlapAnalysis} or \link{geneUsageAnalysis}. +#' @param .data Clustering results from [repOverlapAnalysis] or [geneUsageAnalysis]. #' @param .point If TRUE then plot sample points. Passed to [factoextra::fviz_cluster]. #' @param .text If TRUE then plot text labels. Passed to [factoextra::fviz_cluster]. #' @param .ellipse If TRUE then plot ellipses around all samples. Passed to "ellipse" from [factoextra::fviz_cluster]. @@ -1619,7 +1619,7 @@ vis.immunr_hclust <- function(.data, .rect = FALSE, .plot = c("clust", "best"), #' @return #' Ggplot2 objects inside the pathwork container. #' -#' @seealso \link{vis}, \link{repOverlapAnalysis}, \link{geneUsageAnalysis} +#' @seealso [vis], [repOverlapAnalysis], [geneUsageAnalysis] #' #' @examples #' data(immdata) @@ -1687,8 +1687,8 @@ vis.immunr_dbscan <- function(.data, .point = TRUE, .text = TRUE, .ellipse = TRU #' #' @aliases vis.immunr_mds vis.immunr_pca vis.immunr_tsne #' -#' @param .data Output from analysis functions such as \link{geneUsageAnalysis} or -#' \link{immunr_pca}, \link{immunr_mds} or \link{immunr_tsne}. +#' @param .data Output from analysis functions such as [geneUsageAnalysis] or +#' [immunr_pca], [immunr_mds] or [immunr_tsne]. #' @param .by Pass NA if you want to plot samples without grouping. #' #' You can pass a character vector with one or several column names from ".meta" @@ -1714,11 +1714,11 @@ vis.immunr_dbscan <- function(.data, .point = TRUE, .text = TRUE, .ellipse = TRU #' @details #' Other visualisation methods: #' -#' - PCA - \link{vis.immunr_pca} +#' - PCA - [vis.immunr_pca] #' -#' - MDS - \link{vis.immunr_mds} +#' - MDS - [vis.immunr_mds] #' -#' - tSNE - \link{vis.immunr_tsne} +#' - tSNE - [vis.immunr_tsne] #' #' @examples #' data(immdata) @@ -1900,12 +1900,12 @@ vis_bar_stacked <- function(.data, .by = NA, .meta = NA, #' #' @aliases vis.immunr_clonal_prop vis.immunr_homeo vis.immunr_top_prop vis.immunr_tail_prop #' -#' @description An utility function to visualise the output from \code{\link{repClonality}}. +#' @description An utility function to visualise the output from [repClonality()]. #' #' @importFrom reshape2 melt #' @importFrom scales percent #' -#' @param .data Output from \code{\link{repClonality}}. +#' @param .data Output from [repClonality()]. #' @param .by Pass NA if you want to plot samples without grouping. #' #' You can pass a character vector with one or several column names from ".meta" @@ -1930,19 +1930,19 @@ vis_bar_stacked <- function(.data, .by = NA, .meta = NA, #' @param ... Not used here. #' #' @details -#' If data is grouped, then statistical tests for comparing means of groups will be performed, unless \code{.test = FALSE} is supplied. +#' If data is grouped, then statistical tests for comparing means of groups will be performed, unless `.test = FALSE` is supplied. #' In case there are only two groups, the Wilcoxon rank sum test (https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) is performed -#' (R function \code{\link{wilcox.test}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. -#' In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link{kruskal.test}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. +#' (R function [wilcox.test()] with an argument `exact = FALSE`) for testing if there is a difference in mean rank values between two groups. +#' In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function [kruskal.test()]), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. #' A significant Kruskal-Wallis test indicates that at least one sample stochastically dominates one other sample. #' Adjusted for multiple comparisons P-values are plotted on the top of groups. #' P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm%E2%80%93Bonferroni_method) (also known as Holm-Bonferroni correction). -#' You can execute the command \code{?p.adjust} in the R console to see more. +#' You can execute the command `?p.adjust` in the R console to see more. #' #' @return #' A ggplot2 object. #' -#' @seealso \link{repClonality} \link{vis} +#' @seealso [repClonality] [vis] #' #' @examples #' data(immdata) @@ -2305,11 +2305,11 @@ vis_bar <- function(.data, .by = NA, .meta = NA, .errorbars = c(0.025, 0.975), . #' @concept diversity #' #' @aliases vis.immunr_chao1 vis.immunr_dxx vis.immunr_rarefaction vis.immunr_div vis.immunr_ginisimp vis.immunr_invsimp vis.immunr_hill -#' @description An utility function to visualise the output from \code{\link{repDiversity}}. +#' @description An utility function to visualise the output from [repDiversity()]. #' #' @importFrom reshape2 melt #' -#' @param .data Output from \code{\link{repDiversity}}. +#' @param .data Output from [repDiversity()]. #' @param .by Pass NA if you want to plot samples without grouping. #' #' You can pass a character vector with one or several column names from ".meta" @@ -2331,19 +2331,19 @@ vis_bar <- function(.data, .by = NA, .meta = NA, .errorbars = c(0.025, 0.975), . #' @param ... Not used here. #' #' @details -#' If data is grouped, then statistical tests for comparing means of groups will be performed, unless \code{.test = FALSE} is supplied. +#' If data is grouped, then statistical tests for comparing means of groups will be performed, unless `.test = FALSE` is supplied. #' In case there are only two groups, the Wilcoxon rank sum test (https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) is performed -#' (R function \code{\link{wilcox.test}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. -#' In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link{kruskal.test}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. +#' (R function [wilcox.test()] with an argument `exact = FALSE`) for testing if there is a difference in mean rank values between two groups. +#' In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function [kruskal.test()]), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. #' A significant Kruskal-Wallis test indicates that at least one sample stochastically dominates one other sample. #' Adjusted for multiple comparisons P-values are plotted on the top of groups. #' P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm%E2%80%93Bonferroni_method) (also known as Holm-Bonferroni correction). -#' You can execute the command \code{?p.adjust} in the R console to see more. +#' You can execute the command `?p.adjust` in the R console to see more. #' #' @return #' A ggplot2 object. #' -#' @seealso \link{repDiversity} \link{vis} +#' @seealso [repDiversity] [vis] #' #' @examples #' data(immdata) @@ -2569,11 +2569,11 @@ vis.immunr_rarefaction <- function(.data, .by = NA, .meta = NA, #' @concept explore #' #' @aliases vis.immunr_exp_vol vis.immunr_exp_count vis.immunr_exp_len vis.immunr_exp_clones -#' @description An utility function to visualise the output from \code{\link{repExplore}}. +#' @description An utility function to visualise the output from [repExplore()]. #' #' @importFrom reshape2 melt #' -#' @param .data Output from \code{\link{repExplore}}. +#' @param .data Output from [repExplore()]. #' @param .by Pass NA if you want to plot samples without grouping. #' #' You can pass a character vector with one or several column names from ".meta" @@ -2598,19 +2598,19 @@ vis.immunr_rarefaction <- function(.data, .by = NA, .meta = NA, #' @param ... Not used here. #' #' @details -#' If data is grouped, then statistical tests for comparing means of groups will be performed, unless \code{.test = FALSE} is supplied. +#' If data is grouped, then statistical tests for comparing means of groups will be performed, unless `.test = FALSE` is supplied. #' In case there are only two groups, the Wilcoxon rank sum test (https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test) is performed -#' (R function \code{\link{wilcox.test}} with an argument \code{exact = FALSE}) for testing if there is a difference in mean rank values between two groups. -#' In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function \code{\link{kruskal.test}}), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. +#' (R function [wilcox.test()] with an argument `exact = FALSE`) for testing if there is a difference in mean rank values between two groups. +#' In case there more than two groups, the Kruskal-Wallis test (https://en.wikipedia.org/wiki/Kruskal%E2%80%93Wallis_one-way_analysis_of_variance) is performed (R function [kruskal.test()]), that is equivalent to ANOVA for ranks and it tests whether samples from different groups originated from the same distribution. #' A significant Kruskal-Wallis test indicates that at least one sample stochastically dominates one other sample. #' Adjusted for multiple comparisons P-values are plotted on the top of groups. #' P-value adjusting is done using the Holm method (https://en.wikipedia.org/wiki/Holm%E2%80%93Bonferroni_method) (also known as Holm-Bonferroni correction). -#' You can execute the command \code{?p.adjust} in the R console to see more. +#' You can execute the command `?p.adjust` in the R console to see more. #' #' @return #' A ggplot2 object. #' -#' @seealso \link{repExplore} \link{vis} +#' @seealso [repExplore] [vis] #' #' @examples #' data(immdata) @@ -2718,14 +2718,14 @@ vis.immunr_exp_clones <- function(.data, .by = NA, .meta = NA, #' #' @param .data Data frame with two columns "Kmers" and "Count" or a list with such data frames. See Examples. #' @param .head Number of the most frequent kmers to choose for plotting from each data frame. -#' @param .position Character vector of length 1. Position of bars for each kmers. Value for the \code{ggplot2} argument \code{position}. +#' @param .position Character vector of length 1. Position of bars for each kmers. Value for the `ggplot2` argument `position`. #' @param .log Logical. If TRUE then plot log-scaled plots. #' @param ... Not used here. #' #' @return #' A ggplot2 object. #' -#' @seealso \code{get.kmers} +#' @seealso `get.kmers` #' #' @examples #' # Load necessary data and package. @@ -2799,7 +2799,7 @@ vis.immunr_kmer_table <- function(.data, .head = 100, .position = c("stack", "do #' `vis_seqlogo` is a traditional sequence logo plots. Useful when there are one or two amino acids #' with clear differences in their occurrences. #' -#' @param .data Output from the \code{kmer.profile} function. +#' @param .data Output from the `kmer.profile` function. #' @param .replace.zero.with.na if TRUE then replace all zeros with NAs, therefore letters with #' zero frequency wont appear at the plot. #' @param .scheme Character. An argument passed to [ggseqlogo::geom_logo] specifying how to colour symbols. @@ -2810,7 +2810,7 @@ vis.immunr_kmer_table <- function(.data, .head = 100, .position = c("stack", "do #' @return #' A ggplot2 object. #' -#' @seealso \link{getKmers}, \link{kmer_profile} +#' @seealso [getKmers], [kmer_profile] #' #' @examples #' data(immdata) @@ -2855,13 +2855,13 @@ vis_seqlogo <- function(.data, .scheme = "chemistry", ...) { #' #' @concept kmers #' -#' @param .data Kmer data, an output from \link{kmer_profile}. +#' @param .data Kmer data, an output from [kmer_profile]. #' @param .plot String specifying the plot type: #' -#' - "seqlogo" for traditional sequence logo plots using \link{vis_seqlogo}; +#' - "seqlogo" for traditional sequence logo plots using [vis_seqlogo]; #' -#' - "textlogo" for modified approach to sequence logo plots via text labels using \link{vis_textlogo}; -#' @param ... Other arguments passed to \link{vis_textlogo} or \link{vis_seqlogo}, depending +#' - "textlogo" for modified approach to sequence logo plots via text labels using [vis_textlogo]; +#' @param ... Other arguments passed to [vis_textlogo] or [vis_seqlogo], depending #' on the ".plot" argument. #' #' @return @@ -2923,7 +2923,7 @@ vis.immunr_kmer_profile_self <- function(.data, .plot = c("textlogo", "seqlogo") #' #' @name vis.immunr_dynamics #' -#' @param .data Output from the \link{trackClonotypes} function. +#' @param .data Output from the [trackClonotypes] function. #' @param .plot Character. Either "smooth", "area" or "line". Each specifies a type of plot for visualisation of clonotype dynamics. #' @param .order Numeric or character vector. Specifies the order to samples, e.g., it used for ordering samples #' by timepoints. Either See "Examples" below for more details. @@ -3049,7 +3049,7 @@ vis.immunr_dynamics <- function(.data, .plot = c("smooth", "area", "line"), .ord #' #' @concept phylip #' -#' @param .data Clonal families from 1 or multiple samples: \code{\link{repClonalFamily}} output. +#' @param .data Clonal families from 1 or multiple samples: [repClonalFamily()] output. #' @param ... Not used here. #' #' @return @@ -3095,7 +3095,7 @@ vis.clonal_family <- function(.data, ...) { #' #' @concept phylip #' -#' @param .data Single clonal family tree data from 1 cluster: 1 element from TreeStats column from \code{\link{repClonalFamily}} output. +#' @param .data Single clonal family tree data from 1 cluster: 1 element from TreeStats column from [repClonalFamily()] output. #' @param ... Not used here. #' #' @return From d1fcf690dd7e53e541acccc05693a3b32947efbb Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:22:09 +0200 Subject: [PATCH 12/36] refactor: markdown docs for tools --- R/tools.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/tools.R b/R/tools.R index 383d0818..63477193 100644 --- a/R/tools.R +++ b/R/tools.R @@ -73,7 +73,7 @@ check_distribution <- function(.data, .do.norm = NA, .laplace = 1, .na.val = 0, #' @param .class String with the desired class name. #' #' @return -#' Input object with additional class \code{.class}. +#' Input object with additional class `.class`. #' #' @section Developer Examples: #' tmp <- "abc" @@ -125,7 +125,7 @@ get_empty_object_with_class <- function(.class) { #' add_pb(.pb, .value = 1) #' #' @param .max Integer. Maximal value of the progress bar. -#' @param .pb Progress bar object from \code{set_pb}. +#' @param .pb Progress bar object from `set_pb`. #' @param .value Numeric. Value to add to the progress bar at each step. #' #' @return @@ -276,7 +276,7 @@ check_group_names <- function(.meta, .by) { #' #' @param .by Character vector. Specify a column or columns in the input metadata to group by. #' @param .metadata Metadata object. -#' @param .sep Character vector. Defines a separator between groups if more than one group passed in \code{.by}. +#' @param .sep Character vector. Defines a separator between groups if more than one group passed in `.by`. #' #' @return #' Character vector with group names. From 79ec9ea9f7c1b2077f7cfa742d14ba7c4f6fcd23 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:22:45 +0200 Subject: [PATCH 13/36] chore: remove old files --- R/immunarch-remaster.R | 25 -------- vignettes/immunarch_v1_migration.Rmd | 91 ---------------------------- 2 files changed, 116 deletions(-) delete mode 100644 R/immunarch-remaster.R delete mode 100644 vignettes/immunarch_v1_migration.Rmd diff --git a/R/immunarch-remaster.R b/R/immunarch-remaster.R deleted file mode 100644 index 27bb962c..00000000 --- a/R/immunarch-remaster.R +++ /dev/null @@ -1,25 +0,0 @@ -# .check_immundata <- function (.object) { -# if (!is.instance(.object, "ImmunData")) { -# stop("Error: the input object is not of class ImmunData. Immunarch works on ImmunData only. Helpful manual: ...") -# } -# } -# -# .repertoire_overlap <- function (.data, .method, .verbose = TRUE, ...) { -# check_immundata(.data) -# } -# -# .gene_usage <- function (.data, .gene, .type, .use_counts, .norm, .gene_vec) { -# -# } -# -# .repertoire_diversity <- function (.data, .method, .verbose = TRUE, ...) { -# -# } -# -# .track_clonotypes <- function () { -# -# } -# -# .public_repertoire <- function () { -# -# } diff --git a/vignettes/immunarch_v1_migration.Rmd b/vignettes/immunarch_v1_migration.Rmd deleted file mode 100644 index a9067515..00000000 --- a/vignettes/immunarch_v1_migration.Rmd +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: "Immunarch 0.9.x -> 1.0.0 Migration Guide" -date: "support@immunomind.com" -output: - html_document: - fig_height: 8 - fig_width: 10 - theme: spacelab - toc: yes - pdf_document: - toc: yes - word_document: - toc: yes ---- - - - - -# Overview - -There are three major points related to transformations: - -- how immunarch 1.0.0 works with data, -- interface or API, i.e., names and parameters of the functions, implemented in immunarch, and -- removing or moving some functions to separate package to make immunarch easier to install and manage - -For more long-term plans take a look at the final sections. - -For the nearest changes, please continue reading. - - -# Major update for the current version: Spring 2025 - -## What changed and what you can do - -removed ggpubr, factoextra, fpc, ggraph, phangorn, igraph and some other packages -Sadly I didn't have a chance to do it gradually due to the CRAN requirements. -The good news is that immunarch now needs *only* around 80 packages to install instead of 184 before. - -If you have been using immunarch for some time, there won't be anything changing for you. - -If you want to re-install immunarch, you may encounter errors that asks you to install some of the packages. Just install it, and the function will work - nothing else was changed. - - -# Next major update: Summer 2025 - -## What will be changed - -## What can you do to mitigate risks - - -# Future major updates: Autumn-Winter 2025 - -## What will be changed - -## What can you do to mitigate risks - - -# How immunarch 1.0.0. would look like - -Why do we need even need it? - -- outdated code, hard to support and maintain -- imrpoving the code culture in academia - -## Scalable and fast data processing - -## Lighter interface - -## Modularizing the ecosystem - - - -```{r setup, include=FALSE, echo=FALSE} -# knitr::knit_hooks$set(optipng = knitr::hook_optipng) -# knitr::opts_chunk$set(optipng = '-o7') - -knitr::opts_chunk$set(echo = TRUE) -knitr::opts_chunk$set(fig.align = "center") -knitr::opts_chunk$set(fig.width = 12) -knitr::opts_chunk$set(fig.height = 6) - -library(immunarch) -# source("../R/testing.R") -# immdata = load_test_data() -data(immdata) -``` From e24d1eb7e9f0f4739f9d0416fc2fd681ae7f5ae0 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:26:00 +0200 Subject: [PATCH 14/36] refactor: module-like structure for the package --- R/{align_lineage.R => v0_align_lineage.R} | 3 +- R/{annotation.R => v0_annotation.R} | 2 +- R/{clonality.R => v0_clonality.R} | 0 R/{clustering.R => v0_clustering.R} | 0 R/{data_docs.R => v0_data_docs.R} | 0 R/{dimensions.R => v0_dimensions.R} | 20 +- R/{distance.R => v0_distance.R} | 3 +- R/{diversity.R => v0_diversity.R} | 0 R/{dynamics.R => v0_dynamics.R} | 0 R/{explore.R => v0_explore.R} | 0 R/{filters.R => v0_filters.R} | 0 R/{gene_usage.R => v0_gene_usage.R} | 4 +- ...ge_analysis.R => v0_gene_usage_analysis.R} | 0 R/{germline.R => v0_germline.R} | 1 - ..._data_format.R => v0_immunr_data_format.R} | 0 R/{info_theory.R => v0_info_theory.R} | 0 R/{io.R => v0_io.R} | 5 +- R/{io-parsers.R => v0_io_parsers.R} | 43 ---- R/{io-savers.R => v0_io_savers.R} | 0 R/{io-utility.R => v0_io_utility.R} | 0 R/{kmers.R => v0_kmers.R} | 0 R/{overlap.R => v0_overlap.R} | 0 ...erlap_analysis.R => v0_overlap_analysis.R} | 0 R/{phylip.R => v0_phylip.R} | 10 +- R/{preprocessing.R => v0_preprocessing.R} | 2 +- R/{public.R => v0_public.R} | 9 +- R/{sampling.R => v0_sampling.R} | 3 + R/{seqCluster.R => v0_seqCluster.R} | 4 +- R/{shiny.R => v0_shiny.R} | 6 +- R/{singlecell.R => v0_singlecell.R} | 0 ...rmutation.R => v0_somatic_hypermutation.R} | 0 R/{spectratyping.R => v0_spectratyping.R} | 0 R/{tools.R => v0_tools.R} | 8 +- R/{v0-vis.R => v0_vis.R} | 232 ++++++++++++++---- 34 files changed, 228 insertions(+), 127 deletions(-) rename R/{align_lineage.R => v0_align_lineage.R} (99%) rename R/{annotation.R => v0_annotation.R} (99%) rename R/{clonality.R => v0_clonality.R} (100%) rename R/{clustering.R => v0_clustering.R} (100%) rename R/{data_docs.R => v0_data_docs.R} (100%) rename R/{dimensions.R => v0_dimensions.R} (85%) rename R/{distance.R => v0_distance.R} (98%) rename R/{diversity.R => v0_diversity.R} (100%) rename R/{dynamics.R => v0_dynamics.R} (100%) rename R/{explore.R => v0_explore.R} (100%) rename R/{filters.R => v0_filters.R} (100%) rename R/{gene_usage.R => v0_gene_usage.R} (99%) rename R/{gene_usage_analysis.R => v0_gene_usage_analysis.R} (100%) rename R/{germline.R => v0_germline.R} (99%) rename R/{immunr_data_format.R => v0_immunr_data_format.R} (100%) rename R/{info_theory.R => v0_info_theory.R} (100%) rename R/{io.R => v0_io.R} (99%) rename R/{io-parsers.R => v0_io_parsers.R} (97%) rename R/{io-savers.R => v0_io_savers.R} (100%) rename R/{io-utility.R => v0_io_utility.R} (100%) rename R/{kmers.R => v0_kmers.R} (100%) rename R/{overlap.R => v0_overlap.R} (100%) rename R/{overlap_analysis.R => v0_overlap_analysis.R} (100%) rename R/{phylip.R => v0_phylip.R} (98%) rename R/{preprocessing.R => v0_preprocessing.R} (98%) rename R/{public.R => v0_public.R} (98%) rename R/{sampling.R => v0_sampling.R} (99%) rename R/{seqCluster.R => v0_seqCluster.R} (98%) rename R/{shiny.R => v0_shiny.R} (99%) rename R/{singlecell.R => v0_singlecell.R} (100%) rename R/{somatic_hypermutation.R => v0_somatic_hypermutation.R} (100%) rename R/{spectratyping.R => v0_spectratyping.R} (100%) rename R/{tools.R => v0_tools.R} (98%) rename R/{v0-vis.R => v0_vis.R} (96%) diff --git a/R/align_lineage.R b/R/v0_align_lineage.R similarity index 99% rename from R/align_lineage.R rename to R/v0_align_lineage.R index cbc25187..27bd1293 100644 --- a/R/align_lineage.R +++ b/R/v0_align_lineage.R @@ -7,7 +7,6 @@ #' @importFrom magrittr %>% %<>% extract2 #' @importFrom stringr str_extract_all str_sub str_length boundary #' @importFrom plyr dlply . -#' @importFrom purrr map_dfr #' @importFrom rlist list.remove #' @importFrom ape as.DNAbin clustal #' @importFrom doParallel registerDoParallel stopImplicitCluster @@ -202,7 +201,7 @@ convert_results_to_df <- function(nested_results_list, alignments_list) { tibble(Sequences = .) df <- nested_results_list %>% lapply(rlist::list.remove, c("Alignment", "Sequences")) %>% - purrr::map_dfr(~.) %>% + map_dfr(~.) %>% cbind(alignments, sequences) return(df) } diff --git a/R/annotation.R b/R/v0_annotation.R similarity index 99% rename from R/annotation.R rename to R/v0_annotation.R index 3a57a4b5..99170735 100644 --- a/R/annotation.R +++ b/R/v0_annotation.R @@ -123,7 +123,7 @@ dbLoad <- function(.path, .db, .species = NA, .chain = NA, .pathology = NA) { #' For more information, see the [online tutorial](https://immunarch.com/articles/web_only/v11_db.html). #' #' @param .data The data to process. It can be a [data.frame], a -#' [data.table], or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' [immunarch_data_format] diff --git a/R/clonality.R b/R/v0_clonality.R similarity index 100% rename from R/clonality.R rename to R/v0_clonality.R diff --git a/R/clustering.R b/R/v0_clustering.R similarity index 100% rename from R/clustering.R rename to R/v0_clustering.R diff --git a/R/data_docs.R b/R/v0_data_docs.R similarity index 100% rename from R/data_docs.R rename to R/v0_data_docs.R diff --git a/R/dimensions.R b/R/v0_dimensions.R similarity index 85% rename from R/dimensions.R rename to R/v0_dimensions.R index c9ba8b38..817275cd 100644 --- a/R/dimensions.R +++ b/R/v0_dimensions.R @@ -28,9 +28,9 @@ default_scale_fun <- function(x) { #' #' - `immunr_pca` performs PCA (Principal Component Analysis) using [prcomp]; #' -#' - `immunr_mds` performs MDS (Multi-Dimensional Scaling) using [isoMDS][MASS::isoMDS]; +#' - `immunr_mds` performs MDS (Multi-Dimensional Scaling) using isoMODS from MASS package. #' -#' - `immunr_tsne` performs tSNE (t-Distributed Stochastic Neighbour Embedding) using [Rtsne][Rtsne::Rtsne]. +#' - `immunr_tsne` performs tSNE (t-Distributed Stochastic Neighbour Embedding) using Rtsne Rtsne package. #' #' @usage #' @@ -45,7 +45,7 @@ default_scale_fun <- function(x) { #' @param .scale A function to apply to your data before passing it to any of #' dimensionality reduction algorithms. There is no scaling by default. #' -#' @param .perp The perplexity parameter for [Rtsne][Rtsne::Rtsne]. Specifies the number +#' @param .perp The perplexity parameter for Rtsne. Specifies the number #' of neighbors each data point must have in the resulting plot. #' #' @param .raw If TRUE then returns the non-processed output from dimensionality reduction @@ -56,14 +56,14 @@ default_scale_fun <- function(x) { #' #' @param .dist If TRUE then assumes that ".data" is a distance matrix. #' -#' @param ... Other parameters passed to [Rtsne][Rtsne::Rtsne]. +#' @param ... Other parameters passed to Rtsne. #' #' @return #' `immunr_pca` - an output from [prcomp]. #' -#' `immunr_mds` - an output from [isoMDS][MASS::isoMDS]. +#' `immunr_mds` - an output from isoMDS. #' -#' `immunr_tsne` - an output from \[Rtsne][Rtsne::Rtsne]. +#' `immunr_tsne` - an output from Rtsne. #' #' @seealso [vis.immunr_pca] for visualisations. #' @@ -103,6 +103,10 @@ immunr_pca <- function(.data, .scale = default_scale_fun, .raw = TRUE, .orig = F } immunr_mds <- function(.data, .scale = default_scale_fun, .raw = TRUE, .orig = FALSE, .dist = TRUE) { + if (!requireNamespace("MASS", quietly = TRUE)) { + stop("Package 'MASS' is required for this function. Please install it first via `pak::pkg_install('MASS')`", call. = FALSE) + } + if (.dist) { .data <- as.dist(.scale(.data)) } else { @@ -129,6 +133,10 @@ immunr_mds <- function(.data, .scale = default_scale_fun, .raw = TRUE, .orig = F } immunr_tsne <- function(.data, .perp = 1, .dist = TRUE, ...) { + if (!requireNamespace("Rtsne", quietly = TRUE)) { + stop("Package 'Rtsne' is required for this function. Please install it first via `pak::pkg_install('Rtsne')`", call. = FALSE) + } + if (.dist) { data_proc <- as.dist(.data) } else { diff --git a/R/distance.R b/R/v0_distance.R similarity index 98% rename from R/distance.R rename to R/v0_distance.R index 031b0fbd..0db310da 100644 --- a/R/distance.R +++ b/R/v0_distance.R @@ -3,7 +3,6 @@ #' @concept distance #' #' @importFrom stringdist stringdistmatrix -#' @importFrom purrr map pmap map2 #' @importFrom magrittr %>% %<>% set_attr #' @importFrom tidyr unite #' @importFrom dplyr select_if group_keys group_map group_by group_by_at @@ -55,7 +54,7 @@ #' #' data(immdata) #' # Reducing data to save time on examples -#' immdata$data <- purrr::map(immdata$data, ~ .x %>% head(10)) +#' immdata$data <- map(immdata$data, ~ .x %>% head(10)) #' # Computing hamming distance for the first two repertoires in `'immdata'` #' seqDist(immdata$data[1:2]) #' diff --git a/R/diversity.R b/R/v0_diversity.R similarity index 100% rename from R/diversity.R rename to R/v0_diversity.R diff --git a/R/dynamics.R b/R/v0_dynamics.R similarity index 100% rename from R/dynamics.R rename to R/v0_dynamics.R diff --git a/R/explore.R b/R/v0_explore.R similarity index 100% rename from R/explore.R rename to R/v0_explore.R diff --git a/R/filters.R b/R/v0_filters.R similarity index 100% rename from R/filters.R rename to R/v0_filters.R diff --git a/R/gene_usage.R b/R/v0_gene_usage.R similarity index 99% rename from R/gene_usage.R rename to R/v0_gene_usage.R index 9dc090a9..68857b16 100644 --- a/R/gene_usage.R +++ b/R/v0_gene_usage.R @@ -191,12 +191,10 @@ geneUsage <- function(.data, # df, list, MonetDB #' WIP #' -#' @concept gene_usage +#' @concept data #' #' @importFrom dplyr n #' -#' @aliases gene_stats -#' #' @return #' `gene_stats` returns all segment gene statistics #' diff --git a/R/gene_usage_analysis.R b/R/v0_gene_usage_analysis.R similarity index 100% rename from R/gene_usage_analysis.R rename to R/v0_gene_usage_analysis.R diff --git a/R/germline.R b/R/v0_germline.R similarity index 99% rename from R/germline.R rename to R/v0_germline.R index d636492e..9e4950bf 100644 --- a/R/germline.R +++ b/R/v0_germline.R @@ -5,7 +5,6 @@ #' @aliases repGermline #' #' @importFrom stringr str_sub str_length str_replace fixed str_extract_all str_extract boundary str_c -#' @importFrom purrr imap map_dfr #' @importFrom magrittr %>% %<>% extract2 #' @importFrom dplyr filter rowwise #' @importFrom tidyselect any_of diff --git a/R/immunr_data_format.R b/R/v0_immunr_data_format.R similarity index 100% rename from R/immunr_data_format.R rename to R/v0_immunr_data_format.R diff --git a/R/info_theory.R b/R/v0_info_theory.R similarity index 100% rename from R/info_theory.R rename to R/v0_info_theory.R diff --git a/R/io.R b/R/v0_io.R similarity index 99% rename from R/io.R rename to R/v0_io.R index f3577a15..08a5acb4 100644 --- a/R/io.R +++ b/R/v0_io.R @@ -17,7 +17,6 @@ if (getRversion() >= "2.15.1") { #' @concept io #' #' @importFrom readr read_delim read_tsv read_csv col_integer col_character col_double col_logical col_guess cols write_lines -#' @importFrom jsonlite read_json #' @importFrom stringr str_split str_detect str_replace_all str_trim #' @importFrom methods as #' @importFrom dplyr contains first select_ group_by_at one_of row_number @@ -175,7 +174,6 @@ repLoad <- function(.path, .mode = "paired", .coding = TRUE, ...) { catt = parse_catt, rtcr = parse_rtcr, imseq = parse_imseq, - vidjil = parse_vidjil, NA ) @@ -434,7 +432,6 @@ repLoad <- function(.path, .mode = "paired", .coding = TRUE, ...) { #' #' @importFrom utils packageVersion #' @importFrom plyr mapvalues -#' @importFrom purrr map #' #' @description #' @@ -460,7 +457,7 @@ repLoad <- function(.path, .mode = "paired", .coding = TRUE, ...) { #' @examples #' data(immdata) #' # Reduce data to save time on examples -#' immdata$data <- purrr::map(immdata$data, ~ .x %>% head(10)) +#' immdata$data <- map(immdata$data, ~ .x %>% head(10)) #' dirpath <- tempdir() #' # Save the list of repertoires #' repSave(immdata, dirpath) diff --git a/R/io-parsers.R b/R/v0_io_parsers.R similarity index 97% rename from R/io-parsers.R rename to R/v0_io_parsers.R index fd0601cd..3adb1a5c 100644 --- a/R/io-parsers.R +++ b/R/v0_io_parsers.R @@ -1275,46 +1275,3 @@ parse_imseq <- function(.filename, .mode) { .total.insertions = total.insertions, .skip = .skip, .sep = .sep ) } - -parse_vidjil <- function(.filename, .mode) { - json_data <- read_json(.filename, simplifyVector = TRUE) - clones <- json_data[["clones"]] - - count <- as.vector(clones[["reads"]], mode = "numeric") - proportion <- count / sum(count) - cdr3nt <- NA - cdr3aa <- as.vector(clones[["seg"]][["cdr3"]][["aa"]]) - vgenes <- as.vector(clones[["seg"]][["5"]]) - dgenes <- NA - jgenes <- as.vector(clones[["seg"]][["3"]]) - vend <- as.vector(clones[["seg"]][["5end"]], mode = "numeric") - dstart <- NA - dend <- NA - jstart <- as.vector(clones[["seg"]][["3start"]], mode = "numeric") - vj.insertions <- NA - vd.insertions <- NA - dj.insertions <- NA - - df <- data.frame( - count, proportion, cdr3nt, cdr3aa, vgenes, dgenes, jgenes, - vend, dstart, dend, jstart, vj.insertions, vd.insertions, dj.insertions - ) - - colnames(df)[1] <- IMMCOL$count - colnames(df)[2] <- IMMCOL$prop - colnames(df)[3] <- IMMCOL$cdr3nt - colnames(df)[4] <- IMMCOL$cdr3aa - colnames(df)[5] <- IMMCOL$v - colnames(df)[6] <- IMMCOL$d - colnames(df)[7] <- IMMCOL$j - colnames(df)[8] <- IMMCOL$ve - colnames(df)[9] <- IMMCOL$ds - colnames(df)[10] <- IMMCOL$de - colnames(df)[11] <- IMMCOL$js - colnames(df)[12] <- IMMCOL$vnj - colnames(df)[13] <- IMMCOL$vnd - colnames(df)[14] <- IMMCOL$dnj - - df <- .postprocess(df) - df -} diff --git a/R/io-savers.R b/R/v0_io_savers.R similarity index 100% rename from R/io-savers.R rename to R/v0_io_savers.R diff --git a/R/io-utility.R b/R/v0_io_utility.R similarity index 100% rename from R/io-utility.R rename to R/v0_io_utility.R diff --git a/R/kmers.R b/R/v0_kmers.R similarity index 100% rename from R/kmers.R rename to R/v0_kmers.R diff --git a/R/overlap.R b/R/v0_overlap.R similarity index 100% rename from R/overlap.R rename to R/v0_overlap.R diff --git a/R/overlap_analysis.R b/R/v0_overlap_analysis.R similarity index 100% rename from R/overlap_analysis.R rename to R/v0_overlap_analysis.R diff --git a/R/phylip.R b/R/v0_phylip.R similarity index 98% rename from R/phylip.R rename to R/v0_phylip.R index 4f9bb4e0..155ab695 100644 --- a/R/phylip.R +++ b/R/v0_phylip.R @@ -5,14 +5,11 @@ #' @aliases repClonalFamily #' #' @importFrom magrittr %>% %<>% extract2 -#' @importFrom purrr map_dfr #' @importFrom rlist list.remove #' @importFrom stringr str_match str_count fixed str_extract_all str_length str_sub -#' @importFrom stringi stri_replace_all_fixed #' @importFrom utils capture.output #' @importFrom parallel mclapply detectCores #' @importFrom ape read.tree -#' @importFrom uuid UUIDgenerate #' @importFrom data.table fread #' @description @@ -158,12 +155,15 @@ process_cluster <- function(cluster_row, vis_groups) { fsep <- if (.Platform$OS.type == "windows") "\\" else "/" shell <- if (.Platform$OS.type == "windows") "powershell /c " else "sh -c " - temp_dir <- file.path(tempdir(check = TRUE), uuid::UUIDgenerate(use.time = FALSE), fsep = fsep) + + temp_dir <- tempfile(pattern = "tempdir_") dir.create(temp_dir) + # workaround for phylip: it shows "Unexpected end-of-file" for too short sequence labels; # these \t are also used to read outfile as table rownames(alignment) %<>% paste0("\t") phangorn::write.phyDat(alignment, file.path(temp_dir, "infile", fsep = fsep)) + dnapars <- if (Sys.which("phylip") == "") "dnapars" else "phylip dnapars" system( paste0(shell, "\"cd ", temp_dir, "; ", dnapars, " infile\""), @@ -373,7 +373,7 @@ convert_nested_to_df <- function(nested_results_list) { tibble(Sequences = .) df <- nested_results_list %>% lapply(rlist::list.remove, c("Tree", "TreeStats", "Sequences")) %>% - purrr::map_dfr(~.) %>% + map_dfr(~.) %>% cbind(tree, tree_stats, sequences) # fix column types after dataframe rebuilding df[["Trunk.Length"]] %<>% as.integer() diff --git a/R/preprocessing.R b/R/v0_preprocessing.R similarity index 98% rename from R/preprocessing.R rename to R/v0_preprocessing.R index 18533c6b..e1218b23 100644 --- a/R/preprocessing.R +++ b/R/v0_preprocessing.R @@ -63,7 +63,7 @@ top <- function(.data, .n = 10) { #' outofframes(.data) #' #' @param .data The data to be processed. Can be [data.frame], -#' [data.table], or a list of these objects. +#' [data.table::data.table], or a list of these objects. #' #' Every object must have columns in the immunarch compatible format. #' [immunarch_data_format] diff --git a/R/public.R b/R/v0_public.R similarity index 98% rename from R/public.R rename to R/v0_public.R index b8113033..ab5cff59 100644 --- a/R/public.R +++ b/R/v0_public.R @@ -128,6 +128,11 @@ publicRepertoire <- pubRep #' #' @concept pubrep #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' #' @param .data Public repertoire, an output from [pubRep]. #' #' @return @@ -245,7 +250,9 @@ publicRepertoireFilter <- pubRepFilter #' #' @aliases pubRepApply publicRepertoireApply #' -#' @description Work In Progress +#' @description +#' +#' `r lifecycle::badge('deprecated')` #' #' @param .pr1 First public repertoire. #' @param .pr2 Second public repertoire. diff --git a/R/sampling.R b/R/v0_sampling.R similarity index 99% rename from R/sampling.R rename to R/v0_sampling.R index a256be4a..701c0614 100644 --- a/R/sampling.R +++ b/R/v0_sampling.R @@ -22,6 +22,9 @@ #' @aliases repSample #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' Sample (downsample) repertoires using different approches. #' #' @param .data The data to be processed. Can be [data.frame], diff --git a/R/seqCluster.R b/R/v0_seqCluster.R similarity index 98% rename from R/seqCluster.R rename to R/v0_seqCluster.R index 050c49a6..2f234240 100644 --- a/R/seqCluster.R +++ b/R/v0_seqCluster.R @@ -2,13 +2,13 @@ #' #' @concept seq_cluster #' -#' @importFrom purrr map map_lgl map_chr map2 map2_chr map_df map2_lgl pmap map2_df #' @importFrom magrittr %>% %<>% #' @importFrom reshape2 melt #' @importFrom dplyr group_by mutate ungroup select cur_group_id left_join #' @importFrom reshape2 melt #' @importFrom tibble rownames_to_column #' @importFrom glue glue +#' @importFrom purrr map_chr #' #' @description #' @@ -100,7 +100,7 @@ seqCluster <- function(.data, .dist, .perc_similarity, .nt_similarity, .fixed_th threshold <- map(seq_length, ~ .x %>% threshold_fun()) group_values <- map_dfr(dist_list, ~ attr(.x, "group_values")) if (all(is.na(grouping_cols))) { - protocluster_names <- map_chr(seq_labels, 1) + protocluster_names <- purrr::map_chr(seq_labels, 1) result_single <- data.frame( Sequence = unlist(seq_labels[singleseq_flag]), Cluster = paste0( diff --git a/R/shiny.R b/R/v0_shiny.R similarity index 99% rename from R/shiny.R rename to R/v0_shiny.R index a20e7d8f..79d63672 100644 --- a/R/shiny.R +++ b/R/v0_shiny.R @@ -11,7 +11,11 @@ if (getRversion() >= "2.15.1") { #' #' @importFrom graphics plot #' -#' @description The `fixVis` is a built-in software tool for the manipulation +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' The `fixVis` is a built-in software tool for the manipulation #' of plots, such as adjusting title text font and size, axes, and more. It is a powerful #' tool designed to produce publication-ready plots with minimal amount of coding. #' diff --git a/R/singlecell.R b/R/v0_singlecell.R similarity index 100% rename from R/singlecell.R rename to R/v0_singlecell.R diff --git a/R/somatic_hypermutation.R b/R/v0_somatic_hypermutation.R similarity index 100% rename from R/somatic_hypermutation.R rename to R/v0_somatic_hypermutation.R diff --git a/R/spectratyping.R b/R/v0_spectratyping.R similarity index 100% rename from R/spectratyping.R rename to R/v0_spectratyping.R diff --git a/R/tools.R b/R/v0_tools.R similarity index 98% rename from R/tools.R rename to R/v0_tools.R index 63477193..8d4408d6 100644 --- a/R/tools.R +++ b/R/v0_tools.R @@ -189,7 +189,7 @@ add_pb <- function(.pb, .value = 1) { #' @section Developer Examples: #' mat <- matrix(0, 3, 3) #' mat -#' mat[1, 3] <- 1 +#' mat(1, 3) <- 1 #' mat <- immunarch:::matrixdiagcopy(mat) #' mat matrixdiagcopy <- function(.mat) { @@ -362,7 +362,7 @@ rename_column <- function(.data, .old, .new) { #' @param .diag Either NA for NA or something else != NULL for .fun(x,x). #' @param .verbose if TRUE then output a progress bar. #' -#' @return Matrix with values M[i,j] = fun(datalist[i], datalist[j]) +#' @return Matrix with values M(i,j) = fun(datalist(i), datalist(j)) #' #' @examples #' data(immdata) @@ -510,7 +510,7 @@ apply_to_sample_or_list <- function(.data, .function, .with_names = FALSE, .vali } if (.with_names) { .data %<>% - purrr::imap(function(sample_data, sample_name) { + imap(function(sample_data, sample_name) { sample_data %>% as_tibble() %>% .function(..., sample_name = sample_name) @@ -624,7 +624,7 @@ require_system_package <- function(executable_names, if (.nofail & .prev_failed) { return(FALSE) } - package_not_exist <- all(unlist(purrr::map(Sys.which(executable_names), identical, ""))) + package_not_exist <- all(unlist(map(Sys.which(executable_names), identical, ""))) if (package_not_exist) { if (.nofail) { cat(error_message) diff --git a/R/v0-vis.R b/R/v0_vis.R similarity index 96% rename from R/v0-vis.R rename to R/v0_vis.R index d58bb315..bf52c686 100644 --- a/R/v0-vis.R +++ b/R/v0_vis.R @@ -12,50 +12,67 @@ if (getRversion() >= "2.15.1") { )) } -theme_pubr <- function (base_size = 12, base_family = "", border = FALSE, margin = TRUE, - legend = c("top", "bottom", "left", "right", "none"), x.text.angle = 0) -{ - half_line <- base_size/2 - if (!is.numeric(legend)) +theme_pubr <- function(base_size = 12, base_family = "", border = FALSE, margin = TRUE, + legend = c("top", "bottom", "left", "right", "none"), x.text.angle = 0) { + half_line <- base_size / 2 + if (!is.numeric(legend)) { legend <- match.arg(legend) - if (x.text.angle > 5) + } + if (x.text.angle > 5) { xhjust <- 1 - else xhjust <- NULL + } else { + xhjust <- NULL + } if (border) { - panel.border <- element_rect(fill = NA, colour = "black", - size = 0.7) + panel.border <- element_rect( + fill = NA, colour = "black", + size = 0.7 + ) axis.line <- element_blank() - } - else { + } else { panel.border <- element_blank() - axis.line = element_line(colour = "black", size = 0.5) + axis.line <- element_line(colour = "black", size = 0.5) + } + if (margin) { + plot.margin <- margin( + half_line, half_line, half_line, + half_line + ) + } else { + plot.margin <- unit(c(0.5, 0.3, 0.3, 0.3), "mm") } - if (margin) - plot.margin <- margin(half_line, half_line, half_line, - half_line) - else plot.margin <- unit(c(0.5, 0.3, 0.3, 0.3), "mm") .theme <- theme_bw(base_size = base_size, base_family = base_family) %+replace% - theme(panel.border = panel.border, panel.grid.major = element_blank(), - panel.grid.minor = element_blank(), axis.line = axis.line, - axis.text = element_text(color = "black"), legend.key = element_blank(), - strip.background = element_rect(fill = "#F2F2F2", - colour = "black", size = 0.7), plot.margin = plot.margin, - legend.position = legend, complete = TRUE) - if (x.text.angle != 0) - .theme <- .theme + theme(axis.text.x = element_text(angle = x.text.angle, - hjust = xhjust)) + theme( + panel.border = panel.border, panel.grid.major = element_blank(), + panel.grid.minor = element_blank(), axis.line = axis.line, + axis.text = element_text(color = "black"), legend.key = element_blank(), + strip.background = element_rect( + fill = "#F2F2F2", + colour = "black", size = 0.7 + ), plot.margin = plot.margin, + legend.position = legend, complete = TRUE + ) + if (x.text.angle != 0) { + .theme <- .theme + theme(axis.text.x = element_text( + angle = x.text.angle, + hjust = xhjust + )) + } .theme } -rotate_x_text <- function (angle = 90, hjust = NULL, vjust = NULL, ...) -{ - if (missing(hjust) & angle > 5) +rotate_x_text <- function(angle = 90, hjust = NULL, vjust = NULL, ...) { + if (missing(hjust) & angle > 5) { hjust <- 1 - if (missing(vjust) & angle == 90) + } + if (missing(vjust) & angle == 90) { vjust <- 0.5 - theme(axis.text.x = element_text(angle = angle, hjust = hjust, - vjust = vjust, ...)) + } + theme(axis.text.x = element_text( + angle = angle, hjust = hjust, + vjust = vjust, ... + )) } @@ -154,7 +171,11 @@ theme_cleveland2 <- function(rotate = TRUE) { #' @importFrom grDevices colorRampPalette #' @importFrom tidyr drop_na #' -#' @description Output from every function in immunarch can be visualised with a +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Output from every function in immunarch can be visualised with a #' single function - `vis`. The `vis` automatically detects #' the type of the data and draws a proper visualisation. For example, output #' from the `repOverlap` function will be identified as repertoire overlap values @@ -252,7 +273,11 @@ vis <- function(.data, ...) { #' #' @aliases vis.immunr_ov_matrix vis.immunr_gu_matrix #' -#' @description Visualises matrices with overlap values or gene usage distances among samples. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualises matrices with overlap values or gene usage distances among samples. #' For details see the links below. #' #' @param .data Output from [repOverlap] or [geneUsageAnalysis]. @@ -326,7 +351,11 @@ vis.immunr_gu_matrix <- function(.data, .plot = c("heatmap", "heatmap2", "circos #' #' @aliases vis_heatmap #' -#' @description Fast and easy visualisations of matrices or data frames +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Fast and easy visualisations of matrices or data frames #' with functions based on the ggplot2 package. #' #' @param .data Input object: a matrix or a data frame. @@ -454,7 +483,11 @@ vis_heatmap <- function(.data, .text = TRUE, .scientific = FALSE, .signif.digits #' #' @name vis_heatmap2 #' -#' @description Visualise matrices with the functions based on the [pheatmap][pheatmap::pheatmap] +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualise matrices with the functions based on the [pheatmap][pheatmap::pheatmap] #' package with minimum amount of arguments. #' #' @param .data Input matrix. Column names and row names (if presented) will be used as names for labs. @@ -508,7 +541,11 @@ vis_heatmap2 <- function(.data, .meta = NA, .by = NA, .title = NA, .color = colo #' #' @name vis_circos #' -#' @description Visualise matrices with the [circlize::chordDiagram] function +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualise matrices with the [circlize::chordDiagram] function #' from the circlize package. #' #' @param .data Input matrix. @@ -626,6 +663,11 @@ vis_circos <- function(.data, .title = NULL, ...) { #' #' @importFrom dplyr rename #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' #' @name vis.immunr_inc_overlap #' #' @param .data Output from the [repOverlap] function that uses "top" methods. @@ -724,6 +766,11 @@ vis.immunr_inc_overlap <- function(.data, .target = 1, .grid = FALSE, .ncol = 2, #' #' @name vis.immunr_public_repertoire #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' #' @param .data Public repertoire, an output from [pubRep]. #' @param .plot A string specifying the plot type: #' @@ -765,7 +812,11 @@ vis.immunr_public_repertoire <- function(.data, .plot = c("freq", "clonotypes"), #' #' @name vis.immunr_public_statistics #' -#' @description Visualise public clonotype frequencies. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualise public clonotype frequencies. #' #' @param .data Public repertoire - an output from the [pubRep] function. #' @@ -781,7 +832,6 @@ vis.immunr_public_repertoire <- function(.data, .plot = c("freq", "clonotypes"), #' pubRepStatistics(pr) %>% vis() #' @export vis.immunr_public_statistics <- function(.data, ...) { - if (!requireNamespace("UpSetR", quietly = TRUE)) { stop("Package 'UpSetR' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) } @@ -798,7 +848,11 @@ vis.immunr_public_statistics <- function(.data, ...) { #' #' @name vis_public_frequencies #' -#' @description Visualise public clonotype frequencies. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualise public clonotype frequencies. #' #' @param .data Public repertoire - an output from the [pubRep] function. #' @param .by Pass NA if you want to plot samples without grouping. @@ -894,7 +948,11 @@ vis_public_frequencies <- function(.data, .by = NA, .meta = NA, #' @importFrom stats lm #' @importFrom patchwork wrap_plots plot_annotation #' -#' @description Visualise correlation of public clonotype frequencies in pairs of repertoires. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualise correlation of public clonotype frequencies in pairs of repertoires. #' #' @param .data Public repertoire data - an output from the [pubRep] function. #' @@ -1097,7 +1155,11 @@ vis_public_clonotypes <- function(.data, .x.rep = NA, .y.rep = NA, #' #' @name vis.immunr_gene_usage #' -#' @description Visualise distributions of genes using heatmaps or other plots. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualise distributions of genes using heatmaps or other plots. #' #' @param .data Output from the [geneUsage] function. #' @@ -1172,7 +1234,11 @@ vis.immunr_gene_usage <- function(.data, .plot = c("hist", "box", "heatmap", "he #' #' @name vis_hist #' -#' @description Visualisation of distributions using ggplot2-based histograms. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualisation of distributions using ggplot2-based histograms. #' #' @param .data Input matrix or data frame. #' @@ -1366,7 +1432,11 @@ vis_hist <- function(.data, .by = NA, .meta = NA, .title = "Gene usage", .ncol = #' #' @name vis_box #' -#' @description Visualisation of distributions using ggplot2-based boxplots. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' Visualisation of distributions using ggplot2-based boxplots. #' #' @param .data Input matrix or data frame. #' @@ -1545,6 +1615,9 @@ vis_box <- function(.data, .by = NA, .meta = NA, .melt = TRUE, #' @concept post_analysis #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' Visualisation of the results of hierarchical clustering. #' For other clustering visualisations see [vis.immunr_kmeans]. #' @@ -1600,6 +1673,9 @@ vis.immunr_hclust <- function(.data, .rect = FALSE, .plot = c("clust", "best"), #' @concept post_analysis #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' Visualisation of the results of K-means and DBSCAN clustering. #' For hierarhical clustering visualisations see [vis.immunr_hclust]. #' @@ -1687,6 +1763,11 @@ vis.immunr_dbscan <- function(.data, .point = TRUE, .text = TRUE, .ellipse = TRU #' #' @aliases vis.immunr_mds vis.immunr_pca vis.immunr_tsne #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' #' @param .data Output from analysis functions such as [geneUsageAnalysis] or #' [immunr_pca], [immunr_mds] or [immunr_tsne]. #' @param .by Pass NA if you want to plot samples without grouping. @@ -1900,7 +1981,11 @@ vis_bar_stacked <- function(.data, .by = NA, .meta = NA, #' #' @aliases vis.immunr_clonal_prop vis.immunr_homeo vis.immunr_top_prop vis.immunr_tail_prop #' -#' @description An utility function to visualise the output from [repClonality()]. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' An utility function to visualise the output from [repClonality()]. #' #' @importFrom reshape2 melt #' @importFrom scales percent @@ -2089,6 +2174,11 @@ vis.immunr_rare_prop <- function(.data, .by = NA, .meta = NA, .errorbars = c(0.0 #' #' @name vis_bar #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' #' @param .data Data to visualise. #' @param .by Pass NA if you want to plot samples without grouping. #' @@ -2305,7 +2395,12 @@ vis_bar <- function(.data, .by = NA, .meta = NA, .errorbars = c(0.025, 0.975), . #' @concept diversity #' #' @aliases vis.immunr_chao1 vis.immunr_dxx vis.immunr_rarefaction vis.immunr_div vis.immunr_ginisimp vis.immunr_invsimp vis.immunr_hill -#' @description An utility function to visualise the output from [repDiversity()]. +#' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' An utility function to visualise the output from [repDiversity()]. #' #' @importFrom reshape2 melt #' @@ -2492,7 +2587,6 @@ vis.immunr_dxx <- function(.data, .by = NA, .meta = NA, vis.immunr_rarefaction <- function(.data, .by = NA, .meta = NA, .mean = TRUE, .errors = TRUE, .log = FALSE, .labels = TRUE, ...) { - if (!requireNamespace("ggrepel", quietly = TRUE)) { stop("Package 'ggrepel' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) } @@ -2569,7 +2663,11 @@ vis.immunr_rarefaction <- function(.data, .by = NA, .meta = NA, #' @concept explore #' #' @aliases vis.immunr_exp_vol vis.immunr_exp_count vis.immunr_exp_len vis.immunr_exp_clones -#' @description An utility function to visualise the output from [repExplore()]. +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' An utility function to visualise the output from [repExplore()]. #' #' @importFrom reshape2 melt #' @@ -2714,6 +2812,9 @@ vis.immunr_exp_clones <- function(.data, .by = NA, .meta = NA, #' @name vis.immunr_kmer_table #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' Plot a distribution (bar plot) of the most frequent kmers in a data. #' #' @param .data Data frame with two columns "Kmers" and "Count" or a list with such data frames. See Examples. @@ -2779,8 +2880,6 @@ vis.immunr_kmer_table <- function(.data, .head = 100, .position = c("stack", "do #' #' @concept kmers #' -#' @importFrom ggseqlogo geom_logo theme_logo -#' #' @aliases vis_seqlogo vis_textlogo #' #' @name vis_textlogo @@ -2791,6 +2890,9 @@ vis.immunr_kmer_table <- function(.data, .head = 100, .position = c("stack", "do #' vis_seqlogo(.data, .scheme = "chemistry", ...) #' #' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' Plot sequence logo plots for visualising of amino acid motif sequences / profiles. #' #' `vis_textlogo` plots sequences in a text format - each letter has the same height. Useful when there @@ -2802,7 +2904,7 @@ vis.immunr_kmer_table <- function(.data, .head = 100, .position = c("stack", "do #' @param .data Output from the `kmer.profile` function. #' @param .replace.zero.with.na if TRUE then replace all zeros with NAs, therefore letters with #' zero frequency wont appear at the plot. -#' @param .scheme Character. An argument passed to [ggseqlogo::geom_logo] specifying how to colour symbols. +#' @param .scheme Character. An argument passed to geom_logo from ggseqlogo package specifying how to colour symbols. #' @param .width Width for jitter, i.e., how much points will scatter around the verical line. Pass 0 (zero) #' to plot points on the straight vertical line for each position. #' @param ... Not used here. @@ -2845,6 +2947,10 @@ vis_textlogo <- function(.data, .replace.zero.with.na = TRUE, .width = 0.1, ...) #' @export vis_seqlogo <- function(.data, .scheme = "chemistry", ...) { + if (!requireNamespace("ggseqlogo", quietly = TRUE)) { + stop("Package 'ggseqlogo' is required for this function. Please install it first via `pak::pkg_install('ggseqlogo')`", call. = FALSE) + } + ggplot() + ggseqlogo::geom_logo(.data, method = "custom", col_scheme = .scheme) + ggseqlogo::theme_logo() @@ -2855,6 +2961,11 @@ vis_seqlogo <- function(.data, .scheme = "chemistry", ...) { #' #' @concept kmers #' +#' @description +#' +#' #' `r lifecycle::badge('deprecated')` +#' +#' #' @param .data Kmer data, an output from [kmer_profile]. #' @param .plot String specifying the plot type: #' @@ -2923,6 +3034,11 @@ vis.immunr_kmer_profile_self <- function(.data, .plot = c("textlogo", "seqlogo") #' #' @name vis.immunr_dynamics #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' #' @param .data Output from the [trackClonotypes] function. #' @param .plot Character. Either "smooth", "area" or "line". Each specifies a type of plot for visualisation of clonotype dynamics. #' @param .order Numeric or character vector. Specifies the order to samples, e.g., it used for ordering samples @@ -2982,7 +3098,6 @@ vis.immunr_kmer_profile_self <- function(.data, .plot = c("textlogo", "seqlogo") #' vis(tc, .order = sample_order) #' @export vis.immunr_dynamics <- function(.data, .plot = c("smooth", "area", "line"), .order = NA, .log = FALSE, ...) { - if (!requireNamespace("ggalluvial", quietly = TRUE)) { stop("Package 'ggalluvial' is required for this function. Please install it first via install.packages() or devtools::install_github().", call. = FALSE) } @@ -3049,9 +3164,15 @@ vis.immunr_dynamics <- function(.data, .plot = c("smooth", "area", "line"), .ord #' #' @concept phylip #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' #' @param .data Clonal families from 1 or multiple samples: [repClonalFamily()] output. #' @param ... Not used here. #' +#' #' @return #' A ggraph object. #' @@ -3095,6 +3216,11 @@ vis.clonal_family <- function(.data, ...) { #' #' @concept phylip #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' +#' #' @param .data Single clonal family tree data from 1 cluster: 1 element from TreeStats column from [repClonalFamily()] output. #' @param ... Not used here. #' @@ -3143,6 +3269,10 @@ vis.clonal_family_tree <- function(.data, ...) { #' Handler for .nofail argument of pipeline steps that prevents examples from crashing #' on computers where certain dependencies are not installed #' +#' @description +#' +#' `r lifecycle::badge('deprecated')` +#' #' @param .data Not used here. #' @param ... Not used here. #' From 1a559d7de6bb5000b15db3de34d8d5b872025089 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:26:35 +0200 Subject: [PATCH 15/36] docs: add deprecation badge --- man/aa_properties.Rd | 2 +- man/aa_table.Rd | 2 +- man/add_class.Rd | 2 +- man/airr_public.Rd | 84 +++++++++++++++++++++++++++++ man/apply_symm.Rd | 4 +- man/bcrdata.Rd | 2 +- man/bunch_translate.Rd | 2 +- man/check_distribution.Rd | 2 +- man/coding.Rd | 4 +- man/dbAnnotate.Rd | 4 +- man/dbLoad.Rd | 2 +- man/dot-quant_column_choice.Rd | 2 +- man/entropy.Rd | 2 +- man/fixVis.Rd | 4 +- man/geneUsage.Rd | 2 +- man/geneUsageAnalysis.Rd | 2 +- man/gene_segments.Rd | 2 +- man/gene_stats.Rd | 4 +- man/getKmers.Rd | 2 +- man/get_immunarch_news.Rd | 1 + man/group_from_metadata.Rd | 2 +- man/has_class.Rd | 2 +- man/im_common_args.Rd | 30 +++++++++++ man/immdata.Rd | 2 +- man/immunarch_v1_updates.Rd | 5 +- man/immunr_data_format.Rd | 2 +- man/immunr_hclust.Rd | 2 +- man/immunr_pca.Rd | 14 ++--- man/inc_overlap.Rd | 2 +- man/list_immunarch_news.Rd | 1 + man/matrixdiagcopy.Rd | 4 +- man/pubRep.Rd | 2 +- man/pubRepApply.Rd | 4 +- man/pubRepFilter.Rd | 2 +- man/pubRepStatistics.Rd | 2 +- man/public_matrix.Rd | 4 +- man/repAlignLineage.Rd | 2 +- man/repClonalFamily.Rd | 2 +- man/repClonality.Rd | 2 +- man/repDiversity.Rd | 2 +- man/repExplore.Rd | 2 +- man/repFilter.Rd | 2 +- man/repGermline.Rd | 2 +- man/repLoad.Rd | 2 +- man/repOverlap.Rd | 2 +- man/repOverlapAnalysis.Rd | 2 +- man/repSample.Rd | 4 +- man/repSave.Rd | 4 +- man/repSomaticHypermutation.Rd | 2 +- man/scdata.Rd | 2 +- man/select_barcodes.Rd | 2 +- man/select_clusters.Rd | 2 +- man/seqCluster.Rd | 2 +- man/seqDist.Rd | 4 +- man/set_pb.Rd | 2 +- man/spectratype.Rd | 2 +- man/split_to_kmers.Rd | 2 +- man/switch_type.Rd | 2 +- man/top.Rd | 2 +- man/trackClonotypes.Rd | 2 +- man/vis.Rd | 4 +- man/vis.clonal_family.Rd | 4 +- man/vis.clonal_family_tree.Rd | 4 +- man/vis.immunr_chao1.Rd | 4 +- man/vis.immunr_clonal_prop.Rd | 4 +- man/vis.immunr_dynamics.Rd | 4 +- man/vis.immunr_exp_vol.Rd | 4 +- man/vis.immunr_gene_usage.Rd | 4 +- man/vis.immunr_hclust.Rd | 4 +- man/vis.immunr_inc_overlap.Rd | 4 +- man/vis.immunr_kmeans.Rd | 4 +- man/vis.immunr_kmer_table.Rd | 4 +- man/vis.immunr_mds.Rd | 4 +- man/vis.immunr_ov_matrix.Rd | 4 +- man/vis.immunr_public_repertoire.Rd | 4 +- man/vis.immunr_public_statistics.Rd | 4 +- man/vis.step_failure_ignored.Rd | 5 +- man/vis_bar.Rd | 4 +- man/vis_box.Rd | 4 +- man/vis_circos.Rd | 4 +- man/vis_heatmap.Rd | 4 +- man/vis_heatmap2.Rd | 4 +- man/vis_hist.Rd | 4 +- man/vis_immunr_kmer_profile_main.Rd | 4 +- man/vis_public_clonotypes.Rd | 4 +- man/vis_public_frequencies.Rd | 4 +- man/vis_textlogo.Rd | 6 ++- 87 files changed, 266 insertions(+), 110 deletions(-) create mode 100644 man/airr_public.Rd create mode 100644 man/im_common_args.Rd diff --git a/man/aa_properties.Rd b/man/aa_properties.Rd index 9f4a4068..8386bc3e 100644 --- a/man/aa_properties.Rd +++ b/man/aa_properties.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/data_docs.R +% Please edit documentation in R/v0_data_docs.R \docType{data} \name{aa_properties} \alias{aa_properties} diff --git a/man/aa_table.Rd b/man/aa_table.Rd index f57d6781..f5a0b57b 100644 --- a/man/aa_table.Rd +++ b/man/aa_table.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/data_docs.R +% Please edit documentation in R/v0_data_docs.R \docType{data} \name{aa_table} \alias{aa_table} diff --git a/man/add_class.Rd b/man/add_class.Rd index b2940057..f20a1087 100644 --- a/man/add_class.Rd +++ b/man/add_class.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{add_class} \alias{add_class} \title{Add a new class attribute} diff --git a/man/airr_public.Rd b/man/airr_public.Rd new file mode 100644 index 00000000..ad53eb8e --- /dev/null +++ b/man/airr_public.Rd @@ -0,0 +1,84 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/v1_airr_public.R +\name{airr_public} +\alias{airr_public} +\alias{airr_public_intersection} +\alias{airr_public_jaccard} +\title{Public indices — pairwise repertoire overlap} +\usage{ +airr_public_intersection( + idata, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) + +airr_public_jaccard( + idata, + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) +} +\arguments{ +\item{idata}{An \code{ImmunData} object.} + +\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. +For \code{format="analysis"}, metadata is joined to the long table; for +\code{format="ml"}, it’s joined after pivoting to wide. Defaults to +\code{getOption("immundata.autojoin", FALSE)}.} + +\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet +columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} + +\item{features}{Character vector of \strong{feature keys} to keep when +\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key +looks like \verb{family.method|facet1=...;facet2=...} (e.g., +\code{airr_stats.genes|v_call=TRBV7-2}).} +} +\value{ +\subsection{\code{airr_public_intersection}}{ + +A \strong{symmetric numeric matrix} where rows/columns are \code{repertoire_id} and each +cell is the count of shared unique receptors. The diagonal contains per-repertoire +richness (total unique receptors). Row/column names are repertoire IDs. +} + +\subsection{\code{airr_public_jaccard}}{ + +A \strong{symmetric numeric matrix} where rows/columns are \code{repertoire_id} and each +cell is the Jaccard similarity in \verb{[0, 1]}. The diagonal is \code{1}. Row/column +names are repertoire IDs. +} +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A family of functions to quantify \strong{public or shared receptors} between repertoire. +\subsection{Available functions:}{ +} + +\code{airr_public_intersection} — number of \strong{shared receptors} between +each pair of repertoires (intersection size). Handy for quick overlap heatmaps, +QC of replicate similarity, or spotting donor-shared “public” clonotypes. + +\code{airr_public_jaccard} — \strong{Jaccard similarity} of receptor +sets between repertoires (\verb{|A∩B| / |A∪B|}). Best when comparing cohorts with +different sizes to get a scale-invariant overlap score. +} +\examples{ +# +# airr_public_intersection +# +m_pub <- airr_public_intersection(immdata) + +# +# airr_public_jaccard +# +m_jac <- airr_public_jaccard(immdata) + +} +\seealso{ +\link[immundata:ImmunData]{immundata::ImmunData} +} +\concept{Public indices} diff --git a/man/apply_symm.Rd b/man/apply_symm.Rd index bdb15938..df35a2b1 100644 --- a/man/apply_symm.Rd +++ b/man/apply_symm.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{apply_symm} \alias{apply_symm} \alias{apply_asymm} @@ -21,7 +21,7 @@ apply_asymm(.datalist, .fun, ..., .diag = NA, .verbose = TRUE) \item{.verbose}{if TRUE then output a progress bar.} } \value{ -Matrix with values M\link{i,j} = fun(datalist\link{i}, datalist\link{j}) +Matrix with values M(i,j) = fun(datalist(i), datalist(j)) } \description{ Apply the given function to every pair in the given datalist. Function either diff --git a/man/bcrdata.Rd b/man/bcrdata.Rd index f641727f..68b6f6a5 100644 --- a/man/bcrdata.Rd +++ b/man/bcrdata.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/data_docs.R +% Please edit documentation in R/v0_data_docs.R \docType{data} \name{bcrdata} \alias{bcrdata} diff --git a/man/bunch_translate.Rd b/man/bunch_translate.Rd index 29acfaf9..e843611e 100644 --- a/man/bunch_translate.Rd +++ b/man/bunch_translate.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{bunch_translate} \alias{bunch_translate} \alias{translate_bunch} diff --git a/man/check_distribution.Rd b/man/check_distribution.Rd index 7b206647..656d7395 100644 --- a/man/check_distribution.Rd +++ b/man/check_distribution.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{check_distribution} \alias{check_distribution} \title{Check and normalise distributions} diff --git a/man/coding.Rd b/man/coding.Rd index 5bcfb461..1239913f 100644 --- a/man/coding.Rd +++ b/man/coding.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/preprocessing.R +% Please edit documentation in R/v0_preprocessing.R \name{coding} \alias{coding} \alias{noncoding} @@ -17,7 +17,7 @@ outofframes(.data) } \arguments{ \item{.data}{The data to be processed. Can be \link{data.frame}, -\link{data.table}, or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} diff --git a/man/dbAnnotate.Rd b/man/dbAnnotate.Rd index 9f665944..21407d3d 100644 --- a/man/dbAnnotate.Rd +++ b/man/dbAnnotate.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/annotation.R +% Please edit documentation in R/v0_annotation.R \name{dbAnnotate} \alias{dbAnnotate} \title{Annotate clonotypes in immune repertoires using clonotype databases (e.g., VDJDB, McPAS)} @@ -8,7 +8,7 @@ dbAnnotate(.data, .db, .data.col, .db.col) } \arguments{ \item{.data}{The data to process. It can be a \link{data.frame}, a -\link{data.table}, or a list of these objects. +\link[data.table:data.table]{data.table::data.table}, or a list of these objects. Every object must have columns in the immunarch compatible format. \link{immunarch_data_format} diff --git a/man/dbLoad.Rd b/man/dbLoad.Rd index a4aaaaf6..88b3c41a 100644 --- a/man/dbLoad.Rd +++ b/man/dbLoad.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/annotation.R +% Please edit documentation in R/v0_annotation.R \name{dbLoad} \alias{dbLoad} \title{Load clonotype databases such as VDJDB and McPAS into the R workspace} diff --git a/man/dot-quant_column_choice.Rd b/man/dot-quant_column_choice.Rd index 5831881b..db8b9382 100644 --- a/man/dot-quant_column_choice.Rd +++ b/man/dot-quant_column_choice.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{.quant_column_choice} \alias{.quant_column_choice} \title{Get a column's name using the input alias} diff --git a/man/entropy.Rd b/man/entropy.Rd index 1e0c624c..8d750c30 100644 --- a/man/entropy.Rd +++ b/man/entropy.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/info_theory.R +% Please edit documentation in R/v0_info_theory.R \name{entropy} \alias{entropy} \alias{kl_div} diff --git a/man/fixVis.Rd b/man/fixVis.Rd index 295cca89..03ff421d 100644 --- a/man/fixVis.Rd +++ b/man/fixVis.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/shiny.R +% Please edit documentation in R/v0_shiny.R \name{fixVis} \alias{fixVis} \title{Manipulate ggplot plots and create publication-ready plots} @@ -13,6 +13,8 @@ fixVis(.plot = NA) No return value because it is an application. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + The \code{fixVis} is a built-in software tool for the manipulation of plots, such as adjusting title text font and size, axes, and more. It is a powerful tool designed to produce publication-ready plots with minimal amount of coding. diff --git a/man/geneUsage.Rd b/man/geneUsage.Rd index fe830fe4..fd019ce9 100644 --- a/man/geneUsage.Rd +++ b/man/geneUsage.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/gene_usage.R +% Please edit documentation in R/v0_gene_usage.R \name{geneUsage} \alias{geneUsage} \alias{get_aliases} diff --git a/man/geneUsageAnalysis.Rd b/man/geneUsageAnalysis.Rd index d456a579..a1e19cb6 100644 --- a/man/geneUsageAnalysis.Rd +++ b/man/geneUsageAnalysis.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/gene_usage_analysis.R +% Please edit documentation in R/v0_gene_usage_analysis.R \name{geneUsageAnalysis} \alias{geneUsageAnalysis} \title{Post-analysis of V-gene and J-gene statistics: PCA, clustering, etc.} diff --git a/man/gene_segments.Rd b/man/gene_segments.Rd index 7f9ef638..6e81d885 100644 --- a/man/gene_segments.Rd +++ b/man/gene_segments.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/data_docs.R +% Please edit documentation in R/v0_data_docs.R \docType{data} \name{gene_segments} \alias{gene_segments} diff --git a/man/gene_stats.Rd b/man/gene_stats.Rd index 3fcb8876..1da224a6 100644 --- a/man/gene_stats.Rd +++ b/man/gene_stats.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/gene_usage.R +% Please edit documentation in R/v0_gene_usage.R \name{gene_stats} \alias{gene_stats} \title{WIP} @@ -16,4 +16,4 @@ WIP gene_stats() get_genes("hs.trbv", "segment") } -\concept{gene_usage} +\concept{data} diff --git a/man/getKmers.Rd b/man/getKmers.Rd index 1c34e395..f1b8c1c7 100644 --- a/man/getKmers.Rd +++ b/man/getKmers.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/kmers.R +% Please edit documentation in R/v0_kmers.R \name{getKmers} \alias{getKmers} \alias{get.kmers} diff --git a/man/get_immunarch_news.Rd b/man/get_immunarch_news.Rd index 96040132..e623626f 100644 --- a/man/get_immunarch_news.Rd +++ b/man/get_immunarch_news.Rd @@ -24,3 +24,4 @@ If no matching update is found, a warning is issued along with available update \seealso{ \code{\link[=list_immunarch_news]{list_immunarch_news()}} } +\concept{migration_utility} diff --git a/man/group_from_metadata.Rd b/man/group_from_metadata.Rd index e9bce0a7..eb720f0e 100644 --- a/man/group_from_metadata.Rd +++ b/man/group_from_metadata.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{group_from_metadata} \alias{group_from_metadata} \title{Get a character vector of samples' groups from the input metadata file} diff --git a/man/has_class.Rd b/man/has_class.Rd index 6d7a39db..1f42a004 100644 --- a/man/has_class.Rd +++ b/man/has_class.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{has_class} \alias{has_class} \title{Check for the specific class} diff --git a/man/im_common_args.Rd b/man/im_common_args.Rd new file mode 100644 index 00000000..94fb8612 --- /dev/null +++ b/man/im_common_args.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/aaa-registry.R +\name{im_common_args} +\alias{im_common_args} +\title{Common arguments for immundata helpers} +\usage{ +im_common_args( + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL +) +} +\arguments{ +\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. +For \code{format="analysis"}, metadata is joined to the long table; for +\code{format="ml"}, it’s joined after pivoting to wide. Defaults to +\code{getOption("immundata.autojoin", FALSE)}.} + +\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet +columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} + +\item{features}{Character vector of \strong{feature keys} to keep when +\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key +looks like \verb{family.method|facet1=...;facet2=...} (e.g., +\code{airr_stats.genes|v_call=TRBV7-2}).} +} +\description{ +Common arguments for immundata helpers +} +\keyword{internal} diff --git a/man/immdata.Rd b/man/immdata.Rd index 658a0973..4b659f8d 100644 --- a/man/immdata.Rd +++ b/man/immdata.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/data_docs.R +% Please edit documentation in R/v0_data_docs.R \docType{data} \name{immdata} \alias{immdata} diff --git a/man/immunarch_v1_updates.Rd b/man/immunarch_v1_updates.Rd index 00b0c453..be0ba856 100644 --- a/man/immunarch_v1_updates.Rd +++ b/man/immunarch_v1_updates.Rd @@ -3,7 +3,7 @@ \docType{data} \name{immunarch_v1_updates} \alias{immunarch_v1_updates} -\title{Some description} +\title{Get a list of package updates} \format{ An object of class \code{list} of length 1. } @@ -11,6 +11,7 @@ An object of class \code{list} of length 1. immunarch_v1_updates } \description{ -Some description +Get a list of package updates } +\concept{migration_utility} \keyword{datasets} diff --git a/man/immunr_data_format.Rd b/man/immunr_data_format.Rd index 0d24fe99..94d8f6fb 100644 --- a/man/immunr_data_format.Rd +++ b/man/immunr_data_format.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/immunr_data_format.R +% Please edit documentation in R/v0_immunr_data_format.R \docType{data} \name{immunr_data_format} \alias{immunr_data_format} diff --git a/man/immunr_hclust.Rd b/man/immunr_hclust.Rd index 9f167951..c5dd80bc 100644 --- a/man/immunr_hclust.Rd +++ b/man/immunr_hclust.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/clustering.R +% Please edit documentation in R/v0_clustering.R \name{immunr_hclust} \alias{immunr_hclust} \alias{immunr_kmeans} diff --git a/man/immunr_pca.Rd b/man/immunr_pca.Rd index 264ac2bf..65124b91 100644 --- a/man/immunr_pca.Rd +++ b/man/immunr_pca.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dimensions.R +% Please edit documentation in R/v0_dimensions.R \name{immunr_pca} \alias{immunr_pca} \alias{immunr_mds} @@ -26,17 +26,17 @@ if you want to visualise results.} \item{.dist}{If TRUE then assumes that ".data" is a distance matrix.} -\item{.perp}{The perplexity parameter for \link[Rtsne:Rtsne]{Rtsne}. Specifies the number +\item{.perp}{The perplexity parameter for Rtsne. Specifies the number of neighbors each data point must have in the resulting plot.} -\item{...}{Other parameters passed to \link[Rtsne:Rtsne]{Rtsne}.} +\item{...}{Other parameters passed to Rtsne.} } \value{ \code{immunr_pca} - an output from \link{prcomp}. -\code{immunr_mds} - an output from \link[MASS:isoMDS]{isoMDS}. +\code{immunr_mds} - an output from isoMDS. -\code{immunr_tsne} - an output from [Rtsne][Rtsne::Rtsne]. +\code{immunr_tsne} - an output from Rtsne. } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} @@ -47,8 +47,8 @@ sometimes more accurate, since it also reduces noise in the data. Currently avai methods are: \itemize{ \item \code{immunr_pca} performs PCA (Principal Component Analysis) using \link{prcomp}; -\item \code{immunr_mds} performs MDS (Multi-Dimensional Scaling) using \link[MASS:isoMDS]{isoMDS}; -\item \code{immunr_tsne} performs tSNE (t-Distributed Stochastic Neighbour Embedding) using \link[Rtsne:Rtsne]{Rtsne}. +\item \code{immunr_mds} performs MDS (Multi-Dimensional Scaling) using isoMODS from MASS package. +\item \code{immunr_tsne} performs tSNE (t-Distributed Stochastic Neighbour Embedding) using Rtsne Rtsne package. } } \examples{ diff --git a/man/inc_overlap.Rd b/man/inc_overlap.Rd index b2f25451..743ccaec 100644 --- a/man/inc_overlap.Rd +++ b/man/inc_overlap.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/overlap.R +% Please edit documentation in R/v0_overlap.R \name{inc_overlap} \alias{inc_overlap} \title{Incremental counting of repertoire similarity} diff --git a/man/list_immunarch_news.Rd b/man/list_immunarch_news.Rd index 983fbe68..1c559391 100644 --- a/man/list_immunarch_news.Rd +++ b/man/list_immunarch_news.Rd @@ -15,3 +15,4 @@ Returns the list of available update keys for immunarch v1. \seealso{ \code{\link[=get_immunarch_news]{get_immunarch_news()}} } +\concept{migration_utility} diff --git a/man/matrixdiagcopy.Rd b/man/matrixdiagcopy.Rd index 27751646..2661e85d 100644 --- a/man/matrixdiagcopy.Rd +++ b/man/matrixdiagcopy.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{matrixdiagcopy} \alias{matrixdiagcopy} \title{Copy the upper matrix triangle to the lower one} @@ -19,7 +19,7 @@ Copy the upper matrix triangle to the lower one mat <- matrix(0, 3, 3) mat -mat\link{1, 3} <- 1 +mat(1, 3) <- 1 mat <- immunarch:::matrixdiagcopy(mat) mat } diff --git a/man/pubRep.Rd b/man/pubRep.Rd index f0dc4ff0..a5f83bb5 100644 --- a/man/pubRep.Rd +++ b/man/pubRep.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/public.R +% Please edit documentation in R/v0_public.R \name{pubRep} \alias{pubRep} \alias{publicRepertoire} diff --git a/man/pubRepApply.Rd b/man/pubRepApply.Rd index 6890eff7..5c8f8405 100644 --- a/man/pubRepApply.Rd +++ b/man/pubRepApply.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/public.R +% Please edit documentation in R/v0_public.R \name{pubRepApply} \alias{pubRepApply} \alias{publicRepertoireApply} @@ -20,7 +20,7 @@ found in both public repertoires.} Work in progress. } \description{ -Work In Progress +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/pubRepFilter.Rd b/man/pubRepFilter.Rd index 5acb9dbc..b8191ca9 100644 --- a/man/pubRepFilter.Rd +++ b/man/pubRepFilter.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/public.R +% Please edit documentation in R/v0_public.R \name{pubRepFilter} \alias{pubRepFilter} \alias{publicRepertoireFilter} diff --git a/man/pubRepStatistics.Rd b/man/pubRepStatistics.Rd index c8f66f97..a93bd13d 100644 --- a/man/pubRepStatistics.Rd +++ b/man/pubRepStatistics.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/public.R +% Please edit documentation in R/v0_public.R \name{pubRepStatistics} \alias{pubRepStatistics} \title{Statistics of number of public clonotypes for each possible combinations of repertoires} diff --git a/man/public_matrix.Rd b/man/public_matrix.Rd index 07ea842d..539d4824 100644 --- a/man/public_matrix.Rd +++ b/man/public_matrix.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/public.R +% Please edit documentation in R/v0_public.R \name{public_matrix} \alias{public_matrix} \title{Get a matrix with public clonotype frequencies} @@ -13,7 +13,7 @@ public_matrix(.data) Matrix with per-sample clonotype counts / proportions only. } \description{ -Get a matrix with public clonotype frequencies +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/repAlignLineage.Rd b/man/repAlignLineage.Rd index 7d204ba1..ad565f41 100644 --- a/man/repAlignLineage.Rd +++ b/man/repAlignLineage.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/align_lineage.R +% Please edit documentation in R/v0_align_lineage.R \name{repAlignLineage} \alias{repAlignLineage} \title{Aligns all sequences incliding germline within each clonal lineage within each cluster} diff --git a/man/repClonalFamily.Rd b/man/repClonalFamily.Rd index 1ba573c3..64b3468c 100644 --- a/man/repClonalFamily.Rd +++ b/man/repClonalFamily.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/phylip.R +% Please edit documentation in R/v0_phylip.R \name{repClonalFamily} \alias{repClonalFamily} \title{Builds a phylogenetic tree using the sequences of a clonal lineage} diff --git a/man/repClonality.Rd b/man/repClonality.Rd index 99a7949a..d537b8ce 100644 --- a/man/repClonality.Rd +++ b/man/repClonality.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/clonality.R +% Please edit documentation in R/v0_clonality.R \name{repClonality} \alias{repClonality} \alias{clonality} diff --git a/man/repDiversity.Rd b/man/repDiversity.Rd index 20726616..c5835f6f 100644 --- a/man/repDiversity.Rd +++ b/man/repDiversity.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/diversity.R +% Please edit documentation in R/v0_diversity.R \name{repDiversity} \alias{repDiversity} \alias{chao1} diff --git a/man/repExplore.Rd b/man/repExplore.Rd index 95d64565..a94eec0e 100644 --- a/man/repExplore.Rd +++ b/man/repExplore.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/explore.R +% Please edit documentation in R/v0_explore.R \name{repExplore} \alias{repExplore} \title{Main function for exploratory data analysis: compute the distribution of lengths, clones, etc.} diff --git a/man/repFilter.Rd b/man/repFilter.Rd index 461e945a..d136490c 100644 --- a/man/repFilter.Rd +++ b/man/repFilter.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/filters.R +% Please edit documentation in R/v0_filters.R \name{repFilter} \alias{repFilter} \alias{include} diff --git a/man/repGermline.Rd b/man/repGermline.Rd index b1d129eb..652916d8 100644 --- a/man/repGermline.Rd +++ b/man/repGermline.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/germline.R +% Please edit documentation in R/v0_germline.R \name{repGermline} \alias{repGermline} \title{Creates germlines for clonal lineages} diff --git a/man/repLoad.Rd b/man/repLoad.Rd index cf25b39a..516c8878 100644 --- a/man/repLoad.Rd +++ b/man/repLoad.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/io.R +% Please edit documentation in R/v0_io.R \name{repLoad} \alias{repLoad} \title{Load immune repertoire files into the R workspace} diff --git a/man/repOverlap.Rd b/man/repOverlap.Rd index e173c351..0677ac6d 100644 --- a/man/repOverlap.Rd +++ b/man/repOverlap.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/overlap.R +% Please edit documentation in R/v0_overlap.R \name{repOverlap} \alias{repOverlap} \title{Main function for public clonotype statistics calculations} diff --git a/man/repOverlapAnalysis.Rd b/man/repOverlapAnalysis.Rd index 096765e6..d4cdf1e9 100644 --- a/man/repOverlapAnalysis.Rd +++ b/man/repOverlapAnalysis.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/overlap_analysis.R +% Please edit documentation in R/v0_overlap_analysis.R \name{repOverlapAnalysis} \alias{repOverlapAnalysis} \title{Post-analysis of public clonotype statistics: PCA, clustering, etc.} diff --git a/man/repSample.Rd b/man/repSample.Rd index 673fa89e..f1c1bc06 100644 --- a/man/repSample.Rd +++ b/man/repSample.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/sampling.R +% Please edit documentation in R/v0_sampling.R \name{repSample} \alias{repSample} \title{Downsampling and resampling of immune repertoires} @@ -38,6 +38,8 @@ repertoires to the size of the smallest repertoire in the ".data".} Subsampled immune repertoire or a list of subsampled immune repertoires. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Sample (downsample) repertoires using different approches. } \details{ diff --git a/man/repSave.Rd b/man/repSave.Rd index c6052fb6..3ac73066 100644 --- a/man/repSave.Rd +++ b/man/repSave.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/io.R +% Please edit documentation in R/v0_io.R \name{repSave} \alias{repSave} \title{Save immune repertoires to the disk} @@ -35,7 +35,7 @@ does not exist it will be created automatically. \examples{ data(immdata) # Reduce data to save time on examples -immdata$data <- purrr::map(immdata$data, ~ .x \%>\% head(10)) +immdata$data <- map(immdata$data, ~ .x \%>\% head(10)) dirpath <- tempdir() # Save the list of repertoires repSave(immdata, dirpath) diff --git a/man/repSomaticHypermutation.Rd b/man/repSomaticHypermutation.Rd index e4e9bd11..4ec0fc15 100644 --- a/man/repSomaticHypermutation.Rd +++ b/man/repSomaticHypermutation.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/somatic_hypermutation.R +% Please edit documentation in R/v0_somatic_hypermutation.R \name{repSomaticHypermutation} \alias{repSomaticHypermutation} \title{Calculates number of mutations against the germline for each clonotype} diff --git a/man/scdata.Rd b/man/scdata.Rd index 56bb170e..b395e3bd 100644 --- a/man/scdata.Rd +++ b/man/scdata.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/data_docs.R +% Please edit documentation in R/v0_data_docs.R \docType{data} \name{scdata} \alias{scdata} diff --git a/man/select_barcodes.Rd b/man/select_barcodes.Rd index 500dd115..3b00c2b5 100644 --- a/man/select_barcodes.Rd +++ b/man/select_barcodes.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/singlecell.R +% Please edit documentation in R/v0_singlecell.R \name{select_barcodes} \alias{select_barcodes} \title{Select specific clonotypes using barcodes from single-cell metadata} diff --git a/man/select_clusters.Rd b/man/select_clusters.Rd index d018c477..cfd01257 100644 --- a/man/select_clusters.Rd +++ b/man/select_clusters.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/singlecell.R +% Please edit documentation in R/v0_singlecell.R \name{select_clusters} \alias{select_clusters} \title{Split the immune repertoire data to clusters from single-cell barcodes} diff --git a/man/seqCluster.Rd b/man/seqCluster.Rd index f6a6a24a..f112051a 100644 --- a/man/seqCluster.Rd +++ b/man/seqCluster.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/seqCluster.R +% Please edit documentation in R/v0_seqCluster.R \name{seqCluster} \alias{seqCluster} \title{Function for assigning clusters based on sequences similarity} diff --git a/man/seqDist.Rd b/man/seqDist.Rd index 76c8523e..a521cb62 100644 --- a/man/seqDist.Rd +++ b/man/seqDist.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/distance.R +% Please edit documentation in R/v0_distance.R \name{seqDist} \alias{seqDist} \title{Function for computing distance for sequences} @@ -48,7 +48,7 @@ Computing sequential distances between clonotypes from two repertoires: data(immdata) # Reducing data to save time on examples -immdata$data <- purrr::map(immdata$data, ~ .x \%>\% head(10)) +immdata$data <- map(immdata$data, ~ .x \%>\% head(10)) # Computing hamming distance for the first two repertoires in `'immdata'` seqDist(immdata$data[1:2]) diff --git a/man/set_pb.Rd b/man/set_pb.Rd index 69682d05..1787395b 100644 --- a/man/set_pb.Rd +++ b/man/set_pb.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{set_pb} \alias{set_pb} \alias{add_pb} diff --git a/man/spectratype.Rd b/man/spectratype.Rd index fa7e3ecd..46c0014e 100644 --- a/man/spectratype.Rd +++ b/man/spectratype.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/spectratyping.R +% Please edit documentation in R/v0_spectratyping.R \name{spectratype} \alias{spectratype} \title{Immune repertoire spectratyping} diff --git a/man/split_to_kmers.Rd b/man/split_to_kmers.Rd index 02702dca..13f65399 100644 --- a/man/split_to_kmers.Rd +++ b/man/split_to_kmers.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/kmers.R +% Please edit documentation in R/v0_kmers.R \name{split_to_kmers} \alias{split_to_kmers} \alias{kmer_profile} diff --git a/man/switch_type.Rd b/man/switch_type.Rd index 898ce890..4d911208 100644 --- a/man/switch_type.Rd +++ b/man/switch_type.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tools.R +% Please edit documentation in R/v0_tools.R \name{switch_type} \alias{switch_type} \alias{process_col_argument} diff --git a/man/top.Rd b/man/top.Rd index 54ca1083..d46f40e1 100644 --- a/man/top.Rd +++ b/man/top.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/preprocessing.R +% Please edit documentation in R/v0_preprocessing.R \name{top} \alias{top} \title{Get the N most abundant clonotypes} diff --git a/man/trackClonotypes.Rd b/man/trackClonotypes.Rd index a259b176..22c93398 100644 --- a/man/trackClonotypes.Rd +++ b/man/trackClonotypes.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/dynamics.R +% Please edit documentation in R/v0_dynamics.R \name{trackClonotypes} \alias{trackClonotypes} \title{Track clonotypes across time and data points} diff --git a/man/vis.Rd b/man/vis.Rd index 418b9805..22f92818 100644 --- a/man/vis.Rd +++ b/man/vis.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis} \alias{vis} \title{One function to visualise them all} @@ -15,6 +15,8 @@ vis(.data, ...) A ggplot2, pheatmap or circlize object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Output from every function in immunarch can be visualised with a single function - \code{vis}. The \code{vis} automatically detects the type of the data and draws a proper visualisation. For example, output diff --git a/man/vis.clonal_family.Rd b/man/vis.clonal_family.Rd index 1a9045f0..dcdcc33d 100644 --- a/man/vis.clonal_family.Rd +++ b/man/vis.clonal_family.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.clonal_family} \alias{vis.clonal_family} \title{Visualise clonal family tree: wrapper for calling on the entire repClonalFamily output} @@ -15,7 +15,7 @@ A ggraph object. } \description{ -Visualise clonal family tree: wrapper for calling on the entire repClonalFamily output +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(bcrdata) diff --git a/man/vis.clonal_family_tree.Rd b/man/vis.clonal_family_tree.Rd index 50048c34..d88d3feb 100644 --- a/man/vis.clonal_family_tree.Rd +++ b/man/vis.clonal_family_tree.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.clonal_family_tree} \alias{vis.clonal_family_tree} \title{Visualise clonal family tree} @@ -15,7 +15,7 @@ A ggraph object. } \description{ -Visualise clonal family tree +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(bcrdata) diff --git a/man/vis.immunr_chao1.Rd b/man/vis.immunr_chao1.Rd index efb9f105..8f8f9384 100644 --- a/man/vis.immunr_chao1.Rd +++ b/man/vis.immunr_chao1.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_chao1} \alias{vis.immunr_chao1} \alias{vis.immunr_dxx} @@ -56,6 +56,8 @@ Disabled if no group passed to the ".by" argument.} A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + An utility function to visualise the output from \code{\link[=repDiversity]{repDiversity()}}. } \details{ diff --git a/man/vis.immunr_clonal_prop.Rd b/man/vis.immunr_clonal_prop.Rd index 99c2def4..7834b015 100644 --- a/man/vis.immunr_clonal_prop.Rd +++ b/man/vis.immunr_clonal_prop.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_clonal_prop} \alias{vis.immunr_clonal_prop} \alias{vis.immunr_homeo} @@ -53,6 +53,8 @@ Disabled if no group passed to the ".by" argument.} A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + An utility function to visualise the output from \code{\link[=repClonality]{repClonality()}}. } \details{ diff --git a/man/vis.immunr_dynamics.Rd b/man/vis.immunr_dynamics.Rd index f26c5af2..668ff6e6 100644 --- a/man/vis.immunr_dynamics.Rd +++ b/man/vis.immunr_dynamics.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_dynamics} \alias{vis.immunr_dynamics} \title{Visualise clonotype dynamics} @@ -22,7 +22,7 @@ by timepoints. Either See "Examples" below for more details.} A ggplot2 object. } \description{ -Visualise clonotype dynamics +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ # Load an example data that comes with immunarch diff --git a/man/vis.immunr_exp_vol.Rd b/man/vis.immunr_exp_vol.Rd index e293d429..b8e54b15 100644 --- a/man/vis.immunr_exp_vol.Rd +++ b/man/vis.immunr_exp_vol.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_exp_vol} \alias{vis.immunr_exp_vol} \alias{vis.immunr_exp_count} @@ -53,6 +53,8 @@ Disabled if no group passed to the ".by" argument.} A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + An utility function to visualise the output from \code{\link[=repExplore]{repExplore()}}. } \details{ diff --git a/man/vis.immunr_gene_usage.Rd b/man/vis.immunr_gene_usage.Rd index b66c92a2..c252977b 100644 --- a/man/vis.immunr_gene_usage.Rd +++ b/man/vis.immunr_gene_usage.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_gene_usage} \alias{vis.immunr_gene_usage} \title{Histograms and boxplots (general case / gene usage)} @@ -30,6 +30,8 @@ A ggplot2 object, pheatmap or circlize object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualise distributions of genes using heatmaps or other plots. } \examples{ diff --git a/man/vis.immunr_hclust.Rd b/man/vis.immunr_hclust.Rd index f0afb565..0499dc8f 100644 --- a/man/vis.immunr_hclust.Rd +++ b/man/vis.immunr_hclust.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_hclust} \alias{vis.immunr_hclust} \title{Visualisation of hierarchical clustering} @@ -21,6 +21,8 @@ If both then plot both.} Ggplot2 objects inside the patchwork container. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualisation of the results of hierarchical clustering. For other clustering visualisations see \link{vis.immunr_kmeans}. } diff --git a/man/vis.immunr_inc_overlap.Rd b/man/vis.immunr_inc_overlap.Rd index 24641b63..a065de3d 100644 --- a/man/vis.immunr_inc_overlap.Rd +++ b/man/vis.immunr_inc_overlap.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_inc_overlap} \alias{vis.immunr_inc_overlap} \title{Visualise incremental overlaps} @@ -21,7 +21,7 @@ A ggplot2 object. } \description{ -Visualise incremental overlaps +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/vis.immunr_kmeans.Rd b/man/vis.immunr_kmeans.Rd index 8b126de2..ce090099 100644 --- a/man/vis.immunr_kmeans.Rd +++ b/man/vis.immunr_kmeans.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_kmeans} \alias{vis.immunr_kmeans} \alias{vis.immunr_dbscan} @@ -39,6 +39,8 @@ If both then plot both.} Ggplot2 objects inside the pathwork container. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualisation of the results of K-means and DBSCAN clustering. For hierarhical clustering visualisations see \link{vis.immunr_hclust}. } diff --git a/man/vis.immunr_kmer_table.Rd b/man/vis.immunr_kmer_table.Rd index 1b63dc00..f9d513a2 100644 --- a/man/vis.immunr_kmer_table.Rd +++ b/man/vis.immunr_kmer_table.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_kmer_table} \alias{vis.immunr_kmer_table} \title{Most frequent kmers visualisation.} @@ -27,6 +27,8 @@ A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Plot a distribution (bar plot) of the most frequent kmers in a data. } \examples{ diff --git a/man/vis.immunr_mds.Rd b/man/vis.immunr_mds.Rd index ba9de7f6..ba731d9e 100644 --- a/man/vis.immunr_mds.Rd +++ b/man/vis.immunr_mds.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_mds} \alias{vis.immunr_mds} \alias{vis.immunr_pca} @@ -51,7 +51,7 @@ such as age, serostatus or hla.} A ggplot2 object. } \description{ -PCA / MDS / tSNE visualisation (mainly overlap / gene usage) +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \details{ Other visualisation methods: diff --git a/man/vis.immunr_ov_matrix.Rd b/man/vis.immunr_ov_matrix.Rd index 55b705ea..1982dfcc 100644 --- a/man/vis.immunr_ov_matrix.Rd +++ b/man/vis.immunr_ov_matrix.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_ov_matrix} \alias{vis.immunr_ov_matrix} \alias{vis.immunr_gu_matrix} @@ -28,6 +28,8 @@ A ggplot2, pheatmap or circlize object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualises matrices with overlap values or gene usage distances among samples. For details see the links below. } diff --git a/man/vis.immunr_public_repertoire.Rd b/man/vis.immunr_public_repertoire.Rd index 46bb421e..691a3477 100644 --- a/man/vis.immunr_public_repertoire.Rd +++ b/man/vis.immunr_public_repertoire.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_public_repertoire} \alias{vis.immunr_public_repertoire} \title{Public repertoire visualisation} @@ -24,7 +24,7 @@ depending on the ".plot" argument.} A ggplot2 object. } \description{ -Public repertoire visualisation +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/vis.immunr_public_statistics.Rd b/man/vis.immunr_public_statistics.Rd index 929a165e..c794b99e 100644 --- a/man/vis.immunr_public_statistics.Rd +++ b/man/vis.immunr_public_statistics.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.immunr_public_statistics} \alias{vis.immunr_public_statistics} \title{Visualise sharing of clonotypes among samples} @@ -15,6 +15,8 @@ A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualise public clonotype frequencies. } \examples{ diff --git a/man/vis.step_failure_ignored.Rd b/man/vis.step_failure_ignored.Rd index 26b86dd6..fee68222 100644 --- a/man/vis.step_failure_ignored.Rd +++ b/man/vis.step_failure_ignored.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis.step_failure_ignored} \alias{vis.step_failure_ignored} \title{Handler for .nofail argument of pipeline steps that prevents examples from crashing @@ -16,6 +16,5 @@ on computers where certain dependencies are not installed} An empty object with "step_failure_ignored" class. } \description{ -Handler for .nofail argument of pipeline steps that prevents examples from crashing -on computers where certain dependencies are not installed +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } diff --git a/man/vis_bar.Rd b/man/vis_bar.Rd index 53ae786d..10e33e93 100644 --- a/man/vis_bar.Rd +++ b/man/vis_bar.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_bar} \alias{vis_bar} \title{Bar plots} @@ -80,7 +80,7 @@ Disabled if no group passed to the ".by" argument.} A ggplot2 object. } \description{ -Bar plots +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ vis_bar(data.frame(Sample = c("A", "B", "C"), Value = c(1, 2, 3))) diff --git a/man/vis_box.Rd b/man/vis_box.Rd index 9d99d139..8619aa74 100644 --- a/man/vis_box.Rd +++ b/man/vis_box.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_box} \alias{vis_box} \title{Flexible box-plots for visualisation of distributions} @@ -69,6 +69,8 @@ Each numeric column should be associated with a specific repertoire sample.} A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualisation of distributions using ggplot2-based boxplots. } \examples{ diff --git a/man/vis_circos.Rd b/man/vis_circos.Rd index a39c2245..590fa615 100644 --- a/man/vis_circos.Rd +++ b/man/vis_circos.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_circos} \alias{vis_circos} \title{Visualisation of matrices using circos plots} @@ -17,6 +17,8 @@ vis_circos(.data, .title = NULL, ...) A circlize object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualise matrices with the \link[circlize:chordDiagram]{circlize::chordDiagram} function from the circlize package. } diff --git a/man/vis_heatmap.Rd b/man/vis_heatmap.Rd index 8f675a06..412becb5 100644 --- a/man/vis_heatmap.Rd +++ b/man/vis_heatmap.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_heatmap} \alias{vis_heatmap} \title{Visualisation of matrices and data frames using ggplo2-based heatmaps} @@ -57,6 +57,8 @@ just plot coloured cells instead.} A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Fast and easy visualisations of matrices or data frames with functions based on the ggplot2 package. } diff --git a/man/vis_heatmap2.Rd b/man/vis_heatmap2.Rd index a6eb3aa4..87fa2055 100644 --- a/man/vis_heatmap2.Rd +++ b/man/vis_heatmap2.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_heatmap2} \alias{vis_heatmap2} \title{Visualisation of matrices using pheatmap-based heatmaps} @@ -33,6 +33,8 @@ Pass NA to use the default pheatmap colors.} A pheatmap object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualise matrices with the functions based on the \link[pheatmap:pheatmap]{pheatmap} package with minimum amount of arguments. } diff --git a/man/vis_hist.Rd b/man/vis_hist.Rd index 46d3201f..900d95fe 100644 --- a/man/vis_hist.Rd +++ b/man/vis_hist.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_hist} \alias{vis_hist} \title{Visualisation of distributions using histograms} @@ -68,6 +68,8 @@ If NA automatically detects the best way to display legend.} A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualisation of distributions using ggplot2-based histograms. } \details{ diff --git a/man/vis_immunr_kmer_profile_main.Rd b/man/vis_immunr_kmer_profile_main.Rd index befdaf29..8362f4f4 100644 --- a/man/vis_immunr_kmer_profile_main.Rd +++ b/man/vis_immunr_kmer_profile_main.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_immunr_kmer_profile_main} \alias{vis_immunr_kmer_profile_main} \title{Visualise kmer profiles} @@ -22,7 +22,7 @@ on the ".plot" argument.} A ggplot2 object. } \description{ -Visualise kmer profiles +#' \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ data(immdata) diff --git a/man/vis_public_clonotypes.Rd b/man/vis_public_clonotypes.Rd index 1fe84823..f774d4c5 100644 --- a/man/vis_public_clonotypes.Rd +++ b/man/vis_public_clonotypes.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_public_clonotypes} \alias{vis_public_clonotypes} \title{Visualisation of public clonotypes} @@ -48,6 +48,8 @@ for the R adjusted coefficient.} A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualise correlation of public clonotype frequencies in pairs of repertoires. } \examples{ diff --git a/man/vis_public_frequencies.Rd b/man/vis_public_frequencies.Rd index b587b261..8cbdbc01 100644 --- a/man/vis_public_frequencies.Rd +++ b/man/vis_public_frequencies.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_public_frequencies} \alias{vis_public_frequencies} \title{Public repertoire visualisation} @@ -34,6 +34,8 @@ such as age, serostatus or hla.} A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Visualise public clonotype frequencies. } \examples{ diff --git a/man/vis_textlogo.Rd b/man/vis_textlogo.Rd index 6e67796d..1bc76907 100644 --- a/man/vis_textlogo.Rd +++ b/man/vis_textlogo.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/v0-vis.R +% Please edit documentation in R/v0_vis.R \name{vis_textlogo} \alias{vis_textlogo} \alias{vis_seqlogo} @@ -20,12 +20,14 @@ to plot points on the straight vertical line for each position.} \item{...}{Not used here.} -\item{.scheme}{Character. An argument passed to \link[ggseqlogo:geom_logo]{ggseqlogo::geom_logo} specifying how to colour symbols.} +\item{.scheme}{Character. An argument passed to geom_logo from ggseqlogo package specifying how to colour symbols.} } \value{ A ggplot2 object. } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + Plot sequence logo plots for visualising of amino acid motif sequences / profiles. \code{vis_textlogo} plots sequences in a text format - each letter has the same height. Useful when there From 3216c0b9778b465e18f546b7cacfbc246b0d601c Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:26:57 +0200 Subject: [PATCH 16/36] chore: basic stuff like purrr and globals --- R/aaa-registry.R | 79 ++++++++++++ R/globals.R | 10 ++ R/immunarch-package.R | 53 ++++++++ R/import-standalone-purrr.R | 244 ++++++++++++++++++++++++++++++++++++ R/v1_aaa_registry_utils.R | 77 ++++++++++++ 5 files changed, 463 insertions(+) create mode 100644 R/aaa-registry.R create mode 100644 R/globals.R create mode 100644 R/import-standalone-purrr.R create mode 100644 R/v1_aaa_registry_utils.R diff --git a/R/aaa-registry.R b/R/aaa-registry.R new file mode 100644 index 00000000..3d536317 --- /dev/null +++ b/R/aaa-registry.R @@ -0,0 +1,79 @@ +IMMUNARCH_METHOD_REGISTRY <- new.env(parent = emptyenv()) + + +#' Common arguments for immundata helpers +#' @keywords internal +#' @param autojoin If TRUE, join repertoire metadata by the schema repertoire id. +#' For `format="analysis"`, metadata is joined to the long table; for +#' `format="ml"`, it’s joined after pivoting to wide. Defaults to +#' `getOption("immundata.autojoin", FALSE)`. +#' @param format One of `"analysis"` (long tibble with `repertoire_id`, facet +#' columns, and `value`) or `"ml"` (wide/unmelted table of features). +#' @param features Character vector of **feature keys** to keep when +#' `format="ml"`. If `NULL`, features are derived from the data. A feature key +#' looks like `family.method|facet1=...;facet2=...` (e.g., +#' `airr_stats.genes|v_call=TRBV7-2`). +im_common_args <- function( + autojoin = getOption("immundata.autojoin", FALSE), + format = c("analysis", "ml"), + features = NULL) {} # nocov + + +im_method <- function(core, family, name) { + checkmate::assert_function(core, args = c("idata")) + checkmate::assert_string(family) + checkmate::assert_string(name) + + # Merge core formals with wrapper defaults to enable autocompletion + core_fmls <- formals(core) + if (!"idata" %in% names(core_fmls)) { + cli::cli_abort("Core method must declare an {.code idata} argument.") + } + if (any(c("autojoin", "format", "features") %in% names(core_fmls))) { + cli::cli_abort("Core method must not declare {.code autojoin}, {.code format}, or {.code features}.") + } + + wrapper <- function() { } + formals(wrapper) <- c( + core_fmls, + formals(im_common_args) + ) + environment(wrapper) <- environment() + + body(wrapper) <- substitute( + { + format <- match.arg(format) + + # Pre: validate idata + schema + checkmate::assert_r6(idata, "ImmunData") + + # Build argument list for core from our own formals (now visible to the user) + .core_args <- mget(names(core_fmls), inherits = TRUE) + out <- do.call(core, .core_args) + + out + }, + list(core = core, core_fmls = core_fmls) + ) + + wrapper +} + + +register_immunarch_method <- function(core, family, name, register_family = TRUE) { + fn <- im_method(core, family, name) + + if (isTRUE(register_family) && exists("register_airr_family", mode = "function", inherits = TRUE)) { + try(register_airr_family(family), silent = TRUE) + } + + if (exists("register_airr_method", mode = "function", inherits = TRUE)) { + try(register_airr_method( + family_name = family, + method_name = name, + fn = fn + ), silent = TRUE) + } + + fn +} diff --git a/R/globals.R b/R/globals.R new file mode 100644 index 00000000..7ffdbaa6 --- /dev/null +++ b/R/globals.R @@ -0,0 +1,10 @@ +utils::globalVariables(c( + "index", + "richness", + "shannon", + "dd" +)) + +#' @keywords internal +#' @importFrom rlang as_function inject global_env is_logical is_true set_names .data .env +NULL diff --git a/R/immunarch-package.R b/R/immunarch-package.R index bd1d6689..a6330ec6 100644 --- a/R/immunarch-package.R +++ b/R/immunarch-package.R @@ -1,5 +1,58 @@ ## usethis namespace: start +#' @importFrom checkmate assert_character +#' @importFrom checkmate assert_choice +#' @importFrom checkmate assert_data_frame +#' @importFrom checkmate assert_logical +#' @importFrom checkmate assert_numeric +#' @importFrom checkmate assert_r6 +#' @importFrom cli cli_alert_info +#' @importFrom cli cli_alert_success +#' @importFrom cli cli_alert_warning +#' @importFrom cli cli_bullets +#' @importFrom cli cli_end +#' @importFrom cli cli_h1 +#' @importFrom cli cli_inform +#' @importFrom cli cli_par +#' @importFrom cli cli_text +#' @importFrom cli spark_line +#' @importFrom cli start_app +#' @importFrom dbplyr sql +#' @importFrom dplyr all_of +#' @importFrom dplyr arrange +#' @importFrom dplyr compute +#' @importFrom dplyr count +#' @importFrom dplyr distinct +#' @importFrom dplyr filter +#' @importFrom dplyr intersect +#' @importFrom dplyr left_join +#' @importFrom dplyr mutate +#' @importFrom dplyr n +#' @importFrom dplyr pull +#' @importFrom dplyr right_join +#' @importFrom dplyr select +#' @importFrom dplyr slice_head +#' @importFrom dplyr summarise +#' @importFrom dplyr union +#' @importFrom dplyr union_all +#' @importFrom duckplyr as_duckdb_tibble +#' @importFrom duckplyr as_tbl +#' @importFrom immundata imd_schema +#' @importFrom immundata ImmunData +#' @importFrom lifecycle deprecated +#' @importFrom purrr map_df +#' @importFrom purrr map_dfr +#' @importFrom purrr map2_df #' @importFrom Rcpp sourceCpp +#' @importFrom rlang .data +#' @importFrom rlang .env +#' @importFrom rlang as_function +#' @importFrom rlang global_env +#' @importFrom rlang inject +#' @importFrom rlang is_logical +#' @importFrom rlang is_true +#' @importFrom rlang set_names +#' @importFrom rlang sym +#' @importFrom utils globalVariables #' @useDynLib immunarch, .registration = TRUE ## usethis namespace: end NULL diff --git a/R/import-standalone-purrr.R b/R/import-standalone-purrr.R new file mode 100644 index 00000000..4ec36e12 --- /dev/null +++ b/R/import-standalone-purrr.R @@ -0,0 +1,244 @@ +# Standalone file: do not edit by hand +# Source: +# ---------------------------------------------------------------------- +# +# --- +# repo: r-lib/rlang +# file: standalone-purrr.R +# last-updated: 2023-02-23 +# license: https://unlicense.org +# imports: rlang +# --- +# +# This file provides a minimal shim to provide a purrr-like API on top of +# base R functions. They are not drop-in replacements but allow a similar style +# of programming. +# +# ## Changelog +# +# 2023-02-23: +# * Added `list_c()` +# +# 2022-06-07: +# * `transpose()` is now more consistent with purrr when inner names +# are not congruent (#1346). +# +# 2021-12-15: +# * `transpose()` now supports empty lists. +# +# 2021-05-21: +# * Fixed "object `x` not found" error in `imap()` (@mgirlich) +# +# 2020-04-14: +# * Removed `pluck*()` functions +# * Removed `*_cpl()` functions +# * Used `as_function()` to allow use of `~` +# * Used `.` prefix for helpers +# +# nocov start + +map <- function(.x, .f, ...) { + .f <- as_function(.f, env = global_env()) + lapply(.x, .f, ...) +} +walk <- function(.x, .f, ...) { + map(.x, .f, ...) + invisible(.x) +} + +map_lgl <- function(.x, .f, ...) { + .rlang_purrr_map_mold(.x, .f, logical(1), ...) +} +map_int <- function(.x, .f, ...) { + .rlang_purrr_map_mold(.x, .f, integer(1), ...) +} +map_dbl <- function(.x, .f, ...) { + .rlang_purrr_map_mold(.x, .f, double(1), ...) +} +map_chr <- function(.x, .f, ...) { + .rlang_purrr_map_mold(.x, .f, character(1), ...) +} +.rlang_purrr_map_mold <- function(.x, .f, .mold, ...) { + .f <- as_function(.f, env = global_env()) + out <- vapply(.x, .f, .mold, ..., USE.NAMES = FALSE) + names(out) <- names(.x) + out +} + +map2 <- function(.x, .y, .f, ...) { + .f <- as_function(.f, env = global_env()) + out <- mapply(.f, .x, .y, MoreArgs = list(...), SIMPLIFY = FALSE) + if (length(out) == length(.x)) { + set_names(out, names(.x)) + } else { + set_names(out, NULL) + } +} +map2_lgl <- function(.x, .y, .f, ...) { + as.vector(map2(.x, .y, .f, ...), "logical") +} +map2_int <- function(.x, .y, .f, ...) { + as.vector(map2(.x, .y, .f, ...), "integer") +} +map2_dbl <- function(.x, .y, .f, ...) { + as.vector(map2(.x, .y, .f, ...), "double") +} +map2_chr <- function(.x, .y, .f, ...) { + as.vector(map2(.x, .y, .f, ...), "character") +} +imap <- function(.x, .f, ...) { + map2(.x, names(.x) %||% seq_along(.x), .f, ...) +} + +pmap <- function(.l, .f, ...) { + .f <- as.function(.f) + args <- .rlang_purrr_args_recycle(.l) + do.call("mapply", c( + FUN = list(quote(.f)), + args, MoreArgs = quote(list(...)), + SIMPLIFY = FALSE, USE.NAMES = FALSE + )) +} +.rlang_purrr_args_recycle <- function(args) { + lengths <- map_int(args, length) + n <- max(lengths) + + stopifnot(all(lengths == 1L | lengths == n)) + to_recycle <- lengths == 1L + args[to_recycle] <- map(args[to_recycle], function(x) rep.int(x, n)) + + args +} + +keep <- function(.x, .f, ...) { + .x[.rlang_purrr_probe(.x, .f, ...)] +} +discard <- function(.x, .p, ...) { + sel <- .rlang_purrr_probe(.x, .p, ...) + .x[is.na(sel) | !sel] +} +map_if <- function(.x, .p, .f, ...) { + matches <- .rlang_purrr_probe(.x, .p) + .x[matches] <- map(.x[matches], .f, ...) + .x +} +.rlang_purrr_probe <- function(.x, .p, ...) { + if (is_logical(.p)) { + stopifnot(length(.p) == length(.x)) + .p + } else { + .p <- as_function(.p, env = global_env()) + map_lgl(.x, .p, ...) + } +} + +compact <- function(.x) { + Filter(length, .x) +} + +transpose <- function(.l) { + if (!length(.l)) { + return(.l) + } + + inner_names <- names(.l[[1]]) + + if (is.null(inner_names)) { + fields <- seq_along(.l[[1]]) + } else { + fields <- set_names(inner_names) + .l <- map(.l, function(x) { + if (is.null(names(x))) { + set_names(x, inner_names) + } else { + x + } + }) + } + + # This way missing fields are subsetted as `NULL` instead of causing + # an error + .l <- map(.l, as.list) + + map(fields, function(i) { + map(.l, .subset2, i) + }) +} + +every <- function(.x, .p, ...) { + .p <- as_function(.p, env = global_env()) + + for (i in seq_along(.x)) { + if (!rlang::is_true(.p(.x[[i]], ...))) { + return(FALSE) + } + } + TRUE +} +some <- function(.x, .p, ...) { + .p <- as_function(.p, env = global_env()) + + for (i in seq_along(.x)) { + if (rlang::is_true(.p(.x[[i]], ...))) { + return(TRUE) + } + } + FALSE +} +negate <- function(.p) { + .p <- as_function(.p, env = global_env()) + function(...) !.p(...) +} + +reduce <- function(.x, .f, ..., .init) { + f <- function(x, y) .f(x, y, ...) + Reduce(f, .x, init = .init) +} +reduce_right <- function(.x, .f, ..., .init) { + f <- function(x, y) .f(y, x, ...) + Reduce(f, .x, init = .init, right = TRUE) +} +accumulate <- function(.x, .f, ..., .init) { + f <- function(x, y) .f(x, y, ...) + Reduce(f, .x, init = .init, accumulate = TRUE) +} +accumulate_right <- function(.x, .f, ..., .init) { + f <- function(x, y) .f(y, x, ...) + Reduce(f, .x, init = .init, right = TRUE, accumulate = TRUE) +} + +detect <- function(.x, .f, ..., .right = FALSE, .p = is_true) { + .p <- as_function(.p, env = global_env()) + .f <- as_function(.f, env = global_env()) + + for (i in .rlang_purrr_index(.x, .right)) { + if (.p(.f(.x[[i]], ...))) { + return(.x[[i]]) + } + } + NULL +} +detect_index <- function(.x, .f, ..., .right = FALSE, .p = is_true) { + .p <- as_function(.p, env = global_env()) + .f <- as_function(.f, env = global_env()) + + for (i in .rlang_purrr_index(.x, .right)) { + if (.p(.f(.x[[i]], ...))) { + return(i) + } + } + 0L +} +.rlang_purrr_index <- function(x, right = FALSE) { + idx <- seq_along(x) + if (right) { + idx <- rev(idx) + } + idx +} + +list_c <- function(x) { + inject(c(!!!x)) +} + +# nocov end diff --git a/R/v1_aaa_registry_utils.R b/R/v1_aaa_registry_utils.R new file mode 100644 index 00000000..7c8e3051 --- /dev/null +++ b/R/v1_aaa_registry_utils.R @@ -0,0 +1,77 @@ +make_immunarch_method_record <- function(fn, method_name, ...) { + list( + fn = fn, + method_name = method_name + ) +} + +register_airr_family <- function(family_name) { + fam_env <- IMMUNARCH_METHOD_REGISTRY[[family_name]] + + if (is.null(fam_env)) { + fam_env <- new.env(parent = emptyenv()) + IMMUNARCH_METHOD_REGISTRY[[family_name]] <- fam_env + } +} + +register_airr_method <- function(family_name, method_name, fn) { + # checkmate checks + + fam_env <- IMMUNARCH_METHOD_REGISTRY[[family_name]] + + assign(method_name, + make_immunarch_method_record( + fn = fn, + method_name = method_name + ), + envir = fam_env + ) +} + +get_airr_method <- function(family_name, method_name, verbose = TRUE) { + # checkmate checks + + fam_env <- IMMUNARCH_METHOD_REGISTRY[[family_name]] + + if (is.null(method_name)) { + if (verbose) { + cli::cli_text("Available methods in {.code {family_name}}:") + cli::cli_ol(ls(fam_env)) + return(invisible(ls(fam_env))) + } else { + return(ls(fam_env)) + } + } else { + # check and throw an error if no such object + record <- get0(method_name, envir = fam_env, ifnotfound = NULL) + + if (is.null(record)) { + cli::cli_abort("No such method: {.code {method_name}}. Available methods: {ls(fam_env)}") + } + + record + } +} + +make_airr_dispatcher <- function(family_name) { + # checkmate for family_name + + function(idata = NULL, method = NULL, ...) { + checkmate::assert_r6(idata, "ImmunData", null.ok = TRUE) + checkmate::assert_character(method, null.ok = TRUE) + + if (is.null(idata)) { + # list available methods for this family + get_airr_method(family_name, NULL) + } else if (is.null(method)) { + cli::cli_abort("{.code idata} provided, but {.code method} is null, aborting the execution; please provide either both {.code idata} and {.code method}, or leave them as nulls to show the list of available methods") + } else { + checkmate::assert_data_frame(idata$repertoires, null.ok = FALSE) + + record <- get_airr_method(family_name, method) + fn <- record$fn + res <- fn(idata, ...) + res + } + } +} From d4612dc0f21179998da75cc484175aeb9cebee3e Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:27:12 +0200 Subject: [PATCH 17/36] docs: few minor docs change --- R/v1_airr_clonality.R | 2 +- R/v1_airr_diversity.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/v1_airr_clonality.R b/R/v1_airr_clonality.R index 98c6f3ec..a1e37c9e 100644 --- a/R/v1_airr_clonality.R +++ b/R/v1_airr_clonality.R @@ -3,7 +3,7 @@ #' @description #' `r lifecycle::badge("experimental")` #' -#' A family of functions to quantify **receptor overabundance** per repertoire. +#' A family of functions to quantify **receptor overabundance** per repertoire. Helps in deciphering the structure and partition the repertoire. #' #' ## Available functions: #' diff --git a/R/v1_airr_diversity.R b/R/v1_airr_diversity.R index a499b331..47995428 100644 --- a/R/v1_airr_diversity.R +++ b/R/v1_airr_diversity.R @@ -3,7 +3,7 @@ #' @description #' `r lifecycle::badge("experimental")` #' -#' A family of functions to quantify **receptor diversity** per repertoire. +#' A family of functions to quantify **receptor diversity** per repertoire. A characteristic of a whole repertoire. #' #' ## Available functions: #' From 6802c7de4a1598030e756da599d340a486d9142e Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:27:28 +0200 Subject: [PATCH 18/36] feat: airr_public as a new syste --- R/v1_airr_public.R | 138 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 R/v1_airr_public.R diff --git a/R/v1_airr_public.R b/R/v1_airr_public.R new file mode 100644 index 00000000..6c8089af --- /dev/null +++ b/R/v1_airr_public.R @@ -0,0 +1,138 @@ +#' @title Public indices — pairwise repertoire overlap +#' +#' @description +#' `r lifecycle::badge("experimental")` +#' +#' A family of functions to quantify **public or shared receptors** between repertoire. +#' +#' ## Available functions: +#' +#' @param idata An `ImmunData` object. +#' @inheritParams airr_public_intersection +#' @inheritParams airr_public_jaccard +#' @inheritParams im_common_args +#' +#' @seealso [immundata::ImmunData] +#' +#' @name airr_public +#' @concept Public indices +NULL + + +#' @keywords internal +airr_public_intersection_impl <- function(idata) { + receptor_id_col <- immundata::imd_schema("receptor") + repertoire_id_col <- immundata::imd_schema("repertoire") + repertoire_ids <- idata$repertoires |> + pull({{ repertoire_id_col }}) |> + unique() + + result_matrix <- matrix(-1, nrow = length(repertoire_ids), ncol = length(repertoire_ids)) + + for (i in seq_along(repertoire_ids[-length(repertoire_ids)])) { + for (j in seq_along(repertoire_ids[(i + 1):length(repertoire_ids)])) { + rep_1_index <- repertoire_ids[i] + rep_2_index <- repertoire_ids[i + j] + + val_pub <- idata$annotations |> + filter(!!rlang::sym(repertoire_id_col) == rep_1_index, !!rlang::sym(repertoire_id_col) == rep_2_index) |> + distinct(!!rlang::sym(repertoire_id_col)) |> + count() |> + pull("n") + + result_matrix[rep_1_index, rep_2_index] <- val_pub + result_matrix[rep_2_index, rep_1_index] <- val_pub + } + } + + result_matrix +} + +#' @description `airr_public_intersection` — number of **shared receptors** between +#' each pair of repertoires (intersection size). Handy for quick overlap heatmaps, +#' QC of replicate similarity, or spotting donor-shared “public” clonotypes. +#' +#' @return +#' +#' ## `airr_public_intersection` +#' A **symmetric numeric matrix** where rows/columns are `repertoire_id` and each +#' cell is the count of shared unique receptors. The diagonal contains per-repertoire +#' richness (total unique receptors). Row/column names are repertoire IDs. +#' +#' @examples +#' # +#' # airr_public_intersection +#' # +#' m_pub <- airr_public_intersection(immdata) +#' +#' @rdname airr_public +#' @concept Public indices +#' @export +airr_public_intersection <- register_immunarch_method(airr_public_intersection_impl, "airr_public", "intersection") + + +#' @keywords internal +airr_public_jaccard_impl <- function(idata) { + receptor_id_col <- immundata::imd_schema("receptor") + repertoire_id_col <- immundata::imd_schema("repertoire") + repertoire_ids <- idata$repertoires |> + pull({{ repertoire_id_col }}) |> + unique() + + result_matrix <- matrix(-1, nrow = length(repertoire_ids), ncol = length(repertoire_ids)) + + for (i in seq_along(repertoire_ids[-length(repertoire_ids)])) { + for (j in seq_along(repertoire_ids[(i + 1):length(repertoire_ids)])) { + rep_1_index <- repertoire_ids[i] + rep_2_index <- repertoire_ids[i + j] + + repertoire_pair <- idata$annotations |> + filter(!!rlang::sym(repertoire_id_col) %in% c(rep_1_index, rep_2_index)) |> + select({{ repertoire_id_col }}, {{ receptor_id_col }}) + + rep_1 <- repertoire_pair |> + filter(!!rlang::sym(repertoire_id_col) == rep_1_index) |> + select({{ receptor_id_col }}) + rep_2 <- repertoire_pair |> + filter(!!rlang::sym(repertoire_id_col) == rep_2_index) |> + select({{ receptor_id_col }}) + + val_inter <- intersect(rep_1, rep_2) |> + count() |> + pull("n") + val_union <- union(rep_1, rep_2) |> + count() |> + pull("n") + + result_matrix[rep_1_index, rep_2_index] <- val_inter / val_union + result_matrix[rep_2_index, rep_1_index] <- val_inter / val_union + } + } + + result_matrix +} + + +#' @description `airr_public_jaccard` — **Jaccard similarity** of receptor +#' sets between repertoires (`|A∩B| / |A∪B|`). Best when comparing cohorts with +#' different sizes to get a scale-invariant overlap score. +#' +#' @inheritParams im_common_args +#' +#' @return +#' +#' ## `airr_public_jaccard` +#' A **symmetric numeric matrix** where rows/columns are `repertoire_id` and each +#' cell is the Jaccard similarity in `[0, 1]`. The diagonal is `1`. Row/column +#' names are repertoire IDs. +#' +#' @examples +#' # +#' # airr_public_jaccard +#' # +#' m_jac <- airr_public_jaccard(immdata) +#' +#' @rdname airr_public +#' @concept Public indices +#' @export +airr_public_jaccard <- register_immunarch_method(airr_public_jaccard_impl, "airr_public", "jaccard") From 059c53511c91b10f832528800b48fff201715cac Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:27:53 +0200 Subject: [PATCH 19/36] chore: necessary chores --- .Rbuildignore | 3 +++ .gitignore | 1 + DESCRIPTION | 29 ++++++++++++--------------- NAMESPACE | 54 +++++++++++++++++++++++++++++++++++++++------------ 4 files changed, 58 insertions(+), 29 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 06c1fb56..012bf463 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -24,3 +24,6 @@ ^.idea$ ^cran-comments\.md$ ^vignettes/*_files$ +^wip-.* +^vignettes/articles$ +^vignettes/.quarto$ diff --git a/.gitignore b/.gitignore index 7096ad0d..a10450c6 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ docs/* vignettes/web_only/*.html immunr.Rproj cran-comments.md +wip-* diff --git a/DESCRIPTION b/DESCRIPTION index 36fe9b58..902bbfc0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -7,10 +7,7 @@ Authors@R: c( comment = c(ORCID = "0000-0003-3659-2709")), person("Vasily O.", "Tsvetkov", , role = "aut"), person("Aleksandr A.", "Popov", , role = "aut"), - person("Ivan", "Balashov", , role = "aut"), - person("Maria", "Samokhina", , role = "aut"), - person("Daniel J.", "Moore", , role = "ctb"), - person("ImmunoMind", role = c("cph", "fnd")) + person("Ivan", "Balashov", , role = "aut") ) Contact: support@immunomind.com Description: A comprehensive framework for bioinformatics exploratory analysis of bulk and single-cell @@ -27,29 +24,24 @@ BugReports: https://github.com/immunomind/immunarch/issues Depends: R (>= 4.1.0), ggplot2 (>= 3.1.0), - immundata (>= 0.0.2.9002), + immundata (>= 0.0.3), patchwork Imports: - dplyr (>= 0.8.0), + dplyr, dtplyr (>= 1.0.0), data.table (>= 1.12.6), cli, pheatmap (>= 1.0.12), reshape2 (>= 1.4.2), circlize, - MASS (>= 7.3), - Rtsne (>= 0.15), airr, - ggseqlogo, Rcpp (>= 1.0), magrittr, methods, scales, rlang, plyr, - purrr, stringdist, - jsonlite, readr, stringr, tibble, @@ -60,15 +52,12 @@ Imports: rlist, utils, glue, - uuid, - stringi, checkmate, duckplyr, dbplyr, - lifecycle + lifecycle, + purrr LinkingTo: Rcpp -Remotes: - immunomind/immundata-rlang Suggests: knitr (>= 1.8), roxygen2 (>= 3.0.0), @@ -80,17 +69,23 @@ Suggests: fpc, ggpubr (>= 0.2), ggraph, + ggseqlogo, igraph, phangorn, ggalluvial (>= 0.10.0), UpSetR (>= 1.4.0), ggrepel (>= 0.8.0), shiny (>= 1.4.0), - shinythemes + shinythemes, + quarto, + MASS (>= 7.3), + Rtsne (>= 0.15) VignetteBuilder: + knitr, quarto Encoding: UTF-8 RoxygenNote: 7.3.2 LazyData: true LazyDataCompression: xz Roxygen: list(markdown = TRUE) +Config/Needs/website: rmarkdown diff --git a/NAMESPACE b/NAMESPACE index e7180f9b..018fb042 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -46,6 +46,19 @@ S3method(vis,immunr_spectr_nogene) S3method(vis,immunr_top_prop) S3method(vis,immunr_tsne) S3method(vis,step_failure_ignored) +export(airr_clonality_line) +export(airr_clonality_prop) +export(airr_clonality_rank) +export(airr_diversity_dxx) +export(airr_diversity_hill) +export(airr_diversity_index) +export(airr_diversity_pielou) +export(airr_diversity_shannon) +export(airr_public_intersection) +export(airr_public_jaccard) +export(airr_stats_chains) +export(airr_stats_genes) +export(airr_stats_lengths) export(apply_asymm) export(apply_symm) export(bunch_translate) @@ -125,6 +138,12 @@ importFrom(Rcpp,sourceCpp) importFrom(ape,as.DNAbin) importFrom(ape,clustal) importFrom(ape,read.tree) +importFrom(checkmate,assert_character) +importFrom(checkmate,assert_choice) +importFrom(checkmate,assert_data_frame) +importFrom(checkmate,assert_logical) +importFrom(checkmate,assert_numeric) +importFrom(checkmate,assert_r6) importFrom(circlize,chordDiagram) importFrom(cli,cli_alert_info) importFrom(cli,cli_alert_success) @@ -147,12 +166,16 @@ importFrom(data.table,setDF) importFrom(data.table,setDT) importFrom(data.table,setcolorder) importFrom(data.table,setnames) +importFrom(dbplyr,sql) importFrom(doParallel,registerDoParallel) importFrom(doParallel,stopImplicitCluster) +importFrom(dplyr,all_of) importFrom(dplyr,arrange) importFrom(dplyr,as_tibble) importFrom(dplyr,collect) +importFrom(dplyr,compute) importFrom(dplyr,contains) +importFrom(dplyr,count) importFrom(dplyr,cur_group_id) importFrom(dplyr,desc) importFrom(dplyr,distinct) @@ -163,30 +186,37 @@ importFrom(dplyr,group_by) importFrom(dplyr,group_by_at) importFrom(dplyr,group_keys) importFrom(dplyr,group_map) +importFrom(dplyr,intersect) importFrom(dplyr,left_join) importFrom(dplyr,mutate) importFrom(dplyr,n) importFrom(dplyr,one_of) importFrom(dplyr,pull) importFrom(dplyr,rename) +importFrom(dplyr,right_join) importFrom(dplyr,row_number) importFrom(dplyr,rowwise) importFrom(dplyr,select) importFrom(dplyr,select_) importFrom(dplyr,select_if) +importFrom(dplyr,slice_head) importFrom(dplyr,summarise) importFrom(dplyr,tally) importFrom(dplyr,top_n) importFrom(dplyr,ungroup) +importFrom(dplyr,union) +importFrom(dplyr,union_all) importFrom(dtplyr,lazy_dt) -importFrom(ggseqlogo,geom_logo) -importFrom(ggseqlogo,theme_logo) +importFrom(duckplyr,as_duckdb_tibble) +importFrom(duckplyr,as_tbl) importFrom(glue,glue) importFrom(grDevices,colorRampPalette) importFrom(graphics,plot) importFrom(grid,gpar) importFrom(grid,rectGrob) -importFrom(jsonlite,read_json) +importFrom(immundata,ImmunData) +importFrom(immundata,imd_schema) +importFrom(lifecycle,deprecated) importFrom(magrittr,"%<>%") importFrom(magrittr,"%>%") importFrom(magrittr,extract2) @@ -205,17 +235,10 @@ importFrom(plyr,.) importFrom(plyr,adply) importFrom(plyr,dlply) importFrom(plyr,mapvalues) -importFrom(purrr,imap) -importFrom(purrr,map) -importFrom(purrr,map2) -importFrom(purrr,map2_chr) importFrom(purrr,map2_df) -importFrom(purrr,map2_lgl) importFrom(purrr,map_chr) importFrom(purrr,map_df) importFrom(purrr,map_dfr) -importFrom(purrr,map_lgl) -importFrom(purrr,pmap) importFrom(readr,col_character) importFrom(readr,col_double) importFrom(readr,col_guess) @@ -227,6 +250,14 @@ importFrom(readr,read_delim) importFrom(readr,read_tsv) importFrom(readr,write_lines) importFrom(reshape2,melt) +importFrom(rlang,.data) +importFrom(rlang,.env) +importFrom(rlang,as_function) +importFrom(rlang,global_env) +importFrom(rlang,inject) +importFrom(rlang,is_logical) +importFrom(rlang,is_true) +importFrom(rlang,set_names) importFrom(rlang,sym) importFrom(rlist,list.remove) importFrom(scales,percent) @@ -242,7 +273,6 @@ importFrom(stats,qnorm) importFrom(stats,rmultinom) importFrom(stats,runif) importFrom(stringdist,stringdistmatrix) -importFrom(stringi,stri_replace_all_fixed) importFrom(stringr,boundary) importFrom(stringr,fixed) importFrom(stringr,str_c) @@ -268,10 +298,10 @@ importFrom(tidyselect,all_of) importFrom(tidyselect,any_of) importFrom(tidyselect,starts_with) importFrom(utils,capture.output) +importFrom(utils,globalVariables) importFrom(utils,packageVersion) importFrom(utils,read.table) importFrom(utils,setTxtProgressBar) importFrom(utils,tail) importFrom(utils,txtProgressBar) -importFrom(uuid,UUIDgenerate) useDynLib(immunarch, .registration = TRUE) From ce46dd856d016716778fa5bd637df3f06905eee8 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:28:28 +0200 Subject: [PATCH 20/36] chore --- tests/testthat/test-distance.R | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/testthat/test-distance.R b/tests/testthat/test-distance.R index 0ebf4eaa..c868bb7c 100644 --- a/tests/testthat/test-distance.R +++ b/tests/testthat/test-distance.R @@ -1,5 +1,4 @@ data(immdata) -library(purrr) short_immdata <- map(immdata$data, ~ .x %>% head(1000)) # smaller sample size saves time in computations f <- function(x, y) { From 71a2537fb3a39c6e7ca8381912a412e179dbe241 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:28:40 +0200 Subject: [PATCH 21/36] refactor: vignette and website refactoring --- _pkgdown.yml | 249 +++++----- vignettes/.gitignore | 4 + vignettes/articles/.gitignore | 2 + vignettes/articles/singlecell.qmd | 483 +++++++++++++++++++ vignettes/immunarch.qmd | 196 ++++++++ vignettes/web_only_v0/BCRpipeline.Rmd | 40 +- vignettes/web_only_v0/clustering.Rmd | 20 +- vignettes/{ => web_only_v0}/data.Rmd | 0 vignettes/{ => web_only_v0}/introduction.Rmd | 0 vignettes/web_only_v0/repFilter_v3.Rmd | 10 +- vignettes/web_only_v0/v21_singlecell.Rmd | 8 +- vignettes/web_only_v1/receptor_track.Rmd | 60 --- 12 files changed, 838 insertions(+), 234 deletions(-) create mode 100644 vignettes/articles/.gitignore create mode 100644 vignettes/articles/singlecell.qmd create mode 100644 vignettes/immunarch.qmd rename vignettes/{ => web_only_v0}/data.Rmd (100%) rename vignettes/{ => web_only_v0}/introduction.Rmd (100%) delete mode 100644 vignettes/web_only_v1/receptor_track.Rmd diff --git a/_pkgdown.yml b/_pkgdown.yml index e6e95042..fe6f3732 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1,198 +1,177 @@ url: https://immunarch.com template: + bootstrap: 5 params: - bootswatch: cosmo + bootswatch: flatly ganalytics: UA-128418614-2 - docsearch: - api_key: '94207562f34b455c0796790d104e3549' - index_name: 'immunarch' authors: ImmunoMind: - href: https://immunomind.io + href: https://immunomind.com Vadim I. Nazarov: href: https://www.linkedin.com/in/vdnaz Vasily O. Tsvetkov: href: https://www.linkedin.com/in/vasily-tsvetkov-227218ab - Siarhei Fiadziushchanka: - href: https://www.linkedin.com/in/sergey-f-709b0415b/ - Eugene Rumynskiy: - href: https://www.linkedin.com/in/erumynskiy/ Aleksandr A. Popov: href: https://www.linkedin.com/in/aleksandr-popov-634878105/ Ivan Balashov: href: https://www.linkedin.com/in/ivan-balashov/ - Maria Samokhina: - href: https://www.linkedin.com/in/maria-volobueva-b0856a223/ articles: -- title: All tutorials +- title: "immunarch v1.0" desc: ~ contents: - - '`v1_introduction`' - - '`v2_data`' - - '`web_only/v21_singlecell`' - - '`web_only/v3_basic_analysis`' - - '`web_only/load_mixcr`' - - '`web_only/load_10x`' - - '`web_only/v4_overlap`' - - '`web_only/v5_gene_usage`' - - '`web_only/v6_diversity`' - - '`web_only/v7_fixvis`' - - '`web_only/v8_tracking`' - - '`web_only/v9_kmers`' - - '`web_only/v11_db`' - - '`web_only/community`' - - '`web_only/repFilter_v3`' - - '`web_only/v10_prop`' - - '`web_only/BCRpipeline`' - - '`web_only/clustering`' + - immunarch + - articles/singlecell +- title: "immunarch v0.9" + desc: ~ + contents: + - '`web_only_v0/introduction`' + - '`web_only_v0/data`' + - '`web_only_v0/v21_singlecell`' + - '`web_only_v0/v3_basic_analysis`' + - '`web_only_v0/load_mixcr`' + - '`web_only_v0/load_10x`' + - '`web_only_v0/v4_overlap`' + - '`web_only_v0/v5_gene_usage`' + - '`web_only_v0/v6_diversity`' + - '`web_only_v0/v7_fixvis`' + - '`web_only_v0/v8_tracking`' + - '`web_only_v0/v9_kmers`' + - '`web_only_v0/v11_db`' + - '`web_only_v0/community`' + - '`web_only_v0/repFilter_v3`' + - '`web_only_v0/v10_prop`' + - '`web_only_v0/BCRpipeline`' + - '`web_only_v0/clustering`' navbar: structure: - left: [articles, reference, covid19] + left: [articles, reference, migration] right: [im_link, twitter, github] components: home: ~ news: ~ - covid19: - text: "COVID-19" - href: https://github.com/immunomind/covid19 + tutorial: + text: "⚡ Start Here - Tutorial for v1.0" + href: articles/singlecell.html + migration: + text: "🚢 Migration Guide" + href: articles/immunarch.html reference: - text: Reference + text: "Reference" href: reference/index.html articles: - text: Start Here + text: "Guides & Tutorials" menu: - - text: Installation & troubleshooting - href: articles/v1_introduction.html + - text: '---' + - text: "IMMUNARCH v1.0" + + # - text: "Tutorial for bulk/single-cell and single-/paired-chain data" + # href: articles/web_only_v1/tutorial_singlecell.html + + - text: '---' + - text: "... more coming soon ..." + + - text: '---' + - text: "IMMUNARCH v0.9" + + - text: '---' + - text: "Package" + + - text: "Installation & troubleshooting" + href: articles/web_only_v0/introduction.html + - text: '---' - text: First steps + - text: Data loading - href: articles/v2_data.html + href: articles/web_only_v0/data.html + - text: 'How-to: Loading MiXCR Data' - href: articles/web_only/load_mixcr.html + href: articles/web_only_v0/load_mixcr.html + - text: 'How-to: Loading 10x Genomics Data' - href: articles/web_only/load_10x.html + href: articles/web_only_v0/load_10x.html + - text: 'How-to: Single-cell and paired chain data' - href: articles/web_only/v21_singlecell.html + href: articles/web_only_v0/v21_singlecell.html + - text: Basic statistics and clonality - href: articles/web_only/v3_basic_analysis.html + href: articles/web_only_v0/v3_basic_analysis.html + - text: 'Data filtering' - href: articles/web_only/repFilter_v3.html + href: articles/web_only_v0/repFilter_v3.html + - text: '---' + - text: Repertoire-level exploration and comparison + - text: Repertoire overlap and public clonotypes - href: articles/web_only/v4_overlap.html + href: articles/web_only_v0/v4_overlap.html + - text: Gene usage - href: articles/web_only/v5_gene_usage.html + href: articles/web_only_v0/v5_gene_usage.html + - text: Diversity estimation - href: articles/web_only/v6_diversity.html + href: articles/web_only_v0/v6_diversity.html + - text: '---' + - text: Clonotype-level exploration and comparison + - text: Track clonotypes across samples and time - href: articles/web_only/v8_tracking.html + href: articles/web_only_v0/v8_tracking.html + - text: Annotate clonotypes using immune receptor databases - href: articles/web_only/v11_db.html + href: articles/web_only_v0/v11_db.html + - text: Kmer and sequence motif analysis and visualisation - href: articles/web_only/v9_kmers.html + href: articles/web_only_v0/v9_kmers.html + - text: '---' + - text: Preparing to publication + - text: Make your plots publication-ready with fixVis - href: articles/web_only/v7_fixvis.html + href: articles/web_only_v0/v7_fixvis.html + - text: '---' + - text: BCR analysis + - text: BCR pipeline - href: articles/web_only/BCRpipeline.html + href: articles/web_only_v0/BCRpipeline.html + - text: Clustering - href: articles/web_only/clustering.html + href: articles/web_only_v0/clustering.html twitter: icon: fa-lg fa-twitter href: http://twitter.com/immunomind im_link: text: ImmunoMind - href: https://immunomind.io + href: https://immunomind.com github: icon: fa-github href: https://github.com/immunomind/immunarch reference: -- title: Bulk and single-cell data -- subtitle: Loading and saving any data - contents: - - has_concept("io") -- subtitle: Filtering data - contents: - - has_concept("filters") -- subtitle: Single-cell - desc: More coming soon! - contents: - - has_concept("single_cell") -- subtitle: Preprocessing - contents: - - has_concept("preprocessing") -- title: BCR data -- subtitle: Clustering - contents: - - has_concept("distance") - - has_concept("seq_cluster") -- subtitle: BCR pipeline - contents: - - has_concept("germline") - - has_concept("align_lineage") - - has_concept("phylip") - - has_concept("somatic_hypermutation") -- title: Basic immune repertoire statistics -- subtitle: Exploratory data analysis - contents: - - has_concept("explore") -- subtitle: Clonality analysis - contents: - - has_concept("clonality") -- title: Clonotype annotation and dynamics -- subtitle: Clonotype annotation - desc: Annotate clonotypes in immune repertoires using external immune receptor databases (VDJDB, McPAS and PIRD). - contents: - - has_concept("annotation") -- subtitle: Immune repertoire dynamics - desc: Track the differences in clonotype abundances over time. - contents: - - has_concept("dynamics") -- title: Compare repertoires -- subtitle: Repertoire diversity analysis - contents: - - has_concept("diversity") -- subtitle: Gene usage - desc: V-gene and J-gene usage statistics, analysis and visualisations - contents: - - has_concept("gene_usage") -- subtitle: Overlap - contents: - - starts_with("repOverlap") - - has_concept("overlap") -- subtitle: Public repertoire - contents: - - has_concept("pubrep") -- title: Advanced immune repertoire analysis -- subtitle: Kmers analysis - contents: - - has_concept("k-mers") -- subtitle: Post-analysis - desc: Advanced methods for post-analysis of gene usage, overlap and other statistics. - contents: - - has_concept("post_analysis") -- title: Visualisations -- subtitle: General visualisation functions - desc: Functions for visualisations of different data types. For analysis-specific visualisation see related sections. - contents: - - starts_with("vis") - - has_concept("vis") -- subtitle: Publication-ready plots - contents: - - has_concept("fixvis") -- title: Utilities -- subtitle: Data - contents: +- title: Stable, v1.0 + +- contents: + - has_lifecycle("stable") + +- title: Experimental, v1.0 + +- contents: + - has_lifecycle("experimental") - has_concept("data") -- subtitle: Public utility utilities - contents: - - has_concept("utility_public") -- subtitle: Internal utility functions - contents: + - has_concept("migration_utility") + +- title: Under Question, v0.9 -> v1.0 + +- contents: - has_concept("utility_private") + - has_concept("utility_public") + - has_concept("preprocessing") + +- title: Deprecated, v0.9 + +- contents: + - has_lifecycle("deprecated") diff --git a/vignettes/.gitignore b/vignettes/.gitignore index 633fb800..771f764f 100644 --- a/vignettes/.gitignore +++ b/vignettes/.gitignore @@ -1 +1,5 @@ *_files +drafts* + +/.quarto/ +**/*.quarto_ipynb diff --git a/vignettes/articles/.gitignore b/vignettes/articles/.gitignore new file mode 100644 index 00000000..097b2416 --- /dev/null +++ b/vignettes/articles/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/articles/singlecell.qmd b/vignettes/articles/singlecell.qmd new file mode 100644 index 00000000..3d01d640 --- /dev/null +++ b/vignettes/articles/singlecell.qmd @@ -0,0 +1,483 @@ +--- +title: "Comprehensive analysis of single-cell immune repertoire data using `immunarch` and `immundata`" +author: "Vadim I. Nazarov" +date: "`r Sys.Date()`" +format: + html: + code-overflow: wrap + code-block-bg: true + code-block-border-left: "#31BAE9" + highlight-style: github + code-line-numbers: false + code-copy: true + toc: true + number-sections: true + # theme: none + # minimal: true +vignette: > + %\VignetteIndexEntry{Comprehensive analysis of single-cell immune repertoire data} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +--- + +## Introduction + +This vignette provides a comprehensive guide on how to analyse single-chain and paired-chain Adaptive Immune Receptor Repertoire (AIRR) data coming from scRNAseq (scVDJseq / scTCRseq / scBCRseq). This tutorils guides you from the very basics to the more advanced steps. The aim is to have a great starting point for both beginners in AIRR data analysis and experts who want specificaly learn `immunarch` and `immundata`. + +We will use data from the study for patient no. 6. The data will have three samples - tumor, blood, and healthy tissue surrounding the tumor. The core idea of the study is to ... + +To ask a question, report a bug, or take a look at the source code, following the GitHub links for [immunarch](https://github.com/immunomind/immunarch) and [immundata](https://github.com/immunomind/immundata). + +To use ChatGPT for interactive helper, use [AIRR-GPT](https://chatgpt.com/g/g-67fe54e302348191814e4ef2efb3bad5-airr-gpt) - a GPT Store model with uploaded documentation for both `immunarch` and `immundata`. + +### Migration from v0.9 to v1.0 + +This is a section for user who already use immunarch. If you are a new user, you can safely skip it and move directly to the **Setup** section, where we will install `immunarch` (together!) and start analysing *your* immune repertoire data. + +#### High-level overview of v1.0 changes + +There are several important changes in the v1.0 version in comparison to v0.9.x versions. + +1) working with data + +2) API changes - backwards compatability + +**Watch for Deprecation Warnings** + - If you see console messages about “deprecated” or “will be removed in v1.1.0,” update your code ASAP.\ + +3) moving packages from Depends to Suggests + +3) working with visualisatiobns - hard to make publication ready - https://github.com/CerrenRichards/ggplot2-for-publications + +Take a look at themes here: https://cran.r-project.org/web/packages/ggsci/vignettes/ggsci.html and https://emilhvitfeldt.github.io/r-color-palettes/ + +For more information and updates, please see the guide here: ... + +To list updates, run the function in console + +#### If you want to work with `immunarch` v0.9 **only** + +To freeze the latest stable version of `immunarch` before `1.0`, you could provide the exact version: + + - **pak** --- `pak::pkg_install("immunarch@=0.9.1")` + + - **install.packages** --- `install.packages("https://cran.r-project.org/src/contrib/Archive/immunarch/immunarch_0.9.1.tar.gz", repos = NULL, type = "source")` + + - **conda** --- `mamba install -c conda-forge r-immunarch=0.9.1` + +#### New data processing backend --- `immundata` + +... + +#### Motivation behind the changes + +... + + +#### Concluding thoughts on migration + +... + +--- + +## Setup + +### Pre-requisites + +... + +```{r} +#| eval: false +install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/stable/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch)) + +pak::pkg_install("immunomind/immunarch") +pak::pkg_install("Seurat") +pak::pkg_install("BiocFileCache") +pak::pkg_install("ggthemes") +pak::pkg_install("ggsci") +``` + +### Load necessary packages and setup + +... + +```{r} +#| label: load-immunarch +#| eval: !expr requireNamespace("Seurat", quietly = TRUE) && requireNamespace("ggthemes", quietly = TRUE) +#| echo: true +#| message: false +#| warning: false + +library("immunarch") +library("Seurat") + +theme_set(ggthemes::theme_few()) +``` + +--- + +## Quick overview + +### Typical workflow + +analyse -> visualise -> write back to Seurat -> visualise Seurat + +--- + +## Working with data + +### Load the prepackaged dataset + +First, we get paths to the metadata table and load it. Metadata is a tab-separate table with rows per sample or file, and columns for different per-sample feature such as "Tissue" or "Donor" or "Immunotherapy response". + +```{r} +#| label: load-dataset-metadata + +md_file <- system.file("extdata/single_cell", "metadata.tsv", package = "immundata") +md_file + +md_table <- immundata::read_metadata(md_file) +md_table +``` + +The metadata table contains the column "Tissue" and we will use it to split data into repertoires. But this is only the beginning - read more to learn how to split data by annotated cell clusters from scRNAseq data and computate statistics on those newly defined repertoires - on-the-fly and without reloading the whole dataset into the environment again. + +Next, we get the file paths to the data packaged with `immundata`. + +```{r} +#| label: load-dataset-files +#| +inp_files <- paste0(system.file("extdata/single_cell", "", package = "immundata"), "/*.csv.gz") +inp_files +``` + +TODO: EXPLAIN MORE WHAT THE RECEPTOR IS IN IMMUNDATA MODEL + +Then, we are ready to load AIRR data. We define a logical unit of analysis - a receptor - as a `"cdr3+v_call"` and will use only the `"TRB"` chain: + +```{r} +#| label: load-dataset-schema +#| eval: true + +schema <- make_receptor_schema(features = c("cdr3", "v_call"), chains = c("TRB")) +schema +``` + +If you want to use other receptor schemas, you can use the `make_receptor_schema()` function to create schemas and pass them to `read_repertoires()`. The dataset we use for this tutorial can support other schemas as well, including the paired-chain data: + +```{r} +#| label: load-dataset-schema-examples +#| eval: true + +# Paired-chain +schema <- make_receptor_schema(features = c("cdr3", "v_call"), chains = c("TRA", "TRB")) +schema + +# Single-chain with "cdr3" only +schema <- make_receptor_schema(features = c("cdr3"), chains = c("TRA")) +schema + +# The most strict receptor definition +schema <- make_receptor_schema(features = c("cdr3", "v_call", "j_call"), chains = c("TRA", "TRB")) +schema +``` + +Use the `read_repertoires()` function to load the data. There are quite many parameters, so let's briefly describe them: + +- `path` - ... + +- `schema` - ... + +- `metadata` - ... + +```{r} +#| label: load-dataset-airr +#| eval: true + +schema <- make_receptor_schema(features = c("cdr3", "v_call"), chains = c("TRB")) + +idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "locus", umi_col = "umis", preprocess = make_default_preprocessing("10x"), repertoire_schema = "Tissue") + +# idata +``` + +The output `idata` is `ImmunData` - a data structure from `immundata` package that holds the AIRR dataset. Think `AnnData` or `SeuratObject`, but for AIRR data. It is not a simple data frame or a list of data frames, and in the next subsection we will talk about how to operate on it. + +We have two optional steps left, and those are needed to load single-cell transcriptomics data. If you analyse bulk data, you obviously don't need to do this. + +We start with reading a cell metadata - a convenient human-readable table with T cell cluster annotations. Please note that in most cases, you will use `SeuratObject` or `AnnData` directly to exctact cluter labels from the object to annotate `ImmunData`. Read the corresponding documentation on how to extract cluster labels from single-cell transcriptomic and other tools. + +```{r} +#| label: load-dataset-cells +#| eval: true + +cells_file <- system.file("extdata/single_cell", "cells.tsv.gz", package = "immundata") +cells_file + +cells <- readr::read_tsv(cells_file) +cells +``` + +And finally, we load the gene expression data to Seurat. The matrix object takes several hundreds of megabytes, so we use cached file to avoid re-downloading the file next time we run the tutorial. Obviously, this wouldn't work without the web connection. + +The `cells` object contains also precomputed coordinates for UMAP to reduce the computations time for this tutorial. In real world, you would run the typical processing pipeline for scRNAseq data and get UMAP coordinates on the `SeuratObject`. To simulate this, we will add the UMAP coordinates to the created object in the code block below. + +```{r} +#| label: load-dataset-seurat +#| eval: true + +url <- "https://zenodo.org/records/15604205/files/l6data.rds?download=1" +dest <- BiocFileCache::bfcrpath(BiocFileCache::BiocFileCache(ask = FALSE), url) + +mat <- readr::read_rds(dest) + +sdata <- CreateSeuratObject(counts = mat) + +embeddings <- as.matrix(cells[c("UMAP_1", "UMAP_2")]) +rownames(embeddings) <- cells$barcode + +umap_dr <- CreateDimReducObject(embeddings = embeddings, key = "UMAP_", assay = DefaultAssay(sdata)) + +sdata[["umap"]] <- umap_dr + +Idents(sdata) <- setNames(cells$ident, cells$barcode) + +DimPlot(sdata, reduction = "umap", order = sort(unique(cells$ident), decreasing = TRUE), label = TRUE, alpha = .5) +``` + + +#### How to read other types of data - bulk, single-chain, etc. + +Note that the code below is for demonstration purposes only. It is not meant to run as a part of this tutorial. + +1. Bulk + +You won't need `barcode_col`, `locus_col`, `umi_col`. You can optionally pass `count_col` to have receptors counts. + +```{r} +#| label: load-dataset-types-bulk +#| eval: false + +idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, count_col = "counts", preprocess = make_default_preprocessing("airr"), repertoire_schema = "Tissue") +``` + +2. Single-cell + +All columns are needed. + +```{r} +#| label: load-dataset-types-singlecell +#| eval: false + +idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "locus", umi_col = "umis", preprocess = make_default_preprocessing("10x"), repertoire_schema = "Tissue") +``` + +3. AIRR or 10XGenomics + +`immunarch` aims to support the AIRR-C standard only. However, there are a couple of format-specific processing utilities. Mind the locus column name and the identifier we pass the to `make_default_preprocessing` function. + +```{r} +#| label: load-dataset-types-10x +#| eval: false + +idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "locus", umi_col = "umis", preprocess = make_default_preprocessing("airr"), repertoire_schema = "Tissue") + +idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "chain", umi_col = "umis", preprocess = make_default_preprocessing("10x"), repertoire_schema = "Tissue") +``` + +4. Pass file paths via metadata table - metadata_file_col + +Pass `""` + +```{r} +#| label: load-dataset-types-meta +#| eval: false + +idata <- read_repertoires(path = "", schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "locus", umi_col = "umis", preprocess = make_default_preprocessing("10x"), repertoire_schema = "Tissue") +``` + +--- + +## Note on materialization + +`ImmunData` object works on out-of-memory datasets the same way it works on in-memory datasets. It saves necessary computations and runs them only when the data is needed, e.g., for visualization. "Materialization" refers to running all the computations and getting this "real" dataset. This behaviour is not very familiar to people. Therefore, if you encounter this error: + +``` +Error: Materialization is disabled, use collect() or as_tibble() to materialize. +``` + +it means that the data is not materialized yet. If the data is not huge, e.g., it is some statistics from `immunarch` functions, you can safely run `immunarch_function() |> collect()` to immediately collect this data. If the dataset is huge, e.g., filtered `ImmunData` object, you usually don't need to materialize it so please think twice before doing this. + +--- + +## Analyse immune repertoires - individually and in groups + + +### Explore key statistics of immune repertoires + + +#### Number of receptors and barcodes for samples + +```{r} +#| label: repertoire-stats-sample-plot +#| eval: true +#| fig-width: 11 +idata_stats <- airr_stats_chains(idata) + +idata_stats + +p1 <- ggplot(idata_stats, aes(x = Tissue, y = n_barcodes, fill = Tissue)) + geom_col() + ggtitle("No. barcodes per sample") + ggsci::scale_fill_locuszoom() +p2 <- ggplot(idata_stats, aes(x = Tissue, y = n_receptors, fill = Tissue)) + geom_col() + ggtitle("No. receptors per sample") + ggsci::scale_fill_locuszoom() + +p1 + p2 +``` + + +#### Number of receptors and barcodes for cell clusters + +Okay, that's great, but what if we want to have a detailed view on how clusters are represented? Currently, we have three repertoires in the `idata` coming from the different tissues: + +```{r} +#| label: repertoire-stats-show-repertoires +#| eval: true + +idata$repertoires +``` + +Ideally, we want to explore each cell subpopulation in each tissue. For this, we will use powerful annotation mechanism from `immundata`. `idata` and `cells` have the same cell barcodes, so we can use them to annotate immune receptors with cluster label information, and then compute the same statistics on cluster level. + +```{r} +#| label: repertoire-stats-cluster +#| eval: true + +annot <- tibble(Cluster = as.character(Idents(sdata)), barcode = names(Idents(sdata))) + +annot + +idata <- annotate_barcodes(idata, annot, "barcode") +idata <- agg_repertoires(idata, c("Tissue", "Cluster")) + +idata$repertoires +``` + +And now, let's plot recompute statistics and plot them, but applied to "new" repertoires, which are now defined by a pair of columns - a tissue name "Tissue" and a cluster label "Cluster". + +```{r} +#| label: repertoire-stats-cluster-plot +#| eval: true +#| fig-width: 11 +idata_stats <- airr_stats_chains(idata) + +idata_stats + +p1 <- ggplot(idata_stats, aes(x = Tissue, y = n_barcodes, fill = Cluster)) + geom_col() + ggtitle("No. barcodes per sample") +p2 <- ggplot(idata_stats, aes(x = Tissue, y = n_receptors, fill = Cluster)) + geom_col() + ggtitle("No. receptors per sample") + +p1 + p2 +``` + +That's a lot of information! Let's group by cluster to understand the differences between tissues. + +```{r} +#| label: repertoire-stats-cluster-plot-patients +#| eval: true +#| fig-width: 11 + +ggplot(idata_stats, aes(x = Cluster, y = n_receptors, fill = Tissue)) + geom_col(position = "dodge") + ggtitle("No. receptors per sample") + ggsci::scale_fill_locuszoom() + theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +``` + +Lots of NAs. This is because we took only "TRB" chain, and the tumor receptors are going crazy, they have lots of receptors per one barcode. + +If we reload the data with paired chain data, we will see another picture, as `immunarch` will filter out receptors additional receptors per barcode and leave only one pair per barcode. Do you want to do it? Consider this your homework! You just need to define a paired-chain schema for receptors (see one of the previous sections) and run pretty much the same code without any changes - that's the power of decoupling data processing to `immundata` and data analysis to `immunarch`. The latter pretty much doesn't care about the former, it just "asks" for receptors to exists - in any shape or form. + +We see some expected yet interesting patterns like more Tregs in the tumor site or more Trm in the surrounding normal tissue. Our data is not normalized so we can't really compare how big is the difference. We will normalize the data by the overall number of receptors per sample, and then plot the same visualization. + +```{r} +#| label: repertoire-stats-cluster-plot-norm +#| eval: true +#| fig-width: 11 + +idata_stats2 <- idata_stats |> mutate(.by = Tissue, TissueSize = sum(n_barcodes)) |> mutate(n_barcodes_div = n_barcodes / TissueSize) +idata_stats2 + +ggplot(idata_stats2, aes(x = Cluster, y = n_barcodes_div, fill = Tissue)) + geom_col(position = "dodge") + ggtitle("No. barcodes per sample") + ggsci::scale_fill_locuszoom() + theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) +``` + +#### Gene usage + +```{r} +#| label: repertoire-gene-usage-plot +#| eval: true +#| fig-width: 11 + +# filter Trm and Treg +# compute stats +# join them +# visualise +airr_stats_genes(idata) +``` + + +#### Length distribution + + +### Clonality + +... + + +### Diversity + +... + + +### Compute public receptor indices + +... + + +#### Number of public receptors + +... + + +#### Jaccard index + +... + + +But what are those public receptors? The next section will help us extract them from the data. + +--- + +## Discover and annotate immune receptors + +This section is under construction as I currently develop the receptor-level analysis functionality. I plan to release the most commonly used functions in October-November 2025. Monitor my [LinkedIn](https://www.linkedin.com/in/vdnaz) and [GitHub](https://github.com/immunomind/immunarch/issues/432) for news and updates. + +The planned topics are: + +- use external databases to find CMV-specific receptors in the input repertoires + +- track specific CMV-related receptors through different tissues and highlight them on single-cell UMAP + +- analyse and plot counts of specific receptors vs. expression of genes of interest + +- public repertoire analysis - discover receptors which are suspiciously overabundant in one groups of repertoires in contrast to another groups of repertoires (e.g., control vs condition to search for TIL or antigen-specific receptors) + +- all of above but using levenshtein-based similarity instead of exact matches + +--- + +## Analyse subgroups of receptors of interest + +This is section is too under constructions. Planned content: + +- discover receptors of interest, e.g., CMV-specific + +- run analysis to compare sum/avg abundance of such receptors between groups to measure the level of signal + +--- + +## Conclusion + +No spoilers. :-) diff --git a/vignettes/immunarch.qmd b/vignettes/immunarch.qmd new file mode 100644 index 00000000..a5604a80 --- /dev/null +++ b/vignettes/immunarch.qmd @@ -0,0 +1,196 @@ +--- +title: "Immunarch 1.0 --- introduction and migration from 0.9 version" +author: "Vadim Nazarov" +date: "`r Sys.Date()`" +format: + html: + toc: true + number-sections: true + # theme: none + # minimal: true +vignette: > + %\VignetteIndexEntry{Immunarch} + %\VignetteEngine{quarto::html} + %\VignetteEncoding{UTF-8} +--- + +Install specific version via `pak::pkg_install("immunarch@=0.9.1")`. + +Mind that the 0.9.x versions will NOT be supported. If something breaks, if some R package dive into oblivion - it won't be fixed, sorry. So it is highly advised to move to the new 1.0 version ASAP, especially considering that the feature parity will be obtained in months. + +However, there is high priority to obrain feature parity, stability and add features for the most common uses case and several complex use cases fcused on immunotherapy development. So please consider switching. Open an issue - I'm willing to help. + +why removed vis -> because it brings only a quick value, hides all the complexity so people created issues to adapt the plot, and they are not publication ready plots. So I opt out to remove them, but focus on helping people learn how to visualise stuff. That's why tutorials will have more visualisation examples. + +In the future I still plan to provide something using more common approachs via ggplot2::autoplot, but it's out of scope for now. + +Short asnwer: great for fast analysis, but as soon as you need something more custom or complex, it becomes too hard to tune and it's easier to write your own from scratch. + +# TODO + +- [ ] I need to clearly state somewhere the list of v1 functions that use immundata. Maybe here or in the updates + +- [ ] lifecycle::deprecated tag for v0 functions + +- [ ] Frame the immundata. + +- [ ] Link to ImmunData README tutorial somewhere + +# Overview + +There are three major points related to transformations: + +1. **How immunarch 1.0.0 works with data**\ +2. **Interface or API changes** (i.e., names and parameters of the functions in immunarch)\ +3. **Removing / moving some functions to a separate package** to make immunarch easier to install and manage + +For more long-term plans, take a look at the final sections. If you’re only interested in what to do **right now**, keep reading below. + +------------------------------------------------------------------------ + +# Major update for the current version: Spring 2025 + + +## What Changed and What You Can Do + +- **Removed heavier dependencies** (ggpubr, factoextra, fpc, ggraph, phangorn, igraph, etc.). + - This was partly due to CRAN requirements and overall maintenance overhead.\ + - The **good news** is that immunarch now needs \~80 packages to install (down from 184!).\ + - If your analysis code relied on these libraries, you can still install them separately. +- **Functionality**: + - If you’ve been using immunarch for a while, most immunarch function signatures remain the same.\ + + - If you see errors asking for those removed packages, simply install them manually. For example: + + ``` r + install.packages("ggpubr") + ``` + + Then re-run your analysis. +- **immundata Integration**: + - We’re introducing better synergy with Immundata. [See details in the “Scalable and fast data processing” section](#scalable-and-fast-data-processing).\ + - You can seamlessly convert older immunarch data objects to the new `ImmunData` format. + +### Key Takeaways + +- **Lighter** default install: less “bloat” you don’t need.\ +- Additional packages can be installed on-demand if your scripts require them.\ +- You shouldn’t see breaking changes in function usage — **only** in how to handle optional libraries. + +------------------------------------------------------------------------ + +# Next Major Update: Summer 2025 + +## What Will Be Changed + +- **Refined Data Structures**: + - We plan to unify the internal data structure for single-cell vs. bulk repertoire data.\ + - The old `immdata` approach will be replaced or augmented by a more consistent framework. +- **Deprecated Functions**: + - Some older convenience wrappers will be marked deprecated.\ + - We’ll provide new recommended calls in the console messages. +- **Possibly More Dependency Splits**: + - Additional packages (e.g., PCA or tree-based analysis libraries) might move out.\ + - A new “immunarch.ext” or similarly named extension package might appear with specialized analyses. + +## What Can You Do to Mitigate Risks + +1. **Pin Your Dependencies** + - Use `renv` or a Docker image to lock your environment if you need stable re-runs.\ +2. **Watch for Deprecation Warnings** + - If you see console messages about “deprecated” or “will be removed in v1.1.0,” update your code ASAP.\ +3. **Try Out Immundata** + - If you handle complex or large-scale data, consider migrating to `ImmunData` early.\ + - [See the “How immunarch 1.0.0 will look” section](#how-immunarch-100-will-look-like) for more details on Immundata synergy. + +------------------------------------------------------------------------ + +# Future Major Updates: Autumn-Winter 2025 + +## What Will Be Changed + +- **Deeper Integration with Immundata** + - We plan to store certain immunarch metadata in `ImmunData` structures by default.\ + - One possibility: all immunarch pipeline steps become “ImmunData” transformations under the hood. +- **Performance Overhaul** + - We may adopt new backends (DuckDB, Polars) for bigger data sets.\ + - This may involve changes to how custom analysis scripts are written. + +## What Can You Do to Mitigate Risks + +1. **Stay Updated** + - Subscribe to the immunarch newsletter or GitHub releases to see upcoming changes.\ +2. **Adopt the “New Way” Early** + - If you see a function is overshadowed by a newer `ImmunData`-based alternative, switch now.\ +3. **Check Release Notes** + - We post details on the migration paths, including function renaming or column renaming. + +------------------------------------------------------------------------ + +# How immunarch 1.0.0 Will Look Like + +## Why Do We Even Need 1.0.0? + +- **Outdated code** that’s hard to maintain, especially in an academic environment where developer turnover is high.\ +- **Improved code culture**: adopting best practices, standard data structures, consistent naming.\ +- **User feedback**: Many users asked for more scalable and flexible pipelines. + +### High-Level Goals + +1. **More maintainable code** base. +2. **Less friction** with environment setups. +3. **Consistent syntax** and naming conventions. + +## Scalable and Fast Data Processing {#scalable-and-fast-data-processing} + +- **Lazy Backends**: We’re exploring or partially implementing backends like DuckDB or Arrow. + - Potential performance boosts for big repertoires.\ + - Immundata is designed to be backend-agnostic.\ +- **Parallelization**: Where possible, certain immarch steps will parallelize out-of-the-box. + +### How Immundata Helps + +- We introduced [Immundata](https://github.com/yourrepo/immundata) to unify TCR/BCR data.\ +- `ImmunData` objects can seamlessly handle single-cell or bulk data in a single pipeline.\ +- The biggest advantage is the **unified schema** (receptor, annotations, repertoire definitions). + +## Lighter Interface + +- Reducing hidden dependencies means fewer manual installs.\ +- Possibly removing large plotting packages from the core install.\ +- You’ll see many advanced visualizations in optional extension modules. + +## Modularizing the Ecosystem + +- In the near future, we plan to have: + - **immunarch.core**: essential data processing.\ + - **immunarch.plots**: advanced visualization.\ + - **immunarch.bioinfo**: alignment, clonotype assignment, etc.\ +- Each sub-package can be installed only if you need that functionality. + +------------------------------------------------------------------------ + +# Proposed Outline / Sections to Expand Further + +1. **Installation Details** + - Precisely how to install or upgrade to immunarch 1.0.0.\ + - Example: `install.packages("immunarch")` (once it’s on CRAN).\ +2. **Detailed Migration Steps** + - If you used old code, step-by-step instructions (like “Replace `immdata$data[[i]]` with `ImmunData$new(...)`”).\ + - Potential script transformation examples.\ +3. **FAQ** + - “I see errors about missing packages?” → install them.\ + - “Where can I find the old plot() function?” → in `immunarch.plots`.\ +4. **Future “Beta” or “Dev” versions** + - Encourage users to test the dev branch if they want the newest changes.\ +5. **In-depth Immundata Demonstrations** + - Show how to create an `ImmunData` from a typical immunarch object.\ + - Show how to use Immundata’s new filter or aggregation pipelines. + +------------------------------------------------------------------------ + +# Conclusion + +immunarch 1.0.0 is a major step in making immune repertoire analysis **lighter**, **faster**, and **easier to maintain**. While many changes revolve around removing heavy dependencies, the core **user experience** should remain familiar. For large or advanced analyses, consider exploring **Immundata** to leverage its robust data structure and efficient transformations. + +Stay tuned for more updates in **Summer 2025** and **Autumn-Winter 2025**, and don’t hesitate to **reach out** on GitHub or our user forum if you have questions or encounter migration issues. diff --git a/vignettes/web_only_v0/BCRpipeline.Rmd b/vignettes/web_only_v0/BCRpipeline.Rmd index 6419869f..d83c742d 100644 --- a/vignettes/web_only_v0/BCRpipeline.Rmd +++ b/vignettes/web_only_v0/BCRpipeline.Rmd @@ -94,7 +94,7 @@ B-cell **clonal lineage** represents a set of B cells that presumably have a com An example of reconstructing clonal lineages using default Immunarch options: -```{r example 2} +```{r example 2, eval=FALSE} #calulate distance matrix distBCR <- seqDist(bcrdata$data %>% top(500)) @@ -108,7 +108,7 @@ Each clonal lineage has its own **germline sequence** that represents the ancest In Immunarch, `repGermline()` function generates germline for each sequence: -```{r example 3, results = 'hide'} +```{r example 3, results = 'hide', eval=FALSE} #generate germline bcrdata$data %>% repGermline(.threads = 1) @@ -116,7 +116,7 @@ bcrdata$data %>% A germline is represented via sequences of V gene - N...N (CDR3 length) - J gene: -```{r example 4} +```{r example 4, eval=FALSE} #germline example bcrdata$data %>% top(1) %>% @@ -151,7 +151,7 @@ sudo apt install clustalw `repAlignLineage` usage example: -```{r example 7, results = 'hide'} +```{r example 7, results = 'hide', eval=FALSE} data(bcrdata) bcr_data <- bcrdata$data %>% top(500) bcr_data %>% @@ -164,7 +164,7 @@ The function has several parameters: - `.min_lineage_sequences` — Filters clusters (clonal lineages) with the number of clonotypes lower than the threshold. Aligning clonal lineages with few sequences is of little use. -```{r example 8, results = 'hide'} +```{r example 8, results = 'hide', eval=FALSE} # take clusters that contain at least 1 sequence bcr_data <- bcrdata$data align_dt <- bcr_data %>% @@ -185,7 +185,7 @@ Requirements for the input table for `repAlignLineage()` Align sequences in a cluster can be visualized using standard functions: -```{r align visualisation} +```{r align visualisation, eval=FALSE} # A name of the first cluster align_dt$full_clones$Cluster[[1]] @@ -217,7 +217,7 @@ sudo apt-get install -y phylip repClonalFamily usage example: -```{r example 10, results = 'hide'} +```{r example 10, results = 'hide', eval=FALSE} bcr <- align_dt %>% repClonalFamily(.threads = 2, .nofail = TRUE) #plot visualization of the first tree @@ -225,14 +225,14 @@ vis(bcr[["full_clones"]][["TreeStats"]][[1]]) ``` For each cluster tree is represented as table (The default number of clones for CommonAncestor, Germline, Presumable is 1): -```{r example 10.1, results = 'hide'} +```{r example 10.1, results = 'hide', eval=FALSE} #example for the first tree bcr[["full_clones"]][["TreeStats"]][[1]] ``` You can recolor leaves. For example, we recolor leaves where number of AA mutations is not 0: -```{r example 10.3, results = 'hide'} +```{r example 10.3, results = 'hide', eval=FALSE} #take sequence where number of AA mutations is not 0 f <- bcr[["full_clones"]][["TreeStats"]][[1]] #rename these leaves @@ -243,7 +243,7 @@ vis(f) Another way to recolor leaves is to use `.vis_groups` parameter for repClonalFamily. It allows to assign group names for specific clone IDs, or lists of clone IDs: -```{r example 10.4, results = 'hide'} +```{r example 10.4, results = 'hide', eval=FALSE} #get all clone IDs from align_dt clone_ids <- unnest(align_dt[["full_clones"]], "Sequences")[["Clone.ID"]] #run repClonalFamily with assigning some of these clones to differently named and colored groups @@ -261,13 +261,13 @@ vis(bcr_with_groups[["full_clones"]][["TreeStats"]][[1]]) We have found 4 clusters: -```{r example 11, warning = FALSE} +```{r example 11, warning = FALSE, eval=FALSE} bcr$full_clones$Cluster %>% unique() ``` We have found mismatches between a germline and an ancestor sequence. Dots represent nucleotides matches between the sequences, letters represent mismatches between the sequences: -```{r example 12} +```{r example 12, eval=FALSE} # the example of common ancestor sequence bcr$full_clones$Common.Ancestor[1] @@ -277,13 +277,13 @@ bcr$full_clones$Germline.Output[1] We have calculated a trunk length for each cluster: -```{r example 13} +```{r example 13, eval=FALSE} bcr$full_clones[ , c('Cluster', 'Trunk.Length') ] ``` Also trunk length specified in "TreeStats" table in column "DistanceNT". -```{r example 10.2, results = 'hide'} +```{r example 10.2, results = 'hide', eval=FALSE} #example fot first tree bcr[["full_clones"]][["TreeStats"]][[1]][1, ] ``` @@ -294,7 +294,7 @@ The rate of somatic hypermutation allows us to estimate repertoire maturation an In Immunarch, `repSomaticHypermutation()` function is designed for hypermutation analysis: -```{r example 14, , warning = FALSE} +```{r example 14, , warning = FALSE, eval=FALSE} bcr_data <- bcrdata$data shm_data <- bcr %>% repSomaticHypermutation(.threads = 2, .nofail = TRUE) @@ -304,7 +304,7 @@ The function repSomaticHypermutation() takes V and J germline sequences and V an Examples of germline and clonotype sequences: -```{r example 15} +```{r example 15, eval=FALSE} full_clones <- shm_data$full_clones v_length <- nchar(paste(full_clones[1, "FR1.nt"], full_clones[1, "CDR1.nt"], full_clones[1, "FR2.nt"], full_clones[1, "CDR2.nt"], full_clones[1, "FR3.nt"], collapse="")) @@ -326,26 +326,26 @@ full_clones$Sequence[1] %>% substr(seq_length - j_length, seq_length) Example: aligning germline and clonotype V sequences: -```{r example 16} +```{r example 16, eval=FALSE} image(shm_data$full_clones$Germline.Alignment.V[[3]], grid = TRUE) ``` Example: aligning germline and clonotype J sequences: -```{r example 17} +```{r example 17, eval=FALSE} image(shm_data$full_clones$Germline.Alignment.J[[3]], grid = TRUE) ``` The number of mutations for each clonotype sequence: -```{r example 18} +```{r example 18, eval=FALSE} cols <- c('Clone.ID', 'Substitutions', 'Insertions', 'Deletions', 'Mutations') shm_data$full_clones[ , cols ] ``` Then you could easily estimate the mutation rate: -```{r example 19} +```{r example 19, eval=FALSE} # estimate mutation rate shm_data$full_clones %>% mutate(Mutation.Rate = Mutations / (nchar(Sequence) - nchar(CDR3.nt))) %>% diff --git a/vignettes/web_only_v0/clustering.Rmd b/vignettes/web_only_v0/clustering.Rmd index 39e85fca..38fb3b9f 100644 --- a/vignettes/web_only_v0/clustering.Rmd +++ b/vignettes/web_only_v0/clustering.Rmd @@ -122,7 +122,7 @@ Clustering is commonly used to expand the concept of a clonotype. For example, y Example: -```{r example 7} +```{r example 7, eval=FALSE} #calculate distance distTCR <- seqDist( TCRdata, .col = 'CDR3.aa') @@ -140,7 +140,7 @@ In general, the number of clusters you get depends on threshold you defined prev Requires defining the minimum percentage of similarity for the sequences in your cluster in advance. For example, if you want to find cluster of BCRs that not only have the same V.name, J.name, and CDR3 length — but also have more than 90 percent match in their CDR3. -```{r example 8, warning = FALSE} +```{r example 8, warning = FALSE, eval=FALSE} #clustering TCR clustTCR <- seqCluster(TCRdata, distTCR, .perc_similarity = 0.75) @@ -155,7 +155,7 @@ clustTCR$"A2-i129" %>% .$Cluster %>% unique() %>% length() Requires directly determining the number of mismatched nucleotides. In case of TCR-recognising the same epitope, use 1 amino acid mismatch in CDR3 sequences. -```{r example 9, warning = FALSE} +```{r example 9, warning = FALSE, eval=FALSE} #clustering TCR clustTCR <- seqCluster(TCRdata, distTCR, .fixed_threshold = 2) @@ -170,7 +170,7 @@ clustTCR$"A2-i129" %>% .$Cluster %>% unique() %>% length() If you want to guarantee that the matches in the sequences are at a set proximity, specify a distance threshold -```{r example 10, warning = FALSE} +```{r example 10, warning = FALSE, eval=FALSE} #clustering TCR clustTCR <- seqCluster(TCRdata, distTCR, .nt_similarity = 10) @@ -187,7 +187,7 @@ If you made it to this part, then you have successfully clustered your sequences Comparing cluster size distributions is a good way to analyse quality of clustering process and to choose the best parameters for functions: -```{r } +```{r eval=FALSE } #write small function for the visualization of cluster size destribution mk_hist <- function(clust_dt, graph_name) { return(ggplot(clust_dt, aes(x=cluster_size)) + geom_histogram( binwidth=1, fill="#69b3a2", color="#e9ecef", alpha=0.9) + @@ -209,7 +209,7 @@ There are other packages that provide computational framework for identification `Immunarch` enables users to integrate results from `scoper` package for further analysis: -```{r example 11, warning = FALSE} +```{r example 11, warning = FALSE, eval=FALSE} #load the package into the R environment library(scoper) @@ -221,7 +221,7 @@ bcr <- bcrdata$data$full_clones %>% Add columns ‘sequence_alignment’ required by `scoper` (https://scoper.readthedocs.io/en/stable/vignettes/Scoper-Vignette/): -```{r example 12} +```{r example 12, eval=FALSE} #generate `sequence_alignment` column cols <- c('FR1.nt', 'CDR1.nt', 'FR2.nt', 'CDR2.nt', 'FR3.nt', 'CDR3.nt', 'FR4.nt') bcr$sequence_alignment <- apply( bcr[ , cols ] , 1 , paste , collapse = "" ) @@ -229,20 +229,20 @@ bcr$sequence_alignment <- apply( bcr[ , cols ] , 1 , paste , collapse = "" ) Rename columns in `scoper` format: -```{r example 13} +```{r example 13, eval=FALSE} ExampleDb <- bcr %>% select(J.allele, V.allele, CDR3.nt, Germline.sequence, sequence_alignment) %>% rename(junction = CDR3.nt, v_call = V.allele, j_call = J.allele, germline_alignment_d_mask = Germline.sequence) ``` Cluster using `scoper` method: -```{r example 14} +```{r example 14, eval=FALSE} results <- hierarchicalClones(ExampleDb, threshold=0.15) plot(results, binwidth=0.02) ``` Note that the column ‘clone_id' in `scoper` format has the same meaning as the ‘Cluster’ column in `immunarch`: -```{r example 15} +```{r example 15, eval=FALSE} glimpse(summary(results)) ``` diff --git a/vignettes/data.Rmd b/vignettes/web_only_v0/data.Rmd similarity index 100% rename from vignettes/data.Rmd rename to vignettes/web_only_v0/data.Rmd diff --git a/vignettes/introduction.Rmd b/vignettes/web_only_v0/introduction.Rmd similarity index 100% rename from vignettes/introduction.Rmd rename to vignettes/web_only_v0/introduction.Rmd diff --git a/vignettes/web_only_v0/repFilter_v3.Rmd b/vignettes/web_only_v0/repFilter_v3.Rmd index 96038ce3..1d964c51 100644 --- a/vignettes/web_only_v0/repFilter_v3.Rmd +++ b/vignettes/web_only_v0/repFilter_v3.Rmd @@ -256,20 +256,20 @@ repFilter(scdata, .method = "by.clonotype", .query = list(CDR3.aa = exclude("par ``` Create a new dataset with cluster-specific immune repertoires (for more information see *Single-cell* tutorials): -```{r} +```{r eval=FALSE} scdata_cl <- select_clusters(scdata, scdata$bc_cluster, "Cluster") scdata_cl$meta ``` And compare the number of clonotypes between clusters: -```{r clonotypes, warnings = F} +```{r clonotypes, warnings = F, eval=FALSE} vis(repExplore(scdata_cl$data, .method = "volume")) ``` Compare J gene usage between three clusters: -```{r geneUsage, warning=F} +```{r geneUsage, warning=F, eval=FALSE} sc_active <- geneUsage(repFilter(scdata_cl, .method = "by.meta", .query = list(Cluster = include("Activ")))$data, "hs.trbj", .norm = T) p1 <- vis(sc_active) p1 @@ -284,7 +284,7 @@ p3 ``` Compare gene usage of IGHJ4 between three clusters: -```{r IGHV3, warning=F} +```{r IGHV3, warning=F, eval=FALSE} scdata_active <- repFilter(scdata_cl, .method = "by.meta", .query = list(Cluster = include("Activ"))) scdata_active <- repFilter(scdata_active, .method = "by.cl", .query = list(J.name = include("IGHJ4")), .match = "substring") sc_active <- geneUsage(scdata_active$data, "hs.trbj", .norm = T) @@ -304,7 +304,7 @@ p1 + p2 + p3 ``` Look at the coding clonotypes in each cluster. Note that there aren't any noncoding clonotypes in the datasets: -```{r ORF, warning=F} +```{r ORF, warning=F, eval=FALSE} scdata_active <- repFilter(scdata_cl, .method = "by.meta", .query = list(Cluster = include("Activ"))) scdata_active <- repFilter(scdata_active, .method = "by.clonotype", .query = list(CDR3.aa = exclude("partial", "out_of_frame"))) exp_vol <- repExplore(scdata_active$data, .method = "volume") diff --git a/vignettes/web_only_v0/v21_singlecell.Rmd b/vignettes/web_only_v0/v21_singlecell.Rmd index f73e8b6c..7f3357c7 100644 --- a/vignettes/web_only_v0/v21_singlecell.Rmd +++ b/vignettes/web_only_v0/v21_singlecell.Rmd @@ -84,7 +84,7 @@ head(igdata$data[[1]][c(1:7, 16, 17)]) To subset the data by barcodes, use the `select_barcodes` function. -```{r} +```{r, eval=FALSE} barcodes <- c("AGTAGTCAGTGTACTC-1", "GGCGACTGTACCGAGA-1", "TTGAACGGTCACCTAA-1") new_df <- select_barcodes(scdata$data[[1]], barcodes) @@ -96,7 +96,7 @@ new_df To create a new dataset with cluster-specific immune repertoires, use the `select_clusters` function: -```{r} +```{r, eval=FALSE} scdata_pat <- select_clusters(scdata, scdata$bc_patient, "Patient") names(scdata_pat$data) @@ -108,7 +108,7 @@ scdata_pat$meta To create a new dataset with cluster-specific immune repertoires, use the `select_clusters` function. You can apply this function after you created patient-specific datasets to get patient-specific cell cluster-specific immune repertoires, e.g., a Memory B Cell repertoire for a specific patient: -```{r} +```{r, eval=FALSE} scdata_cl <- select_clusters(scdata_pat, scdata$bc_cluster, "Cluster") names(scdata_cl$data) @@ -120,7 +120,7 @@ scdata_cl$meta Most functions will work out-of-the-box with paired chain data. -```{r} +```{r, eval=FALSE} p1 <- repOverlap(scdata_cl$data) %>% vis() p2 <- repDiversity(scdata_cl$data) %>% vis() diff --git a/vignettes/web_only_v1/receptor_track.Rmd b/vignettes/web_only_v1/receptor_track.Rmd deleted file mode 100644 index 3e16932b..00000000 --- a/vignettes/web_only_v1/receptor_track.Rmd +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "Tracking receptors across immune space and time" -author: "Vadim I. Nazarov" -date: "`r Sys.Date()`" -output: - html_document: - fig_height: 8 - fig_width: 10 - theme: spacelab - toc: yes - pdf_document: - toc: yes - word_document: - toc: yes ---- - - - - - - -```{r setup, include=FALSE, echo=FALSE} -# knitr::knit_hooks$set(optipng = knitr::hook_optipng) -# knitr::opts_chunk$set(optipng = '-o7') - -knitr::opts_chunk$set(echo = TRUE) -knitr::opts_chunk$set(fig.align = "center") -knitr::opts_chunk$set(fig.width = 12) -knitr::opts_chunk$set(fig.height = 6) - -library(immunarch) -data(immdata) -read_repertoires from system.file. -``` - -# Background - -what it is - -relevance for immunotherapy - -# Tracking receptors - -# Visualising - -# Clustering - -# Input / output -#' 1a) List of CDR3 - vector + col to match (screw that, just pass a data frame) -#' 1b) List of CDR3 + other columns -#' 1c) List of CDR3 alpha + CDR3 beta (+ other columns) -#' 2a) Find abundance of found receptors in an ordered repertoires -#' 2b) Find abundance of receptors close by distance in an ordered repertoires -#' 3a) Visualise via alluvial -#' 3b) Compute PCA on abundances and visualise -#' From c7ebb4edb175175d4a25baacce211d8059bd6c59 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:54:36 +0200 Subject: [PATCH 22/36] chore: update description --- DESCRIPTION | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 902bbfc0..53f10884 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: immunarch Type: Package -Title: Data-Driven Immune Repertoire Insights for Immunotherapy and Vaccine Design +Title: Multi-Modal Immune Repertoire Analytics for Immunotherapy and Vaccine Design in R Version: 0.9.1.9001 Authors@R: c( person("Vadim I.", "Nazarov", , "support@immunomind.com", role = c("aut", "cre"), @@ -10,14 +10,14 @@ Authors@R: c( person("Ivan", "Balashov", , role = "aut") ) Contact: support@immunomind.com -Description: A comprehensive framework for bioinformatics exploratory analysis of bulk and single-cell - T-cell receptor and antibody repertoires. It provides seamless data loading, analysis and - visualisation for AIRR (Adaptive Immune Receptor Repertoire) data, both bulk immunosequencing (RepSeq) - and single-cell sequencing (scRNAseq). Immunarch implements most of the widely used AIRR analysis methods, - such as: clonality analysis, estimation of repertoire similarities in distribution of clonotypes - and gene segments, repertoire diversity analysis, annotation of clonotypes using external immune receptor - databases and clonotype tracking in vaccination and cancer studies. A successor to our - previously published 'tcR' immunoinformatics package (Nazarov 2015) . +Description: A comprehensive analytics framework for building reproducible pipelines on T-cell and B-cell immune receptor repertoire data. + Delivers multi-modal immune profiling (bulk, single-cell, CITE-seq/AbSeq, spatial, immunogenicity data), + feature engineering (ML-ready feature tables and matrices), and biomarker discovery workflows + (cohort comparisons, longitudinal tracking, repertoire similarity, enrichment). + Provides a user-friendly interface to widely used AIRR methods — + clonality/diversity, V(D)J usage, similarity, annotation, tracking, and many more. + Think Scanpy or Seurat, but for AIRR data, a.k.a. Adaptive Immune Receptor Repertoire, VDJ-seq, RepSeq, or + VDJ sequencing data. A successor to our previously published "tcR" R package (Nazarov 2015). License: Apache License (== 2.0) URL: https://immunarch.com/, https://github.com/immunomind/immunarch BugReports: https://github.com/immunomind/immunarch/issues @@ -53,10 +53,11 @@ Imports: utils, glue, checkmate, - duckplyr, + duckplyr (>= 1.1.0), dbplyr, lifecycle, - purrr + purrr, + stats LinkingTo: Rcpp Suggests: knitr (>= 1.8), @@ -84,7 +85,7 @@ VignetteBuilder: knitr, quarto Encoding: UTF-8 -RoxygenNote: 7.3.2 +RoxygenNote: 7.3.3 LazyData: true LazyDataCompression: xz Roxygen: list(markdown = TRUE) From 615b338468c30faf2498b6bd389f9f405e985cc5 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:54:43 +0200 Subject: [PATCH 23/36] chore: readme rewrite --- README.md | 312 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 183 insertions(+), 129 deletions(-) diff --git a/README.md b/README.md index 56c74261..f0813243 100644 --- a/README.md +++ b/README.md @@ -1,198 +1,246 @@ -[![Follow](https://img.shields.io/twitter/follow/immunomind.svg?style=social)](https://twitter.com/intent/follow?screen_name=immunomind) -[![CRAN](http://www.r-pkg.org/badges/version-ago/immunarch?style=flat-square)](https://cran.r-project.org/package=immunarch) -[![Downloads_all](http://cranlogs.r-pkg.org/badges/grand-total/immunarch)](https://www.r-pkg.org/pkg/immunarch) -[![Downloads_week](http://cranlogs.r-pkg.org/badges/last-week/immunarch)](https://www.r-pkg.org/pkg/immunarch) -[![Issues](https://img.shields.io/github/issues/immunomind/immunarch?style=flat-square)](https://github.com/immunomind/immunarch/issues) -[![CI](https://gitlab.com/immunomind/immunarch/badges/master/pipeline.svg?style=flat-square)](https://gitlab.com/immunomind/immunarch/-/jobs) -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3367200.svg)](https://doi.org/10.5281/zenodo.3367200) -![Visitors](https://visitor-badge.glitch.me/badge?page_id=immunomind.immunarch) -[![Downloads_all](http://cranlogs.r-pkg.org/badges/grand-total/tcR)](https://www.r-pkg.org/pkg/tcR) -[![Downloads_week](http://cranlogs.r-pkg.org/badges/last-week/tcR)](https://www.r-pkg.org/pkg/tcR) +
+

🧬 immunarchMulti-modal immune repertoire analysis in R

+
+--- -# `immunarch` --- Fast and Seamless Exploration of Single-cell and Bulk T-cell/Antibody Immune Repertoires in R - -## Why `immunarch`? -- **Work with any type of data:** single-cell, bulk, data tables, databases --- you name it. -- **Community at the heart:** ask questions, share knowledge and thrive in the community of almost 30,000 researchers and medical scientists worldwide. **Pfizer, Novartis, Regeneron, Stanford, UCSF** and **MIT** trust us. -- **One plot --- one line:** write a [whole PhD thesis in 8 lines of code](https://twitter.com/Nusob88/status/1127601201112129536) or reproduce almost any publication in 5-10 lines of `immunarch` code. -- **Be on the bleeding edge of science:** we regularly update `immunarch` with the latest methods. [Let us know what you need!](#help-the-community) -- **Automatic format detection and parsing** for all popular immunosequencing formats: from **MiXCR** and **ImmunoSEQ** to **10XGenomics** and **ArcherDX**. - - -### Lightning-fast Start -```r -install.packages("immunarch") # Install the package -library(immunarch); data(immdata) # Load the package and the test dataset -repOverlap(immdata$data) %>% vis() # Compute and visualise the most important statistics: -geneUsage(immdata$data[[1]]) %>% vis() # public clonotypes, gene usage, sample diversity -repDiversity(immdata$data) %>% vis(.by = "Status", .meta = immdata$meta) # Group samples -``` - + + +

+ Tutorials + | + API reference + | + Ecosystem + | + Publication (coming soon...) +

-### From Berkeley with devotion +--- -`immunarch` is brought to you by [ImmunoMind](https://immunomind.com) --- a [UC Berkeley SkyDeck](https://www.forbes.com/sites/avivalegatt/2019/01/07/launch-your-startup-at-these-five-college-incubators/) startup. ImmunoMind improves the design of adoptive T-cell therapies such as CAR-T by precisely identifying T-cell subpopulations and their immune profile. ImmunoMind's tools are trusted by researchers from top pharma companies and universities, including 10X Genomics, Pfizer, Regeneron, UCSF, MIT, Stanford, John Hopkins School of Medicine and Vanderbilt University. +`immunarch` brings a comprehensive analytics toolkit to build reproducible analysis pipelines for Adaptive Immune Receptor Repertoire (AIRR) data with a particular focus on designing personalized immunotherapies and vaccines. Key features are: -[![Follow](https://img.shields.io/twitter/follow/immunomind.svg?style=social)](https://twitter.com/intent/follow?screen_name=immunomind) +- **Multi-modal immune profiling:** compute receptor- and repertoire-level statistics leveraging single-cell, spatial, immunogenicity or any other receptor annotations; ---- +- **Immunomics at scale:** work seamlessly with datasets that don't fit in memory; -## Table of Contents +- **Immune biomarker discovery:** stratify cohorts and timepoints, derive repertoire signatures (diversity/clonality, V/J usage, similarity), and track antigen-annotated clonotypes; -- [Introduction](#introduction) -- [Contact](#contact) -- [Installation](#installation) -- [Features](#features) -- [Quick Start](#quick-start) -- [Bugs and Issues](#bugs-and-issues) -- [Contribution](#help-the-community) -- [Citation](#citation) +- **Feature engineering:** build Machine Learning-ready feature tables (receptor-, ssample- and cohort-level) from core repertoire metrics and annotations, with consistent IDs/metadata for downstream statistics or modeling; -## Introduction +- **Modular, extendable, adaptable:** add new analyses and metrics via a extension API, and use adapters to interoperate with other AIRR tools and formats. -`immunarch` is an R package designed to analyse T-cell receptor (TCR) and B-cell receptor (BCR) repertoires, mainly tailored to medical scientists and bioinformaticians. The mission of `immunarch` is to make immune sequencing data analysis as effortless as possible and help you focus on research instead of coding. +## 🤔 Why `immunarch`? -## Contact -Create a ticket with a bug or question on [GitHub Issues](https://github.com/immunomind/immunarch/issues) to get help from the community and enrich it with your experience. If you need to send us sensitive data, feel free to contact us via [support@immunomind.io](mailto:support@immunomind.io). +As immune repertoire sequencing becomes a mainstream technology, adopted by major platforms and integrated into more translational and clinical workflows, tooling expectations are changing rapidly. +The pace of innovation and data growth sometimes outstrips what even the most dedicated tool developers can deliver. +That's why it's the perfect moment to step back and rethink **how** and **why** we analyze AIRR data. +Instead of racing to patch each new problem, we need to prepare for the **next epoch** of immunomics. -## Installation +**What defines this next epoch?** -### Latest release on CRAN -In order to install `immunarch` execute the following command: +A massive shift in focus: from pure research towards biomarker discovery, personalized immunotherapies, and integration of immune repertoire data into real clinical decision-making. -```r -install.packages("immunarch") -``` +Today's AIRR analysis must handle: -That's it, you can start using `immunarch` now! See the [Quick Start](#quick-start) section below to dive into immune repertoire data analysis. If you run in any trouble during installation, take a look at the [Installation Troubleshooting](https://immunarch.com/articles/v1_introduction.html#installation-troubleshooting) section. +- **Multi-modal data:** bulk and single-cell V(D)J, spatial transcriptomics, gene expression, clinical metadata, and antigen specificity -- all together; -Note: there are quite a lot of dependencies to install with the package because it installs all the widely-used packages for data analysis and visualisation. You got both the AIRR data analysis framework and the full Data Science package ecosystem with only one command, making `immunarch` the entry-point for single-cell & immune repertoire Data Science. +- **Massive scale:** experiments that move from gigabytes to tens or hundreds of gigabytes, or even terabytes; +- **Reproducibility and collaboration:** workflows that need to be shared, versioned, and rerun months or years later, sometimes by new teams. -### Latest release on GitHub -If the above command doesn't work for any reason, try installing `immunarch` directly from its repository: +With this new landscape, the **how** and **why** of AIRR data analysis are evolving: -```r -install.packages(c("devtools", "pkgload")) # skip this if you already installed these packages -devtools::install_github("immunomind/immunarch") -devtools::reload(pkgload::inst("immunarch")) -``` +- The focus is moving from "can I parse my data?" to "can I robustly extract insights, find biomarkers, and build ML-ready features for discovery or diagnostics?" +- It's not enough for a toolkit to just work. It needs to scale, interoperate, and empower new kinds of science, including complex Deep Learning and foundation models. -### Latest pre-release on GitHub -Since releasing on CRAN is limited to one release per one or two months, you can install the latest pre-release version with all the bleeding edge and optimised features directly from the code repository. In order to install the latest pre-release version, you need to execute the following commands: +By taking a step back and rethinking the core "how" and "why" of AIRR analysis, `immunarch` prepares you for the next epoch of immunomics -- so your science is ready, whatever comes next. -```r -install.packages(c("devtools", "pkgload")) # skip this if you already installed these packages -devtools::install_github("immunomind/immunarch", ref="dev") -devtools::reload(pkgload::inst("immunarch")) -``` +--- -You can find the list of releases of `immunarch` here: https://github.com/immunomind/immunarch/releases +> [!WARNING] +> `immunarch` is evolving towards `1.0` version and undergoing huge changes. +> Please check the updates here: https://github.com/immunomind/immunarch/issues/432 +> +> To install the latest pre-1.0 version, use `pak::pkg_install("immunomind/immunarch@0.9.1")` +> +> To install the latest 1.0 pre-release version, use `pak::pkg_install("immunomind/immunarch")` +--- -## Key Features +- 🤔 [Why `immundata`?](#-why--immundata-) +- 📦 [Installation](#-installation) +- ⚡ [Quick Start](#-quick-start) +- [📄 Documentation](#-documentation) +- [🪲 Bugs and Issues](#-bugs-and-issues) +- 🏷 [About](#-about) + - [Citation](#citation) + - [License](#license) + - [Author and contributors](#author-and-contributors) + - [Commercial usage](#commercial-usage) -1. Data agnostic. Fast and easy manipulation of immune repertoire data: +--- - + The package automatically detects the format of your files---no more guessing what format is *that* file, just pass them to the package; - - + Supports all popular TCR and BCR analysis and post-analysis formats, including single-cell data: [ImmunoSEQ](https://www.adaptivebiotech.com/adaptive-immunosequencing/), [IMGT](https://www.imgt.org/IMGTindex/IMGTHighV-QUEST.php), [MiTCR](https://github.com/milaboratory/mitcr), [MiXCR](https://github.com/milaboratory/mixcr), [MiGEC](https://github.com/mikessh/migec), [MigMap](https://github.com/mikessh/migmap), [VDJtools](https://github.com/mikessh/vdjtools), [tcR](https://github.com/imminfo/tcr), [AIRR](http://docs.airr-community.org/en/latest/), [10XGenomics](https://www.10xgenomics.com/resources/datasets?menu%5Bproducts.name%5D=Single+Cell+Immune+Profiling), ArcherDX. More coming in the future; +## 📦 Installation - + Works on any data source you are comfortable with: R data frames, data tables from [data.table](https://rdatatable.gitlab.io/data.table/), databases like [MonetDB](https://github.com/MonetDB), Apache Spark data frames via [sparklyr](https://spark.posit.co/); - - + Tutorial is available [here](https://immunarch.com/articles/v2_data.html). +### Prerequisites -2. Beginner-friendly. Immune repertoire analysis made simple: +Before installing any release or pre-release version of `immunarch`, please install `pak` that will simplify the installation of any package, not just `immunarch`: - + Most methods are incorporated in a couple of main functions with clear naming---no more remembering dozens and dozens of functions with obscure names. For details see [link](https://immunarch.com/articles/web_only/v3_basic_analysis.html); +```r +install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/stable/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch)) +``` - + Repertoire overlap analysis *(common indices including overlap coefficient, Jaccard index and Morisita's overlap index)*. Tutorial is available [here](https://immunarch.com/articles/web_only/v4_overlap.html); - - + Gene usage estimation *(correlation, Jensen-Shannon Divergence, clustering)*. Tutorial is available [here](https://immunarch.com/articles/web_only/v5_gene_usage.html); +More info if needed is available on [pak website](https://pak.r-lib.org/#arrow_down-installation). - + Diversity evaluation *(ecological diversity index, Gini index, inverse Simpson index, rarefaction analysis)*. Tutorial is available [here](https://immunarch.com/articles/web_only/v6_diversity.html); +### Install the latest version - + Tracking of clonotypes across time points, widely used in vaccination and cancer immunology domains. Tutorial is available [here](https://immunarch.com/articles/web_only/v8_tracking.html); - - + K-mer distribution measures and statistics. Tutorial is available [here](https://immunarch.com/articles/web_only/v9_kmers.html); - - + Coming in the next releases: CDR3 amino acid physical and chemical properties assessment, mutation networks. +To install the latest release of `immunarch`, simply run: -3. Seamless publication-ready plots with a built-in tool for visualisation manipulation: +```r +pak::pkg_install("immunomind/immunarch") +``` - + Rich visualisation procedures with [ggplot2](https://ggplot2.tidyverse.org/); - - + Built-in tool `FixVis` makes your plots publication-ready: easily change font sizes, text angles, titles, legends and many more with clear-cut GUI; - - + Tutorial is available [here](https://immunarch.com/articles/web_only/v7_fixvis.html). - - -## Quick start -The gist of the typical TCR or BCR data analysis workflow can be reduced to the next few lines of code. +Mind that this will install the package from our GitHub instead of CRAN. This method is much preferred due to limitations of CRAN and reliance on other packages, which are distributed via `pak` as well. -### Use `immunarch` data +### Other installation options -**1) Load the package and the data** +We will periodically release `immunarch` on CRAN. To install it from CRAN, run ```r -library(immunarch) # Load the package into R -data(immdata) # Load the test dataset +pak::pkg_install("immunarch") ``` -**2) Calculate and visualise basic statistics** +If you are willing to try unstable yet bleeding edge features, or if there are some hot fix for your open GitHub ticket, please install the development version: ```r -repExplore(immdata$data, "lens") %>% vis() # Visualise the length distribution of CDR3 -repClonality(immdata$data, "homeo") %>% vis() # Visualise the relative abundance of clonotypes +pak::pkg_install("immunomind/immunarch@dev") ``` -**3) Explore and compare T-cell and B-cell repertoires** + +## ⚡ Quick Start + ```r -repOverlap(immdata$data) %>% vis() # Build the heatmap of public clonotypes shared between repertoires -geneUsage(immdata$data[[1]]) %>% vis() # Visualise the V-gene distribution for the first repertoire -repDiversity(immdata$data) %>% vis(.by = "Status", .meta = immdata$meta) # Visualise the Chao1 diversity of repertoires, grouped by the patient status +# Install `pak` - a blazingly-fast package manager +install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/stable/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch)) + +# Install and load immunarch along with the pre-packaged data +pak::pkg_install("immundata/immunarch") +library(immunarch) +immdata <- get_test_idata() |> agg_repertoires("Therapy") + +# In just 4 lines of code you get the essential AIRR statistics +airr_stats_genes(immdata, gene_col = "v_call") +airr_public_jaccard(immdata) +airr_clonality_prop(immdata) +airr_diversity_pielou(immdata) + +# Use your own data by reading sample files from the metadata file +mdtable <- read_metadata("data/metadata.csv") +immdata <- read_repertoires("", metadata = mdtable) + +# Use your own data by reading sample files directly +mdtable <- read_metadata("data/metadata.csv") +immdata <- read_repertoires("data/*.tsv.gz", metadata = mdtable) ``` -### Use your own data +Oh, and one small thing. Even if you have tens of gigabytes of the data, you won't need to adapt the code to a server. +The code will be exactly the same — `immunarch` got your back thanks to [`immundata`](https://github.com/immunomind/immundata/). + + +## 📄 Documentation + +To get a list of available methods and their descriptions, run the default help command in R on specific functions or on a function family prefix: ```r -library(immunarch) # Load the package into R -immdata <- repLoad("path/to/your/data") # Replace it with the path to your data. Immunarch automatically detects the file format. -``` +# This is the same +?airr_stats +# as this +?airr_stats_genes + +# Basic statistics - gene usage, length distribution +?airr_stats + +# Public receptor indices - overlap, jaccard, morisita +?airr_public -### Advanced methods +# Clonality analysis - clonal lines, occupied space, clonal space homeostasis +?airr_clonality -For advanced methods such as clonotype annotation, clonotype tracking, k-mer analysis and public repertoire analysis see "Tutorials". +# Diversity analysis - pielou, shannon, chao1 +?airr_diversity + +# ... more to come ... +``` + +More detailed documentation, guides and comprehensive tutorials are available on the ecosystem website: [https://immunomind.github.io/docs/](https://immunomind.github.io/docs/). -## Bugs and Issues +## 🪲 Bugs and Issues -The mission of `immunarch` is to make bulk and single-cell immune repertoires analysis painless. All bug reports, documentation improvements, enhancements and ideas are appreciated. Just let us know via [GitHub](https://github.com/immunomind/immunarch/issues) (preferably) or [support@immunomind.io](mailto:support@immunomind.io) (in case of private data). +The mission of `immunarch` is to make bulk and single-cell immune repertoires analysis painless. All bug reports, documentation improvements, enhancements and ideas are appreciated. Just let us know via [GitHub](https://github.com/immunomind/immunarch/issues) (preferably) or [support@immunomind.com](mailto:support@immunomind.com) (in case of private data). Bug reports must: 1. Include a short, self-contained R snippet reproducing the problem. -2. Add a minimal data sample for us to reproduce the problem. In case of sensitive data you can send it to [support@immunomind.io](mailto:support@immunomind.io) instead of GitHub issues. +2. Add a minimal data sample for us to reproduce the problem. In case of sensitive data you can send it to [support@immunomind.com](mailto:support@immunomind.com) instead of GitHub issues. 3. Explain why the current behavior is wrong/not desired and what you expect instead. 4. If the issue is about visualisations, please attach a picture to the issue. In other case we wouldn't be able to reproduce the bug and fix it. +We are always open to contributions. There are three ways to contribute: -## Help the community +1. Create an issue [here](https://github.com/immunomind/immunarch/issues) and describe what would you like to improve or discuss. -Aspiring to help the community build the ecosystem of scRNAseq & AIRR analysis tools? Found a bug? A typo? Would like to improve documentation, add a method or optimise an algorithm? +2. Create an issue or find one [here](https://github.com/immunomind/immunarch/issues), fork the repository and make a pull request with the bugfix or improvement. -We are always open to contributions. There are two ways to contribute: +3. Find an existing issue and help others resolve this. -1. Create an issue [here](https://github.com/immunomind/immunarch/issues) and describe what would you like to improve or discuss. -2. Create an issue or find one [here](https://github.com/immunomind/immunarch/issues), fork the repository and make a pull request with the bugfix or improvement. +## 🏷 About +### Citation -## Citation +> Temporary citation is below. The main manuscript is in preparation. Preprint on BioArxiv is coming soon as of 2025. ImmunoMind Team. (2019). immunarch: An R Package for Painless Bioinformatics Analysis of T-Cell and B-Cell Immune Repertoires. Zenodo. http://doi.org/10.5281/zenodo.3367200 @@ -211,14 +259,20 @@ BibTex: For EndNote citation import the [`immunarch-citation.xml`](https://gitlab.com/immunomind/immunarch/raw/master/immunarch-citation.xml?inline=false) file. -Preprint on BioArxiv is coming soon. - -## License +### License The package is freely distributed under the Apache-2.0 license. You can read more about it [here](https://www.tldrlegal.com/license/apache-license-2-0-apache-2-0). -For commercial or server use, please contact ImmunoMind via [support@immunomind.io](mailto:support@immunomind.io) about solutions for biomarker data science of single-cell immune repertoires. +### Author and contributors + +- **Vadim I. Nazarov – main author and developer** +- Vasily Tsvetkov +- Aleksandr Popov +- Ivan Balashov + +### Commercial usage +`immunarch` is free to use for commercial usage as per Apache-2.0 license. However, corporate users will not get a prioritized support for `immunarch`- or AIRR-related issues. The priority of open-source tool `immunarch` is open-source science. -## Commercial Support +If you are looking for prioritized support and setting up your data pipelines, consider contacting [Vadim Nazarov](https://www.linkedin.com/in/vdnaz/) for commercial consulting / support options / workshops and training sessions / designing data platforms and machine learning systems for multi-omics / or anything related. From 17615f4ab826779c2519692d0f12b11ed1d3d890 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 9 Sep 2025 17:54:56 +0200 Subject: [PATCH 24/36] chore: website update --- _pkgdown.yml | 71 ++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index fe6f3732..cb97fe46 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1,8 +1,10 @@ url: https://immunarch.com template: bootstrap: 5 + bslib: + bootswatch: cosmo + pkgdown-nav-height: 100px params: - bootswatch: flatly ganalytics: UA-128418614-2 authors: ImmunoMind: @@ -16,12 +18,8 @@ authors: Ivan Balashov: href: https://www.linkedin.com/in/ivan-balashov/ articles: -- title: "immunarch v1.0" - desc: ~ - contents: - - immunarch - - articles/singlecell -- title: "immunarch v0.9" +- title: "Immunarch v0.9" + subtitle: "Deprecated" desc: ~ contents: - '`web_only_v0/introduction`' @@ -43,39 +41,26 @@ articles: - '`web_only_v0/BCRpipeline`' - '`web_only_v0/clustering`' navbar: + bg: dark + type: dark structure: - left: [articles, reference, migration] - right: [im_link, twitter, github] + left: [tutorial, articles, reference] + right: [github] components: home: ~ news: ~ tutorial: - text: "⚡ Start Here - Tutorial for v1.0" - href: articles/singlecell.html + text: "Immunarch v1.0" + href: https://immunomind.github.io/docs/tutorials/single-cell/ migration: - text: "🚢 Migration Guide" - href: articles/immunarch.html + text: "Migration Guide" + href: https://immunomind.github.io/docs/tutorials/migration/ reference: text: "Reference" href: reference/index.html articles: - text: "Guides & Tutorials" + text: "Immunarch v0.9" menu: - - text: '---' - - text: "IMMUNARCH v1.0" - - # - text: "Tutorial for bulk/single-cell and single-/paired-chain data" - # href: articles/web_only_v1/tutorial_singlecell.html - - - text: '---' - - text: "... more coming soon ..." - - - text: '---' - - text: "IMMUNARCH v0.9" - - - text: '---' - - text: "Package" - - text: "Installation & troubleshooting" href: articles/web_only_v0/introduction.html @@ -142,27 +127,43 @@ navbar: - text: Clustering href: articles/web_only_v0/clustering.html - twitter: - icon: fa-lg fa-twitter - href: http://twitter.com/immunomind - im_link: - text: ImmunoMind - href: https://immunomind.com github: icon: fa-github href: https://github.com/immunomind/immunarch reference: - title: Stable, v1.0 +- subtitle: ... work in progress ... - contents: - has_lifecycle("stable") - title: Experimental, v1.0 +- subtitle: Repertoire descriptive statistics +- contents: + - starts_with("airr_stats") + +- subtitle: Clonality +- contents: + - starts_with("airr_clonality") + +- subtitle: Diversity +- contents: + - starts_with("airr_diversity") + +- subtitle: Public indices +- contents: + - starts_with("airr_public") + +- subtitle: Technical - contents: - has_lifecycle("experimental") - has_concept("data") - has_concept("migration_utility") + - -starts_with("airr_stats") + - -starts_with("airr_clonality") + - -starts_with("airr_diversity") + - -starts_with("airr_public") - title: Under Question, v0.9 -> v1.0 From a090a1b66925363c9d5b04969e56eba92ca00a09 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 9 Sep 2025 18:03:09 +0200 Subject: [PATCH 25/36] feat: basic vignette --- vignettes/immunarch.Rmd | 291 ++++++++++++++++++++++++++++++++++++++++ vignettes/immunarch.qmd | 196 --------------------------- 2 files changed, 291 insertions(+), 196 deletions(-) create mode 100644 vignettes/immunarch.Rmd delete mode 100644 vignettes/immunarch.qmd diff --git a/vignettes/immunarch.Rmd b/vignettes/immunarch.Rmd new file mode 100644 index 00000000..db75e0fe --- /dev/null +++ b/vignettes/immunarch.Rmd @@ -0,0 +1,291 @@ +--- +title: "immunarch" +output: html_document +--- + + + +
+

🧬 immunarch --- Multi-modal immune repertoire analysis in R

+
+ +--- + + + +

+ Tutorials + | + API reference + | + Ecosystem + | + Publication (coming soon...) +

+ +--- + +`immunarch` brings a comprehensive analytics toolkit to build reproducible analysis pipelines for Adaptive Immune Receptor Repertoire (AIRR) data with a particular focus on designing personalized immunotherapies and vaccines. Key features are: + +- **Multi-modal immune profiling:** compute receptor- and repertoire-level statistics leveraging single-cell, spatial, immunogenicity or any other receptor annotations; + +- **Immunomics at scale:** work seamlessly with datasets that don't fit in memory; + +- **Immune biomarker discovery:** stratify cohorts and timepoints, derive repertoire signatures (diversity/clonality, V/J usage, similarity), and track antigen-annotated clonotypes; + +- **Feature engineering:** build Machine Learning-ready feature tables (receptor-, ssample- and cohort-level) from core repertoire metrics and annotations, with consistent IDs/metadata for downstream statistics or modeling; + +- **Modular, extendable, adaptable:** add new analyses and metrics via a extension API, and use adapters to interoperate with other AIRR tools and formats. + + +## 🤔 Why `immunarch`? + +As immune repertoire sequencing becomes a mainstream technology, adopted by major platforms and integrated into more translational and clinical workflows, tooling expectations are changing rapidly. +The pace of innovation and data growth sometimes outstrips what even the most dedicated tool developers can deliver. + +That's why it's the perfect moment to step back and rethink **how** and **why** we analyze AIRR data. +Instead of racing to patch each new problem, we need to prepare for the **next epoch** of immunomics. + +**What defines this next epoch?** + +A massive shift in focus: from pure research towards biomarker discovery, personalized immunotherapies, and integration of immune repertoire data into real clinical decision-making. + +Today's AIRR analysis must handle: + +- **Multi-modal data:** bulk and single-cell V(D)J, spatial transcriptomics, gene expression, clinical metadata, and antigen specificity -- all together; + +- **Massive scale:** experiments that move from gigabytes to tens or hundreds of gigabytes, or even terabytes; + +- **Reproducibility and collaboration:** workflows that need to be shared, versioned, and rerun months or years later, sometimes by new teams. + +With this new landscape, the **how** and **why** of AIRR data analysis are evolving: + +- The focus is moving from "can I parse my data?" to "can I robustly extract insights, find biomarkers, and build ML-ready features for discovery or diagnostics?" + +- It's not enough for a toolkit to just work. It needs to scale, interoperate, and empower new kinds of science, including complex Deep Learning and foundation models. + +By taking a step back and rethinking the core "how" and "why" of AIRR analysis, `immunarch` prepares you for the next epoch of immunomics -- so your science is ready, whatever comes next. + +--- + +> [!WARNING] +> `immunarch` is evolving towards `1.0` version and undergoing huge changes. +> Please check the updates here: https://github.com/immunomind/immunarch/issues/432 +> +> To install the latest pre-1.0 version, use `pak::pkg_install("immunomind/immunarch@0.9.1")` +> +> To install the latest 1.0 pre-release version, use `pak::pkg_install("immunomind/immunarch")` + +--- + +- 🤔 [Why `immundata`?](#-why--immundata-) +- 📦 [Installation](#-installation) +- ⚡ [Quick Start](#-quick-start) +- [📄 Documentation](#-documentation) +- [🪲 Bugs and Issues](#-bugs-and-issues) +- 🏷 [About](#-about) + - [Citation](#citation) + - [License](#license) + - [Author and contributors](#author-and-contributors) + - [Commercial usage](#commercial-usage) + +--- + +## 📦 Installation + +### Prerequisites + +Before installing any release or pre-release version of `immunarch`, please install `pak` that will simplify the installation of any package, not just `immunarch`: + +```r +install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/stable/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch)) +``` + +More info if needed is available on [pak website](https://pak.r-lib.org/#arrow_down-installation). + +### Install the latest version + +To install the latest release of `immunarch`, simply run: + +```r +pak::pkg_install("immunomind/immunarch") +``` + +Mind that this will install the package from our GitHub instead of CRAN. This method is much preferred due to limitations of CRAN and reliance on other packages, which are distributed via `pak` as well. + +### Other installation options + +We will periodically release `immunarch` on CRAN. To install it from CRAN, run + +```r +pak::pkg_install("immunarch") +``` + +If you are willing to try unstable yet bleeding edge features, or if there are some hot fix for your open GitHub ticket, please install the development version: + +```r +pak::pkg_install("immunomind/immunarch@dev") +``` + + +## ⚡ Quick Start + +```r +# Install `pak` - a blazingly-fast package manager +install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/stable/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch)) + +# Install and load immunarch along with the pre-packaged data +pak::pkg_install("immundata/immunarch") +library(immunarch) +immdata <- get_test_idata() |> agg_repertoires("Therapy") + +# In just 4 lines of code you get the essential AIRR statistics +airr_stats_genes(immdata, gene_col = "v_call") +airr_public_jaccard(immdata) +airr_clonality_prop(immdata) +airr_diversity_pielou(immdata) + +# Use your own data by reading sample files from the metadata file +mdtable <- read_metadata("data/metadata.csv") +immdata <- read_repertoires("", metadata = mdtable) +``` + +```r eval=FALSE +# Use your own data by reading sample files directly +mdtable <- read_metadata("data/metadata.csv") +immdata <- read_repertoires("data/*.tsv.gz", metadata = mdtable) +``` + +Oh, and one small thing. Even if you have tens of gigabytes of the data, you won't need to adapt the code to a server. +The code will be exactly the same — `immunarch` got your back thanks to [`immundata`](https://github.com/immunomind/immundata/). + + +## 📄 Documentation + +To get a list of available methods and their descriptions, run the default help command in R on specific functions or on a function family prefix: + +```r +# This is the same +?airr_stats +# as this +?airr_stats_genes + +# Basic statistics - gene usage, length distribution +?airr_stats + +# Public receptor indices - overlap, jaccard, morisita +?airr_public + +# Clonality analysis - clonal lines, occupied space, clonal space homeostasis +?airr_clonality + +# Diversity analysis - pielou, shannon, chao1 +?airr_diversity + +# ... more to come ... +``` + +More detailed documentation, guides and comprehensive tutorials are available on the ecosystem website: [https://immunomind.github.io/docs/](https://immunomind.github.io/docs/). + + +## 🪲 Bugs and Issues + +The mission of `immunarch` is to make bulk and single-cell immune repertoires analysis painless. All bug reports, documentation improvements, enhancements and ideas are appreciated. Just let us know via [GitHub](https://github.com/immunomind/immunarch/issues) (preferably) or [support@immunomind.com](mailto:support@immunomind.com) (in case of private data). + +Bug reports must: + +1. Include a short, self-contained R snippet reproducing the problem. +2. Add a minimal data sample for us to reproduce the problem. In case of sensitive data you can send it to [support@immunomind.com](mailto:support@immunomind.com) instead of GitHub issues. +3. Explain why the current behavior is wrong/not desired and what you expect instead. +4. If the issue is about visualisations, please attach a picture to the issue. In other case we wouldn't be able to reproduce the bug and fix it. + +We are always open to contributions. There are three ways to contribute: + +1. Create an issue [here](https://github.com/immunomind/immunarch/issues) and describe what would you like to improve or discuss. + +2. Create an issue or find one [here](https://github.com/immunomind/immunarch/issues), fork the repository and make a pull request with the bugfix or improvement. + +3. Find an existing issue and help others. + + +## 🏷 About + +### Citation + +> Temporary citation is below. The main manuscript is in preparation. Preprint on BioArxiv is coming soon as of 2025. + +ImmunoMind Team. (2019). immunarch: An R Package for Painless Bioinformatics Analysis of T-Cell and B-Cell Immune Repertoires. Zenodo. http://doi.org/10.5281/zenodo.3367200 + +BibTex: +``` +@misc{immunomind_team_2019_3367200, + author = {{ImmunoMind Team}}, + title = {{immunarch: An R Package for Painless Bioinformatics Analysis + of T-Cell and B-Cell Immune Repertoires}}, + month = aug, + year = 2019, + doi = {10.5281/zenodo.3367200}, + url = {https://doi.org/10.5281/zenodo.3367200} +} +``` + +For EndNote citation import the [`immunarch-citation.xml`](https://gitlab.com/immunomind/immunarch/raw/master/immunarch-citation.xml?inline=false) file. + + +### License + +The package is freely distributed under the Apache-2.0 license. You can read more about it [here](https://www.tldrlegal.com/license/apache-license-2-0-apache-2-0). + +### Author and contributors + +- **Vadim I. Nazarov – main author and developer** +- Vasily Tsvetkov +- Aleksandr Popov +- Ivan Balashov + +### Commercial usage + +`immunarch` is free to use for commercial usage as per Apache-2.0 license. However, corporate users will not get a prioritized support for `immunarch`- or AIRR-related issues. The priority of open-source tool `immunarch` is open-source science. + +If you are looking for prioritized support and setting up your data pipelines, consider contacting [Vadim Nazarov](https://www.linkedin.com/in/vdnaz/) for commercial consulting / support options / workshops and training sessions / designing data platforms and machine learning systems for multi-omics / or anything related. diff --git a/vignettes/immunarch.qmd b/vignettes/immunarch.qmd deleted file mode 100644 index a5604a80..00000000 --- a/vignettes/immunarch.qmd +++ /dev/null @@ -1,196 +0,0 @@ ---- -title: "Immunarch 1.0 --- introduction and migration from 0.9 version" -author: "Vadim Nazarov" -date: "`r Sys.Date()`" -format: - html: - toc: true - number-sections: true - # theme: none - # minimal: true -vignette: > - %\VignetteIndexEntry{Immunarch} - %\VignetteEngine{quarto::html} - %\VignetteEncoding{UTF-8} ---- - -Install specific version via `pak::pkg_install("immunarch@=0.9.1")`. - -Mind that the 0.9.x versions will NOT be supported. If something breaks, if some R package dive into oblivion - it won't be fixed, sorry. So it is highly advised to move to the new 1.0 version ASAP, especially considering that the feature parity will be obtained in months. - -However, there is high priority to obrain feature parity, stability and add features for the most common uses case and several complex use cases fcused on immunotherapy development. So please consider switching. Open an issue - I'm willing to help. - -why removed vis -> because it brings only a quick value, hides all the complexity so people created issues to adapt the plot, and they are not publication ready plots. So I opt out to remove them, but focus on helping people learn how to visualise stuff. That's why tutorials will have more visualisation examples. - -In the future I still plan to provide something using more common approachs via ggplot2::autoplot, but it's out of scope for now. - -Short asnwer: great for fast analysis, but as soon as you need something more custom or complex, it becomes too hard to tune and it's easier to write your own from scratch. - -# TODO - -- [ ] I need to clearly state somewhere the list of v1 functions that use immundata. Maybe here or in the updates - -- [ ] lifecycle::deprecated tag for v0 functions - -- [ ] Frame the immundata. - -- [ ] Link to ImmunData README tutorial somewhere - -# Overview - -There are three major points related to transformations: - -1. **How immunarch 1.0.0 works with data**\ -2. **Interface or API changes** (i.e., names and parameters of the functions in immunarch)\ -3. **Removing / moving some functions to a separate package** to make immunarch easier to install and manage - -For more long-term plans, take a look at the final sections. If you’re only interested in what to do **right now**, keep reading below. - ------------------------------------------------------------------------- - -# Major update for the current version: Spring 2025 - - -## What Changed and What You Can Do - -- **Removed heavier dependencies** (ggpubr, factoextra, fpc, ggraph, phangorn, igraph, etc.). - - This was partly due to CRAN requirements and overall maintenance overhead.\ - - The **good news** is that immunarch now needs \~80 packages to install (down from 184!).\ - - If your analysis code relied on these libraries, you can still install them separately. -- **Functionality**: - - If you’ve been using immunarch for a while, most immunarch function signatures remain the same.\ - - - If you see errors asking for those removed packages, simply install them manually. For example: - - ``` r - install.packages("ggpubr") - ``` - - Then re-run your analysis. -- **immundata Integration**: - - We’re introducing better synergy with Immundata. [See details in the “Scalable and fast data processing” section](#scalable-and-fast-data-processing).\ - - You can seamlessly convert older immunarch data objects to the new `ImmunData` format. - -### Key Takeaways - -- **Lighter** default install: less “bloat” you don’t need.\ -- Additional packages can be installed on-demand if your scripts require them.\ -- You shouldn’t see breaking changes in function usage — **only** in how to handle optional libraries. - ------------------------------------------------------------------------- - -# Next Major Update: Summer 2025 - -## What Will Be Changed - -- **Refined Data Structures**: - - We plan to unify the internal data structure for single-cell vs. bulk repertoire data.\ - - The old `immdata` approach will be replaced or augmented by a more consistent framework. -- **Deprecated Functions**: - - Some older convenience wrappers will be marked deprecated.\ - - We’ll provide new recommended calls in the console messages. -- **Possibly More Dependency Splits**: - - Additional packages (e.g., PCA or tree-based analysis libraries) might move out.\ - - A new “immunarch.ext” or similarly named extension package might appear with specialized analyses. - -## What Can You Do to Mitigate Risks - -1. **Pin Your Dependencies** - - Use `renv` or a Docker image to lock your environment if you need stable re-runs.\ -2. **Watch for Deprecation Warnings** - - If you see console messages about “deprecated” or “will be removed in v1.1.0,” update your code ASAP.\ -3. **Try Out Immundata** - - If you handle complex or large-scale data, consider migrating to `ImmunData` early.\ - - [See the “How immunarch 1.0.0 will look” section](#how-immunarch-100-will-look-like) for more details on Immundata synergy. - ------------------------------------------------------------------------- - -# Future Major Updates: Autumn-Winter 2025 - -## What Will Be Changed - -- **Deeper Integration with Immundata** - - We plan to store certain immunarch metadata in `ImmunData` structures by default.\ - - One possibility: all immunarch pipeline steps become “ImmunData” transformations under the hood. -- **Performance Overhaul** - - We may adopt new backends (DuckDB, Polars) for bigger data sets.\ - - This may involve changes to how custom analysis scripts are written. - -## What Can You Do to Mitigate Risks - -1. **Stay Updated** - - Subscribe to the immunarch newsletter or GitHub releases to see upcoming changes.\ -2. **Adopt the “New Way” Early** - - If you see a function is overshadowed by a newer `ImmunData`-based alternative, switch now.\ -3. **Check Release Notes** - - We post details on the migration paths, including function renaming or column renaming. - ------------------------------------------------------------------------- - -# How immunarch 1.0.0 Will Look Like - -## Why Do We Even Need 1.0.0? - -- **Outdated code** that’s hard to maintain, especially in an academic environment where developer turnover is high.\ -- **Improved code culture**: adopting best practices, standard data structures, consistent naming.\ -- **User feedback**: Many users asked for more scalable and flexible pipelines. - -### High-Level Goals - -1. **More maintainable code** base. -2. **Less friction** with environment setups. -3. **Consistent syntax** and naming conventions. - -## Scalable and Fast Data Processing {#scalable-and-fast-data-processing} - -- **Lazy Backends**: We’re exploring or partially implementing backends like DuckDB or Arrow. - - Potential performance boosts for big repertoires.\ - - Immundata is designed to be backend-agnostic.\ -- **Parallelization**: Where possible, certain immarch steps will parallelize out-of-the-box. - -### How Immundata Helps - -- We introduced [Immundata](https://github.com/yourrepo/immundata) to unify TCR/BCR data.\ -- `ImmunData` objects can seamlessly handle single-cell or bulk data in a single pipeline.\ -- The biggest advantage is the **unified schema** (receptor, annotations, repertoire definitions). - -## Lighter Interface - -- Reducing hidden dependencies means fewer manual installs.\ -- Possibly removing large plotting packages from the core install.\ -- You’ll see many advanced visualizations in optional extension modules. - -## Modularizing the Ecosystem - -- In the near future, we plan to have: - - **immunarch.core**: essential data processing.\ - - **immunarch.plots**: advanced visualization.\ - - **immunarch.bioinfo**: alignment, clonotype assignment, etc.\ -- Each sub-package can be installed only if you need that functionality. - ------------------------------------------------------------------------- - -# Proposed Outline / Sections to Expand Further - -1. **Installation Details** - - Precisely how to install or upgrade to immunarch 1.0.0.\ - - Example: `install.packages("immunarch")` (once it’s on CRAN).\ -2. **Detailed Migration Steps** - - If you used old code, step-by-step instructions (like “Replace `immdata$data[[i]]` with `ImmunData$new(...)`”).\ - - Potential script transformation examples.\ -3. **FAQ** - - “I see errors about missing packages?” → install them.\ - - “Where can I find the old plot() function?” → in `immunarch.plots`.\ -4. **Future “Beta” or “Dev” versions** - - Encourage users to test the dev branch if they want the newest changes.\ -5. **In-depth Immundata Demonstrations** - - Show how to create an `ImmunData` from a typical immunarch object.\ - - Show how to use Immundata’s new filter or aggregation pipelines. - ------------------------------------------------------------------------- - -# Conclusion - -immunarch 1.0.0 is a major step in making immune repertoire analysis **lighter**, **faster**, and **easier to maintain**. While many changes revolve around removing heavy dependencies, the core **user experience** should remain familiar. For large or advanced analyses, consider exploring **Immundata** to leverage its robust data structure and efficient transformations. - -Stay tuned for more updates in **Summer 2025** and **Autumn-Winter 2025**, and don’t hesitate to **reach out** on GitHub or our user forum if you have questions or encounter migration issues. From de20ef02e9cb78eab5ca0281f05a1b238dd6759a Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 9 Sep 2025 18:03:41 +0200 Subject: [PATCH 26/36] docs: minor updates to docs and, you won't believe it, update --- R/immunarch-package.R | 1 + R/v0_distance.R | 4 +- R/v0_io.R | 2 + R/v1_airr_clonality.R | 8 +- R/v1_airr_diversity.R | 8 +- R/v1_airr_public.R | 8 +- R/v1_airr_stats.R | 48 ++- R/v1_migration_updates.R | 53 ++++ R/v1_migration_utils.R | 42 +++ R/v1_package.R | 28 ++ R/zzz.R | 122 ++------ man/airr_clonality.Rd | 9 +- man/airr_diversity.Rd | 9 +- man/airr_public.Rd | 7 +- man/airr_stats.Rd | 46 +-- man/repSave.Rd | 2 + man/seqDist.Rd | 4 +- vignettes/articles/.gitignore | 2 - vignettes/articles/singlecell.qmd | 483 ------------------------------ 19 files changed, 255 insertions(+), 631 deletions(-) create mode 100644 R/v1_migration_updates.R create mode 100644 R/v1_migration_utils.R create mode 100644 R/v1_package.R delete mode 100644 vignettes/articles/.gitignore delete mode 100644 vignettes/articles/singlecell.qmd diff --git a/R/immunarch-package.R b/R/immunarch-package.R index a6330ec6..76eddd95 100644 --- a/R/immunarch-package.R +++ b/R/immunarch-package.R @@ -52,6 +52,7 @@ #' @importFrom rlang is_true #' @importFrom rlang set_names #' @importFrom rlang sym +#' @importFrom stats runif #' @importFrom utils globalVariables #' @useDynLib immunarch, .registration = TRUE ## usethis namespace: end diff --git a/R/v0_distance.R b/R/v0_distance.R index 0db310da..c6f8738f 100644 --- a/R/v0_distance.R +++ b/R/v0_distance.R @@ -51,7 +51,7 @@ #' Named list of list with [dist] objects for given repertoires for each combination of .group_by variable(s) and/or sequence length of .col. #' #' @examples -#' +#' \dontrun{ #' data(immdata) #' # Reducing data to save time on examples #' immdata$data <- map(immdata$data, ~ .x %>% head(10)) @@ -71,6 +71,8 @@ #' } #' #' seqDist(immdata$data[1:2], .method = f, .group_by_seqLength = FALSE) +#' } +#' #' @export seqDist seqDist <- function(.data, diff --git a/R/v0_io.R b/R/v0_io.R index 08a5acb4..4e6db265 100644 --- a/R/v0_io.R +++ b/R/v0_io.R @@ -455,6 +455,7 @@ repLoad <- function(.path, .mode = "paired", .coding = TRUE, ...) { #' @return No return value. #' #' @examples +#' \dontrun{ #' data(immdata) #' # Reduce data to save time on examples #' immdata$data <- map(immdata$data, ~ .x %>% head(10)) @@ -466,6 +467,7 @@ repLoad <- function(.path, .mode = "paired", .coding = TRUE, ...) { #' # sum(immdata$data[[1]] != new_immdata$data[[1]], na.rm = TRUE) #' # sum(immdata$data[[2]] != new_immdata$data[[2]], na.rm = TRUE) #' # sum(immdata$meta != new_immdata$meta, na.rm = TRUE) +#' } #' @export repSave repSave <- function(.data, .path, .format = c("immunarch", "vdjtools"), .compress = TRUE) { diff --git a/R/v1_airr_clonality.R b/R/v1_airr_clonality.R index a1e37c9e..a5099cc7 100644 --- a/R/v1_airr_clonality.R +++ b/R/v1_airr_clonality.R @@ -5,7 +5,9 @@ #' #' A family of functions to quantify **receptor overabundance** per repertoire. Helps in deciphering the structure and partition the repertoire. #' -#' ## Available functions: +#' ## Available functions +#' +#' Supported methods are the following. #' #' @param idata An `ImmunData` object. #' @inheritParams airr_clonality_line @@ -15,6 +17,10 @@ #' #' @seealso [immundata::ImmunData] #' +#' @examples +#' # Load data +#' immdata <- get_test_idata() |> agg_repertoires("Therapy") +#' #' @name airr_clonality #' @concept Clonality NULL diff --git a/R/v1_airr_diversity.R b/R/v1_airr_diversity.R index 47995428..516fb922 100644 --- a/R/v1_airr_diversity.R +++ b/R/v1_airr_diversity.R @@ -5,7 +5,9 @@ #' #' A family of functions to quantify **receptor diversity** per repertoire. A characteristic of a whole repertoire. #' -#' ## Available functions: +#' ## Available functions +#' +#' Supported methods are the following. #' #' @param idata An `ImmunData` object. #' @inheritParams airr_diversity_dxx @@ -17,6 +19,10 @@ #' #' @seealso [immundata::ImmunData] #' +#' @examples +#' # Load data +#' immdata <- get_test_idata() |> agg_repertoires("Therapy") +#' #' @name airr_diversity #' @concept Diversity NULL diff --git a/R/v1_airr_public.R b/R/v1_airr_public.R index 6c8089af..7e4a619e 100644 --- a/R/v1_airr_public.R +++ b/R/v1_airr_public.R @@ -5,7 +5,9 @@ #' #' A family of functions to quantify **public or shared receptors** between repertoire. #' -#' ## Available functions: +#' ## Available functions +#' +#' Supported methods are the following. #' #' @param idata An `ImmunData` object. #' @inheritParams airr_public_intersection @@ -14,6 +16,10 @@ #' #' @seealso [immundata::ImmunData] #' +#' @examples +#' # Load data +#' immdata <- get_test_idata() |> agg_repertoires("Therapy") +#' #' @name airr_public #' @concept Public indices NULL diff --git a/R/v1_airr_stats.R b/R/v1_airr_stats.R index 6fe73118..e1bec2d0 100644 --- a/R/v1_airr_stats.R +++ b/R/v1_airr_stats.R @@ -5,7 +5,9 @@ #' #' A family of functions that extract **core descriptive statistics** from an `ImmunData` object. #' -#' ## Available functions: +#' ## Available functions +#' +#' Supported methods are the following. #' #' @param idata An `ImmunData` object. #' @inheritParams airr_stats_chains @@ -15,6 +17,10 @@ #' #' @seealso [immundata::ImmunData] #' +#' @examples +#' # Load data +#' immdata <- get_test_idata() |> agg_repertoires("Therapy") +#' #' @name airr_stats #' @concept Key AIRR statistics NULL @@ -58,14 +64,18 @@ airr_stats_chains_impl <- function(idata, locus_col = NA) { } -#' @description `airr_stats_chains` --- count V(D)J *chains* per repertoire (optionally split by locus). WHY USEFUL / APPLICATION? +#' @description `airr_stats_chains` --- count V(D)J *chains* per repertoire +#' (optionally split by locus). Quickly gauges capture depth per repertoire +#' and, when split by locus, reveals TRA/TRB/IGH balance. Use it for QC, +#' library-size checks, and to spot locus-specific dropouts or +#' over-representation. #' -#' @param locus_col Column in `idata$annotations` that stores the locus (e.g. `"locus"`). If `NULL` or missing, the result is not split by locus. +#' @param locus_col Column in `idata$annotations` that stores the locus (e.g. +#' `"locus"`). If `NULL` or missing, the result is not split by locus. #' #' @return #' -#' ## `airr_stats_chains` -#' Returns a tibble with columns: +#' ## `airr_stats_chains` Returns a tibble with columns: #' * `repertoire_id` -- repertoire identifier #' * `locus` -- TRA, TRB, IGH … (present only if `locus_col` is supplied) #' * `n_chains` -- number of chains @@ -96,14 +106,18 @@ airr_stats_lengths_impl <- function(idata, seq_col = "cdr3_aa") { } -#' @description `airr_stats_lengths` --- count the number of sequence lengths per repertoire. WHY USEFUL / APPLICATION? +#' @description `airr_stats_lengths` --- count the number of sequence lengths +#' per repertoire. Summarizes the CDR3 length distribution, a sensitive QC +#' fingerprint of repertoire prep and selection. Helpful for detecting +#' primer/UMI biases, comparing cohorts, and deriving length-based features for +#' models. #' -#' @param seq_col Character vector with names of the columns containing sequences. +#' @param seq_col Character vector with names of the columns containing +#' sequences. #' #' @return #' -#' ## `airr_stats_lengths` -#' Returns a tibble with columns: +#' ## `airr_stats_lengths` Returns a tibble with columns: #' * `repertoire_id` -- repertoire identifier #' * `seq_len` -- lengths of sequences #' * `n` -- number of receptors @@ -146,15 +160,18 @@ airr_stats_genes_impl <- function(idata, gene_col = "v_call", level = c("recepto } #' @description `airr_stats_genes` — count V(D)J gene segments per repertoire, -#' optionally split by locus and using either receptor counts or barcode/UMI -#' counts as the measure. WHY USEFUL / APPLICATION? +#' optionally split by locus and using either receptor counts or barcode/UMI +#' counts as the measure. Profiles V/D/J gene usage to characterize repertoire +#' composition and germline biases, with optional locus split. Useful for +#' cohort comparisons, flagging clonal expansions, and producing ML-ready +#' features for repertoire-level ML tasks. #' #' @param gene_col A single column name in `idata$annotations` with gene segment #' calls (e.g., `"v_call"`, `"d_call"`, `"j_call"`, `"c_call"`). Default is #' `"v_call"`. #' @param level One of `"receptor"` or `"barcode"`. If `"receptor"` (default), -#' the function counts **unique receptors** (one per receptor ID) that carry -#' a given gene segment. If `"barcode"`, the function **sums counts** (e.g., +#' the function counts **unique receptors** (one per receptor ID) that carry a +#' given gene segment. If `"barcode"`, the function **sums counts** (e.g., #' cells/UMIs) per gene segment using the column defined by #' `immundata::imd_schema("count")`. #' @param by Either `NULL` (no split) or `"locus"`. When `"locus"`, the result @@ -164,11 +181,10 @@ airr_stats_genes_impl <- function(idata, gene_col = "v_call", level = c("recepto #' #' @return #' -#' ## `airr_stats_genes` -#' A tibble with columns: +#' ## `airr_stats_genes` A tibble with columns: #' * `repertoire_id` — repertoire identifier #' * *(optional)* `locus` — TRA, TRB, IGH … (present only when `by = "locus"` -#' and the locus column exists) +#' and the locus column exists) #' * `` — the gene segment value (e.g., V gene) #' * `n` — the measure: #' - if `level = "receptor"`: number of receptors carrying the gene segment diff --git a/R/v1_migration_updates.R b/R/v1_migration_updates.R new file mode 100644 index 00000000..8d36616f --- /dev/null +++ b/R/v1_migration_updates.R @@ -0,0 +1,53 @@ +#' @keywords internal +immunarch_v1_update_sep_2025 <- function() { + cli::cli_h1("{cli::col_green('immunarch')} {cli::col_yellow('0.9.x')} -- Critical Pre-release Notice") + + cli::cli_alert_warning("Update #1 [Sep 2025] -- Major changes are coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}!") + cli::cli_text(cli::col_yellow(cli::spark_line(runif(110, 0, 1)))) + + cli::cli_par() + cli::cli_text() + cli::cli_text( + "Hi, this is Vadim Nazarov speaking -- author of {cli::col_green('immunarch')}. ", + "{cli::col_green('immunarch')} is finally graduating from out of the {cli::col_yellow('0.x.y')} development cycle. ", + "I'm preparing our {cli::col_yellow('1.0.0')} release, which will remain stable and free of sudden changes until we approach {cli::col_yellow('2.0.0')}, along with ", + "a scientific publication for proper citations. ", + "Significant changes are coming, and I want to ensure you have everything you need to migrate to the new version." + ) + + cli::cli_par() + cli::cli_text() + cli::cli_text("Here's a preview of what's coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}:") + cli::cli_bullets(c( + "i" = "Some computationally intensive or advanced features (e.g., distance computations, graph-based analyses, dimensionality reduction techniques) will move to separate packages, making {cli::col_green('immunarch')} much more lightweight to install and manage;", + "i" = "New functions will be introduced instead of the left old ones to make code more readable and maintainable. Legacy functions will remain temporarily, but they won't be updated and will be removed by {cli::col_yellow('~2027')};", + "i" = "We will discontinue support for most custom file formats because the AIRR ecosystem is now mature enough that the majority of tools adhere to the AIRR standard;", + "i" = "The package will transition from data frames to the new {cli::col_blue('ImmunData')} structure -- better suited for handling modern larger, more complex, and multi-modal datasets (e.g., single-cell, spatial);", + "i" = "{cli::col_blue('ImmunData')} is available in the separate {cli::col_blue('immundata')} package, which you can already install via {cli::col_cyan('pak::pkg_install(\"immundata\")')};", + "i" = "The {cli::col_blue('ImmunData')}-based computations will be significantly faster, support datasets larger than RAM, and fully adhere to AIRR Community standards.", + "i" = "There currently only a handful functions which implement {cli::col_blue('ImmunData')}-based computations. However, if you want to start learning it, or you have a large-scale data, now it is the best time: the tutorials are available on {cli::col_cyan('https://github.com/immunomind/immundata') and {cli::col_cyan('https://immunomind.github.io/docs/')}" + )) + + cli::cli_par() + cli::cli_text() + cli::cli_text( + "See the dedicated migration guide for migration on what you can do now and how to prepare for the future:" + ) + cli::cli_text(">> visit {cli::col_cyan('https://immunomind.github.io/docs/tutorials/migration')}") + + cli::cli_par() + cli::cli_text() + cli::cli_alert_success("Thank you for supporting {cli::col_green('immunarch')} from its early days. Your feedback, contributions, and trust have driven its evolution, and I deeply appreciate it.") + + cli::cli_par() + cli::cli_text() + cli::cli_alert_info("Questions, comments, ideas? I'm available via:") + cli::cli_text(">> Support email: {cli::col_cyan('support@immunomind.com')}") + cli::cli_text(">> GitHub tickets: {cli::col_cyan('https://github.com/immunomind/immunarch')}") + cli::cli_text(">> LinkedIn: {cli::col_cyan('https://www.linkedin.com/in/vdnaz/')}") + + cli::cli_par() + cli::cli_text() + cli::cli_text("--") + cli::cli_text("Vadim I. Nazarov") +} diff --git a/R/v1_migration_utils.R b/R/v1_migration_utils.R new file mode 100644 index 00000000..bdb2e275 --- /dev/null +++ b/R/v1_migration_utils.R @@ -0,0 +1,42 @@ +#' Get the Latest immunarch Update +#' +#' Retrieves an update message for immunarch. +#' +#' If `datepoint` is set to `"latest"`, the function returns the most recent update. +#' Otherwise, specify the update date key (e.g., `"Apr 2025"`) to retrieve that particular update. +#' If no matching update is found, a warning is issued along with available update keys. +#' +#' @param datepoint A string specifying the update date. Use `"latest"` for the most recent update +#' or supply a valid date key (e.g., `"Apr 2025"`). +#' +#' @return A character string with the update details or a warning if the key is not found. +#' +#' @seealso [list_immunarch_news()] +#' +#' @concept migration_utility +#' +#' @export +get_immunarch_news <- function(datepoint = "latest") { + if (datepoint == "latest") { + immunarch_v1_updates[[length(immunarch_v1_updates)]]() + } else if (datepoint %in% names(immunarch_v1_updates)) { + immunarch_v1_updates[[datepoint]]() + } else { + cli::cli_alert_warning("No {datepoint} date in the list of {cli::col_green('immunarch')} updates. Available update names are: {immunarch:::list_immunarch_news()}") + } +} + +#' List Available immunarch Updates +#' +#' Returns the list of available update keys for immunarch v1. +#' +#' @return A character vector containing all the date keys for the available updates. +#' +#' @seealso [get_immunarch_news()] +#' +#' @concept migration_utility +#' +#' @export +list_immunarch_news <- function() { + names(immunarch_v1_updates) +} diff --git a/R/v1_package.R b/R/v1_package.R new file mode 100644 index 00000000..42322b89 --- /dev/null +++ b/R/v1_package.R @@ -0,0 +1,28 @@ +make_immunarch_features <- function(ires, method_name = NULL, feature_col = NULL, value_col = NULL) { + checkmate::check_data_frame(ires) + checkmate::check_character(method_name, null.ok = TRUE) + checkmate::check_character(feature_col, null.ok = TRUE) + checkmate::check_character(value_col, null.ok = TRUE) + + to_rename <- c("feature" = feature_col, "value" = value_col) + + if (is.null(method_name)) { + ires <- ires |> + mutate(method = method_name) + } + + ires |> + rename(to_rename) +} + +immunarch_methods <- function(family_name = NULL) { + checkmate::check_string(family_name) + + if (is.null(family_name)) { + ls(IMMUNARCH_METHOD_REGISTRY) + } else if (family_name %in% IMMUNARCH_METHOD_REGISTRY) { + ls(IMMUNARCH_METHOD_REGISTRY[[family_name]]) + } else { + cli::cli_abort("No such family name: {family_name}") + } +} diff --git a/R/zzz.R b/R/zzz.R index e256f86a..75ae6e1a 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,119 +1,35 @@ -#' @importFrom cli cli_h1 cli_alert_warning cli_par cli_text cli_end cli_alert_info cli_bullets spark_line cli_alert_success start_app cli_inform -#' @importFrom stats runif -immunarch_v1_update_apr_2025 <- function() { - cli::cli_h1("{cli::col_green('immunarch')} {cli::col_yellow('0.9.x')} – Critical Pre-release Notice") - - cli::cli_alert_warning("Update #1 [Apr 2025] -- Major changes are coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}!") - cli::cli_text(cli::col_yellow(cli::spark_line(runif(110, 0, 1)))) - - cli::cli_par() - cli::cli_text() - cli::cli_text( - "Hi, this is Vadim Nazarov speaking -- author of {cli::col_green('immunarch')}. ", - "{cli::col_green('immunarch')} is finally graduating from out of the {cli::col_yellow('0.x.y')} development cycle. ", - "I'm preparing our {cli::col_yellow('1.0.0')} release, which will remain stable and free of sudden changes until we approach {cli::col_yellow('2.0.0')}, along with ", - "a scientific publication for proper citations. ", - "Significant changes are coming, and I want to ensure you have everything you need to migrate to the new version." - ) - - cli::cli_par() - cli::cli_text() - cli::cli_text("Here’s a preview of what's coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}:") - cli::cli_bullets(c( - "i" = "Some computationally intensive or advanced features (e.g., distance computations, graph-based analyses, dimensionality reduction techniques) will move to separate packages, making {cli::col_green('immunarch')} much more lightweight to install and manage;", - "i" = "New functions will be introduced instead of the left old ones to make code more readable and maintainable. Legacy functions will remain temporarily, but they won't be updated and will be removed by {cli::col_yellow('~2027')};", - "i" = "We will discontinue support for most custom file formats because the AIRR ecosystem is now mature enough that the majority of tools adhere to the AIRR standard;", - "i" = "The package will transition from data frames to the new {cli::col_blue('ImmunData')} structure -- better suited for handling modern larger, more complex, and multi-modal datasets (e.g., single-cell, spatial);", - "i" = "{cli::col_blue('ImmunData')} is available in the separate {cli::col_blue('immundata')} package, which you can already install via {cli::col_cyan('install.packages(\"immundata\")')};", - "i" = "The {cli::col_blue('ImmunData')}-based computations will be significantly faster, support datasets larger than RAM, and fully adhere to AIRR Community standards." - )) - - cli::cli_par() - cli::cli_text() - cli::cli_text( - "See the dedicated migration guide for migration on what you can do now and how to prepare for the future:" - ) - cli::cli_text(">> run {cli::col_cyan('vignette(\"immunarch_v1_migration\")')}, or") - cli::cli_text(">> visit {cli::col_cyan('https://immunarch.com/articles/immunarch_v1_migration.html')}") - - cli::cli_par() - cli::cli_text() - cli::cli_alert_warning("Keep an eye on the update number and date at the beginning. I’ll share updates, tips, and important dates for our major transformation. If you happen to miss some update, call {cli::col_cyan('immunarch::immunarch_updates()')} to read previous updates.") - - cli::cli_par() - cli::cli_text() - cli::cli_alert_success("Thank you for supporting {cli::col_green('immunarch')} from its early days. Your feedback, contributions, and trust have driven its evolution, and I deeply appreciate it.") - - cli::cli_par() - cli::cli_text() - cli::cli_alert_info("Questions, comments, ideas? I'm available via:") - cli::cli_text(">> Support email: {cli::col_cyan('support@immunomind.com')}") - cli::cli_text(">> GitHub tickets: {cli::col_cyan('https://github.com/immunomind/immunarch')}") - cli::cli_text(">> LinkedIn: {cli::col_cyan('https://www.linkedin.com/in/vdnaz/')}") -} - -#' Some description +#' Get a list of package updates +#' @concept migration_utility immunarch_v1_updates <- c( - "Apr 2025" = immunarch_v1_update_apr_2025 + "Sep 2025" = immunarch_v1_update_sep_2025 ) -#' Get the Latest immunarch Update -#' -#' Retrieves an update message for immunarch. -#' -#' If `datepoint` is set to `"latest"`, the function returns the most recent update. -#' Otherwise, specify the update date key (e.g., `"Apr 2025"`) to retrieve that particular update. -#' If no matching update is found, a warning is issued along with available update keys. -#' -#' @param datepoint A string specifying the update date. Use `"latest"` for the most recent update -#' or supply a valid date key (e.g., `"Apr 2025"`). -#' -#' @return A character string with the update details or a warning if the key is not found. -#' -#' @seealso [list_immunarch_news()] -#' -#' @export -get_immunarch_news <- function(datepoint = "latest") { - if (datepoint == "latest") { - immunarch_v1_updates[[length(immunarch_v1_updates)]]() - } else if (datepoint %in% names(immunarch_v1_updates)) { - immunarch_v1_updates[[datepoint]]() - } else { - cli::cli_alert_warning("No {datepoint} date in the list of {cli::col_green('immunarch')} updates. Available update names are: {immunarch:::list_immunarch_news()}") - } -} - -#' List Available immunarch Updates -#' -#' Returns the list of available update keys for immunarch v1. -#' -#' @return A character vector containing all the date keys for the available updates. -#' -#' @seealso [get_immunarch_news()] -#' -#' @export -list_immunarch_news <- function() { - names(immunarch_v1_updates) -} - .onAttach <- function(libname, pkgname) { msg <- paste0( "Hi, this is Vadim Nazarov speaking -- author of ", cli::col_green("immunarch"), ".\n", cli::col_green("immunarch"), - " is evolving towards its 1.0.0 release. Soon it will be faster, more user-friendly, and ready for its long-awaited publication. Some functions will no longer be supported or will be replaced with new, more powerful methods.\n", - "\n -- Please run ", - cli::col_cyan("get_immunarch_news()"), - " in your R console to read the latest update and learn what has changed, what's new, how to migrate your code, and what changes are planned for the next update.\n", - "\n -- Run ", - cli::col_cyan("list_immunarch_news()"), - " to list all available updates and catch up on any you may have missed. Latest update: ", cli::col_yellow("#1, Apr 2025"), "\n", + " is evolving towards its 1.0 release. Soon it will be faster, more user-friendly, and ready for its long-awaited publication. Some functions will no longer be supported or will be replaced with new, more powerful methods.\n", + "\n -- Please click on ", + cli::col_cyan("{.run [get_immunarch_news()](immunarch::get_immunarch_news())}"), + " or run it in your R console to read the latest update and learn what has changed, what's new, how to migrate your code, and what changes are planned for the next update.\n", + "\n -- Click on ", + cli::col_cyan("{.run [list_immunarch_news()](immunarch::list_immunarch_news())}"), + " or run it to list all available updates and catch up on any you may have missed. Latest update: ", + cli::col_yellow("#1, Sep 2025"), + "\n", "\n -- To import the package without this message, run ", cli::col_cyan("suppressPackageStartupMessages(library(\"immunarch\"))"), "\n", - "Thank you." + "\nMigration guide is available online:\n\n-- in R: ", + "\n", + " {.url https://immunomind.github.io/docs/tutorials/migration}", + "\n\nThank you.\n", + "\n- Vadim I. Nazarov" ) cli::cli_inform(msg, class = "packageStartupMessage") + + # Show registered methods? } diff --git a/man/airr_clonality.Rd b/man/airr_clonality.Rd index b29e8929..17cd4c10 100644 --- a/man/airr_clonality.Rd +++ b/man/airr_clonality.Rd @@ -104,8 +104,10 @@ If \code{output = "annot"}: an \code{ImmunData} object where \code{annotations} \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} -A family of functions to quantify \strong{receptor overabundance} per repertoire. -\subsection{Available functions:}{ +A family of functions to quantify \strong{receptor overabundance} per repertoire. Helps in deciphering the structure and partition the repertoire. +\subsection{Available functions}{ + +Supported methods are the following. } \code{airr_clonality_line} — build ranked abundance lines: for each @@ -122,6 +124,9 @@ Each receptor is assigned to a named bin according to its \code{proportion} descending order; unmatched receptors fall into \code{"Ultra-rare"}. } \examples{ +# Load data +immdata <- get_test_idata() |> agg_repertoires("Therapy") + # # airr_clonality_line # diff --git a/man/airr_diversity.Rd b/man/airr_diversity.Rd index 84c7fa63..55b31bcc 100644 --- a/man/airr_diversity.Rd +++ b/man/airr_diversity.Rd @@ -124,8 +124,10 @@ A tibble with: \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} -A family of functions to quantify \strong{receptor diversity} per repertoire. -\subsection{Available functions:}{ +A family of functions to quantify \strong{receptor diversity} per repertoire. A characteristic of a whole repertoire. +\subsection{Available functions}{ + +Supported methods are the following. } \code{airr_diversity_dxx} — \strong{coverage diversity}: minimal number of @@ -151,6 +153,9 @@ emphasizes abundant receptors. Perfect when you want a \strong{diversity profile that tunes sensitivity to rare vs. abundant clonotypes. } \examples{ +# Load data +immdata <- get_test_idata() |> agg_repertoires("Therapy") + # # airr_diversity_dxx # diff --git a/man/airr_public.Rd b/man/airr_public.Rd index ad53eb8e..8ebf7da2 100644 --- a/man/airr_public.Rd +++ b/man/airr_public.Rd @@ -55,7 +55,9 @@ names are repertoire IDs. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} A family of functions to quantify \strong{public or shared receptors} between repertoire. -\subsection{Available functions:}{ +\subsection{Available functions}{ + +Supported methods are the following. } \code{airr_public_intersection} — number of \strong{shared receptors} between @@ -67,6 +69,9 @@ sets between repertoires (\verb{|A∩B| / |A∪B|}). Best when comparing cohorts different sizes to get a scale-invariant overlap score. } \examples{ +# Load data +immdata <- get_test_idata() |> agg_repertoires("Therapy") + # # airr_public_intersection # diff --git a/man/airr_stats.Rd b/man/airr_stats.Rd index fd3db029..f194caf6 100644 --- a/man/airr_stats.Rd +++ b/man/airr_stats.Rd @@ -36,7 +36,8 @@ airr_stats_genes( \arguments{ \item{idata}{An \code{ImmunData} object.} -\item{locus_col}{Column in \code{idata$annotations} that stores the locus (e.g. \code{"locus"}). If \code{NULL} or missing, the result is not split by locus.} +\item{locus_col}{Column in \code{idata$annotations} that stores the locus (e.g. +\code{"locus"}). If \code{NULL} or missing, the result is not split by locus.} \item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. For \code{format="analysis"}, metadata is joined to the long table; for @@ -51,15 +52,16 @@ columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} looks like \verb{family.method|facet1=...;facet2=...} (e.g., \code{airr_stats.genes|v_call=TRBV7-2}).} -\item{seq_col}{Character vector with names of the columns containing sequences.} +\item{seq_col}{Character vector with names of the columns containing +sequences.} \item{gene_col}{A single column name in \code{idata$annotations} with gene segment calls (e.g., \code{"v_call"}, \code{"d_call"}, \code{"j_call"}, \code{"c_call"}). Default is \code{"v_call"}.} \item{level}{One of \code{"receptor"} or \code{"barcode"}. If \code{"receptor"} (default), -the function counts \strong{unique receptors} (one per receptor ID) that carry -a given gene segment. If \code{"barcode"}, the function \strong{sums counts} (e.g., +the function counts \strong{unique receptors} (one per receptor ID) that carry a +given gene segment. If \code{"barcode"}, the function \strong{sums counts} (e.g., cells/UMIs) per gene segment using the column defined by \code{immundata::imd_schema("count")}.} @@ -69,9 +71,7 @@ is further split by the locus column if present (as given by split is ignored.} } \value{ -\subsection{\code{airr_stats_chains}}{ - -Returns a tibble with columns: +\subsection{\code{airr_stats_chains} Returns a tibble with columns:}{ \itemize{ \item \code{repertoire_id} -- repertoire identifier \item \code{locus} -- TRA, TRB, IGH … (present only if \code{locus_col} is supplied) @@ -79,9 +79,7 @@ Returns a tibble with columns: } } -\subsection{\code{airr_stats_lengths}}{ - -Returns a tibble with columns: +\subsection{\code{airr_stats_lengths} Returns a tibble with columns:}{ \itemize{ \item \code{repertoire_id} -- repertoire identifier \item \code{seq_len} -- lengths of sequences @@ -89,9 +87,7 @@ Returns a tibble with columns: } } -\subsection{\code{airr_stats_genes}}{ - -A tibble with columns: +\subsection{\code{airr_stats_genes} A tibble with columns:}{ \itemize{ \item \code{repertoire_id} — repertoire identifier \item \emph{(optional)} \code{locus} — TRA, TRB, IGH … (present only when \code{by = "locus"} @@ -109,18 +105,34 @@ and the locus column exists) \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} A family of functions that extract \strong{core descriptive statistics} from an \code{ImmunData} object. -\subsection{Available functions:}{ +\subsection{Available functions}{ + +Supported methods are the following. } -\code{airr_stats_chains} --- count V(D)J \emph{chains} per repertoire (optionally split by locus). WHY USEFUL / APPLICATION? +\code{airr_stats_chains} --- count V(D)J \emph{chains} per repertoire +(optionally split by locus). Quickly gauges capture depth per repertoire +and, when split by locus, reveals TRA/TRB/IGH balance. Use it for QC, +library-size checks, and to spot locus-specific dropouts or +over-representation. -\code{airr_stats_lengths} --- count the number of sequence lengths per repertoire. WHY USEFUL / APPLICATION? +\code{airr_stats_lengths} --- count the number of sequence lengths +per repertoire. Summarizes the CDR3 length distribution, a sensitive QC +fingerprint of repertoire prep and selection. Helpful for detecting +primer/UMI biases, comparing cohorts, and deriving length-based features for +models. \code{airr_stats_genes} — count V(D)J gene segments per repertoire, optionally split by locus and using either receptor counts or barcode/UMI -counts as the measure. WHY USEFUL / APPLICATION? +counts as the measure. Profiles V/D/J gene usage to characterize repertoire +composition and germline biases, with optional locus split. Useful for +cohort comparisons, flagging clonal expansions, and producing ML-ready +features for repertoire-level ML tasks. } \examples{ +# Load data +immdata <- get_test_idata() |> agg_repertoires("Therapy") + # # airr_stats_chains # diff --git a/man/repSave.Rd b/man/repSave.Rd index 3ac73066..d2e79a25 100644 --- a/man/repSave.Rd +++ b/man/repSave.Rd @@ -33,6 +33,7 @@ It is not necessary to create directories beforehand. If the provided directory does not exist it will be created automatically. } \examples{ +\dontrun{ data(immdata) # Reduce data to save time on examples immdata$data <- map(immdata$data, ~ .x \%>\% head(10)) @@ -45,4 +46,5 @@ new_immdata <- repLoad(dirpath) # sum(immdata$data[[2]] != new_immdata$data[[2]], na.rm = TRUE) # sum(immdata$meta != new_immdata$meta, na.rm = TRUE) } +} \concept{io} diff --git a/man/seqDist.Rd b/man/seqDist.Rd index a521cb62..ac5172d3 100644 --- a/man/seqDist.Rd +++ b/man/seqDist.Rd @@ -45,7 +45,7 @@ Named list of list with \link{dist} objects for given repertoires for each combi Computing sequential distances between clonotypes from two repertoires: } \examples{ - +\dontrun{ data(immdata) # Reducing data to save time on examples immdata$data <- map(immdata$data, ~ .x \%>\% head(10)) @@ -65,5 +65,7 @@ f <- function(x, y) { } seqDist(immdata$data[1:2], .method = f, .group_by_seqLength = FALSE) +} + } \concept{distance} diff --git a/vignettes/articles/.gitignore b/vignettes/articles/.gitignore deleted file mode 100644 index 097b2416..00000000 --- a/vignettes/articles/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.html -*.R diff --git a/vignettes/articles/singlecell.qmd b/vignettes/articles/singlecell.qmd deleted file mode 100644 index 3d01d640..00000000 --- a/vignettes/articles/singlecell.qmd +++ /dev/null @@ -1,483 +0,0 @@ ---- -title: "Comprehensive analysis of single-cell immune repertoire data using `immunarch` and `immundata`" -author: "Vadim I. Nazarov" -date: "`r Sys.Date()`" -format: - html: - code-overflow: wrap - code-block-bg: true - code-block-border-left: "#31BAE9" - highlight-style: github - code-line-numbers: false - code-copy: true - toc: true - number-sections: true - # theme: none - # minimal: true -vignette: > - %\VignetteIndexEntry{Comprehensive analysis of single-cell immune repertoire data} - %\VignetteEngine{quarto::html} - %\VignetteEncoding{UTF-8} ---- - -## Introduction - -This vignette provides a comprehensive guide on how to analyse single-chain and paired-chain Adaptive Immune Receptor Repertoire (AIRR) data coming from scRNAseq (scVDJseq / scTCRseq / scBCRseq). This tutorils guides you from the very basics to the more advanced steps. The aim is to have a great starting point for both beginners in AIRR data analysis and experts who want specificaly learn `immunarch` and `immundata`. - -We will use data from the study for patient no. 6. The data will have three samples - tumor, blood, and healthy tissue surrounding the tumor. The core idea of the study is to ... - -To ask a question, report a bug, or take a look at the source code, following the GitHub links for [immunarch](https://github.com/immunomind/immunarch) and [immundata](https://github.com/immunomind/immundata). - -To use ChatGPT for interactive helper, use [AIRR-GPT](https://chatgpt.com/g/g-67fe54e302348191814e4ef2efb3bad5-airr-gpt) - a GPT Store model with uploaded documentation for both `immunarch` and `immundata`. - -### Migration from v0.9 to v1.0 - -This is a section for user who already use immunarch. If you are a new user, you can safely skip it and move directly to the **Setup** section, where we will install `immunarch` (together!) and start analysing *your* immune repertoire data. - -#### High-level overview of v1.0 changes - -There are several important changes in the v1.0 version in comparison to v0.9.x versions. - -1) working with data - -2) API changes - backwards compatability - -**Watch for Deprecation Warnings** - - If you see console messages about “deprecated” or “will be removed in v1.1.0,” update your code ASAP.\ - -3) moving packages from Depends to Suggests - -3) working with visualisatiobns - hard to make publication ready - https://github.com/CerrenRichards/ggplot2-for-publications - -Take a look at themes here: https://cran.r-project.org/web/packages/ggsci/vignettes/ggsci.html and https://emilhvitfeldt.github.io/r-color-palettes/ - -For more information and updates, please see the guide here: ... - -To list updates, run the function in console - -#### If you want to work with `immunarch` v0.9 **only** - -To freeze the latest stable version of `immunarch` before `1.0`, you could provide the exact version: - - - **pak** --- `pak::pkg_install("immunarch@=0.9.1")` - - - **install.packages** --- `install.packages("https://cran.r-project.org/src/contrib/Archive/immunarch/immunarch_0.9.1.tar.gz", repos = NULL, type = "source")` - - - **conda** --- `mamba install -c conda-forge r-immunarch=0.9.1` - -#### New data processing backend --- `immundata` - -... - -#### Motivation behind the changes - -... - - -#### Concluding thoughts on migration - -... - ---- - -## Setup - -### Pre-requisites - -... - -```{r} -#| eval: false -install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/stable/%s/%s/%s", .Platform$pkgType, R.Version()$os, R.Version()$arch)) - -pak::pkg_install("immunomind/immunarch") -pak::pkg_install("Seurat") -pak::pkg_install("BiocFileCache") -pak::pkg_install("ggthemes") -pak::pkg_install("ggsci") -``` - -### Load necessary packages and setup - -... - -```{r} -#| label: load-immunarch -#| eval: !expr requireNamespace("Seurat", quietly = TRUE) && requireNamespace("ggthemes", quietly = TRUE) -#| echo: true -#| message: false -#| warning: false - -library("immunarch") -library("Seurat") - -theme_set(ggthemes::theme_few()) -``` - ---- - -## Quick overview - -### Typical workflow - -analyse -> visualise -> write back to Seurat -> visualise Seurat - ---- - -## Working with data - -### Load the prepackaged dataset - -First, we get paths to the metadata table and load it. Metadata is a tab-separate table with rows per sample or file, and columns for different per-sample feature such as "Tissue" or "Donor" or "Immunotherapy response". - -```{r} -#| label: load-dataset-metadata - -md_file <- system.file("extdata/single_cell", "metadata.tsv", package = "immundata") -md_file - -md_table <- immundata::read_metadata(md_file) -md_table -``` - -The metadata table contains the column "Tissue" and we will use it to split data into repertoires. But this is only the beginning - read more to learn how to split data by annotated cell clusters from scRNAseq data and computate statistics on those newly defined repertoires - on-the-fly and without reloading the whole dataset into the environment again. - -Next, we get the file paths to the data packaged with `immundata`. - -```{r} -#| label: load-dataset-files -#| -inp_files <- paste0(system.file("extdata/single_cell", "", package = "immundata"), "/*.csv.gz") -inp_files -``` - -TODO: EXPLAIN MORE WHAT THE RECEPTOR IS IN IMMUNDATA MODEL - -Then, we are ready to load AIRR data. We define a logical unit of analysis - a receptor - as a `"cdr3+v_call"` and will use only the `"TRB"` chain: - -```{r} -#| label: load-dataset-schema -#| eval: true - -schema <- make_receptor_schema(features = c("cdr3", "v_call"), chains = c("TRB")) -schema -``` - -If you want to use other receptor schemas, you can use the `make_receptor_schema()` function to create schemas and pass them to `read_repertoires()`. The dataset we use for this tutorial can support other schemas as well, including the paired-chain data: - -```{r} -#| label: load-dataset-schema-examples -#| eval: true - -# Paired-chain -schema <- make_receptor_schema(features = c("cdr3", "v_call"), chains = c("TRA", "TRB")) -schema - -# Single-chain with "cdr3" only -schema <- make_receptor_schema(features = c("cdr3"), chains = c("TRA")) -schema - -# The most strict receptor definition -schema <- make_receptor_schema(features = c("cdr3", "v_call", "j_call"), chains = c("TRA", "TRB")) -schema -``` - -Use the `read_repertoires()` function to load the data. There are quite many parameters, so let's briefly describe them: - -- `path` - ... - -- `schema` - ... - -- `metadata` - ... - -```{r} -#| label: load-dataset-airr -#| eval: true - -schema <- make_receptor_schema(features = c("cdr3", "v_call"), chains = c("TRB")) - -idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "locus", umi_col = "umis", preprocess = make_default_preprocessing("10x"), repertoire_schema = "Tissue") - -# idata -``` - -The output `idata` is `ImmunData` - a data structure from `immundata` package that holds the AIRR dataset. Think `AnnData` or `SeuratObject`, but for AIRR data. It is not a simple data frame or a list of data frames, and in the next subsection we will talk about how to operate on it. - -We have two optional steps left, and those are needed to load single-cell transcriptomics data. If you analyse bulk data, you obviously don't need to do this. - -We start with reading a cell metadata - a convenient human-readable table with T cell cluster annotations. Please note that in most cases, you will use `SeuratObject` or `AnnData` directly to exctact cluter labels from the object to annotate `ImmunData`. Read the corresponding documentation on how to extract cluster labels from single-cell transcriptomic and other tools. - -```{r} -#| label: load-dataset-cells -#| eval: true - -cells_file <- system.file("extdata/single_cell", "cells.tsv.gz", package = "immundata") -cells_file - -cells <- readr::read_tsv(cells_file) -cells -``` - -And finally, we load the gene expression data to Seurat. The matrix object takes several hundreds of megabytes, so we use cached file to avoid re-downloading the file next time we run the tutorial. Obviously, this wouldn't work without the web connection. - -The `cells` object contains also precomputed coordinates for UMAP to reduce the computations time for this tutorial. In real world, you would run the typical processing pipeline for scRNAseq data and get UMAP coordinates on the `SeuratObject`. To simulate this, we will add the UMAP coordinates to the created object in the code block below. - -```{r} -#| label: load-dataset-seurat -#| eval: true - -url <- "https://zenodo.org/records/15604205/files/l6data.rds?download=1" -dest <- BiocFileCache::bfcrpath(BiocFileCache::BiocFileCache(ask = FALSE), url) - -mat <- readr::read_rds(dest) - -sdata <- CreateSeuratObject(counts = mat) - -embeddings <- as.matrix(cells[c("UMAP_1", "UMAP_2")]) -rownames(embeddings) <- cells$barcode - -umap_dr <- CreateDimReducObject(embeddings = embeddings, key = "UMAP_", assay = DefaultAssay(sdata)) - -sdata[["umap"]] <- umap_dr - -Idents(sdata) <- setNames(cells$ident, cells$barcode) - -DimPlot(sdata, reduction = "umap", order = sort(unique(cells$ident), decreasing = TRUE), label = TRUE, alpha = .5) -``` - - -#### How to read other types of data - bulk, single-chain, etc. - -Note that the code below is for demonstration purposes only. It is not meant to run as a part of this tutorial. - -1. Bulk - -You won't need `barcode_col`, `locus_col`, `umi_col`. You can optionally pass `count_col` to have receptors counts. - -```{r} -#| label: load-dataset-types-bulk -#| eval: false - -idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, count_col = "counts", preprocess = make_default_preprocessing("airr"), repertoire_schema = "Tissue") -``` - -2. Single-cell - -All columns are needed. - -```{r} -#| label: load-dataset-types-singlecell -#| eval: false - -idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "locus", umi_col = "umis", preprocess = make_default_preprocessing("10x"), repertoire_schema = "Tissue") -``` - -3. AIRR or 10XGenomics - -`immunarch` aims to support the AIRR-C standard only. However, there are a couple of format-specific processing utilities. Mind the locus column name and the identifier we pass the to `make_default_preprocessing` function. - -```{r} -#| label: load-dataset-types-10x -#| eval: false - -idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "locus", umi_col = "umis", preprocess = make_default_preprocessing("airr"), repertoire_schema = "Tissue") - -idata <- read_repertoires(path = inp_files, schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "chain", umi_col = "umis", preprocess = make_default_preprocessing("10x"), repertoire_schema = "Tissue") -``` - -4. Pass file paths via metadata table - metadata_file_col - -Pass `""` - -```{r} -#| label: load-dataset-types-meta -#| eval: false - -idata <- read_repertoires(path = "", schema = schema, metadata = md_table, barcode_col = "barcode", locus_col = "locus", umi_col = "umis", preprocess = make_default_preprocessing("10x"), repertoire_schema = "Tissue") -``` - ---- - -## Note on materialization - -`ImmunData` object works on out-of-memory datasets the same way it works on in-memory datasets. It saves necessary computations and runs them only when the data is needed, e.g., for visualization. "Materialization" refers to running all the computations and getting this "real" dataset. This behaviour is not very familiar to people. Therefore, if you encounter this error: - -``` -Error: Materialization is disabled, use collect() or as_tibble() to materialize. -``` - -it means that the data is not materialized yet. If the data is not huge, e.g., it is some statistics from `immunarch` functions, you can safely run `immunarch_function() |> collect()` to immediately collect this data. If the dataset is huge, e.g., filtered `ImmunData` object, you usually don't need to materialize it so please think twice before doing this. - ---- - -## Analyse immune repertoires - individually and in groups - - -### Explore key statistics of immune repertoires - - -#### Number of receptors and barcodes for samples - -```{r} -#| label: repertoire-stats-sample-plot -#| eval: true -#| fig-width: 11 -idata_stats <- airr_stats_chains(idata) - -idata_stats - -p1 <- ggplot(idata_stats, aes(x = Tissue, y = n_barcodes, fill = Tissue)) + geom_col() + ggtitle("No. barcodes per sample") + ggsci::scale_fill_locuszoom() -p2 <- ggplot(idata_stats, aes(x = Tissue, y = n_receptors, fill = Tissue)) + geom_col() + ggtitle("No. receptors per sample") + ggsci::scale_fill_locuszoom() - -p1 + p2 -``` - - -#### Number of receptors and barcodes for cell clusters - -Okay, that's great, but what if we want to have a detailed view on how clusters are represented? Currently, we have three repertoires in the `idata` coming from the different tissues: - -```{r} -#| label: repertoire-stats-show-repertoires -#| eval: true - -idata$repertoires -``` - -Ideally, we want to explore each cell subpopulation in each tissue. For this, we will use powerful annotation mechanism from `immundata`. `idata` and `cells` have the same cell barcodes, so we can use them to annotate immune receptors with cluster label information, and then compute the same statistics on cluster level. - -```{r} -#| label: repertoire-stats-cluster -#| eval: true - -annot <- tibble(Cluster = as.character(Idents(sdata)), barcode = names(Idents(sdata))) - -annot - -idata <- annotate_barcodes(idata, annot, "barcode") -idata <- agg_repertoires(idata, c("Tissue", "Cluster")) - -idata$repertoires -``` - -And now, let's plot recompute statistics and plot them, but applied to "new" repertoires, which are now defined by a pair of columns - a tissue name "Tissue" and a cluster label "Cluster". - -```{r} -#| label: repertoire-stats-cluster-plot -#| eval: true -#| fig-width: 11 -idata_stats <- airr_stats_chains(idata) - -idata_stats - -p1 <- ggplot(idata_stats, aes(x = Tissue, y = n_barcodes, fill = Cluster)) + geom_col() + ggtitle("No. barcodes per sample") -p2 <- ggplot(idata_stats, aes(x = Tissue, y = n_receptors, fill = Cluster)) + geom_col() + ggtitle("No. receptors per sample") - -p1 + p2 -``` - -That's a lot of information! Let's group by cluster to understand the differences between tissues. - -```{r} -#| label: repertoire-stats-cluster-plot-patients -#| eval: true -#| fig-width: 11 - -ggplot(idata_stats, aes(x = Cluster, y = n_receptors, fill = Tissue)) + geom_col(position = "dodge") + ggtitle("No. receptors per sample") + ggsci::scale_fill_locuszoom() + theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) -``` - -Lots of NAs. This is because we took only "TRB" chain, and the tumor receptors are going crazy, they have lots of receptors per one barcode. - -If we reload the data with paired chain data, we will see another picture, as `immunarch` will filter out receptors additional receptors per barcode and leave only one pair per barcode. Do you want to do it? Consider this your homework! You just need to define a paired-chain schema for receptors (see one of the previous sections) and run pretty much the same code without any changes - that's the power of decoupling data processing to `immundata` and data analysis to `immunarch`. The latter pretty much doesn't care about the former, it just "asks" for receptors to exists - in any shape or form. - -We see some expected yet interesting patterns like more Tregs in the tumor site or more Trm in the surrounding normal tissue. Our data is not normalized so we can't really compare how big is the difference. We will normalize the data by the overall number of receptors per sample, and then plot the same visualization. - -```{r} -#| label: repertoire-stats-cluster-plot-norm -#| eval: true -#| fig-width: 11 - -idata_stats2 <- idata_stats |> mutate(.by = Tissue, TissueSize = sum(n_barcodes)) |> mutate(n_barcodes_div = n_barcodes / TissueSize) -idata_stats2 - -ggplot(idata_stats2, aes(x = Cluster, y = n_barcodes_div, fill = Tissue)) + geom_col(position = "dodge") + ggtitle("No. barcodes per sample") + ggsci::scale_fill_locuszoom() + theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1)) -``` - -#### Gene usage - -```{r} -#| label: repertoire-gene-usage-plot -#| eval: true -#| fig-width: 11 - -# filter Trm and Treg -# compute stats -# join them -# visualise -airr_stats_genes(idata) -``` - - -#### Length distribution - - -### Clonality - -... - - -### Diversity - -... - - -### Compute public receptor indices - -... - - -#### Number of public receptors - -... - - -#### Jaccard index - -... - - -But what are those public receptors? The next section will help us extract them from the data. - ---- - -## Discover and annotate immune receptors - -This section is under construction as I currently develop the receptor-level analysis functionality. I plan to release the most commonly used functions in October-November 2025. Monitor my [LinkedIn](https://www.linkedin.com/in/vdnaz) and [GitHub](https://github.com/immunomind/immunarch/issues/432) for news and updates. - -The planned topics are: - -- use external databases to find CMV-specific receptors in the input repertoires - -- track specific CMV-related receptors through different tissues and highlight them on single-cell UMAP - -- analyse and plot counts of specific receptors vs. expression of genes of interest - -- public repertoire analysis - discover receptors which are suspiciously overabundant in one groups of repertoires in contrast to another groups of repertoires (e.g., control vs condition to search for TIL or antigen-specific receptors) - -- all of above but using levenshtein-based similarity instead of exact matches - ---- - -## Analyse subgroups of receptors of interest - -This is section is too under constructions. Planned content: - -- discover receptors of interest, e.g., CMV-specific - -- run analysis to compare sum/avg abundance of such receptors between groups to measure the level of signal - ---- - -## Conclusion - -No spoilers. :-) From 105fe0569c2b2d02587d326091afb60b5c5cba4d Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 9 Sep 2025 18:03:54 +0200 Subject: [PATCH 27/36] ci: pkgdown website building --- .github/workflows/pkgdown.yaml | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/workflows/pkgdown.yaml diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml new file mode 100644 index 00000000..bfc9f4db --- /dev/null +++ b/.github/workflows/pkgdown.yaml @@ -0,0 +1,49 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + release: + types: [published] + workflow_dispatch: + +name: pkgdown.yaml + +permissions: read-all + +jobs: + pkgdown: + runs-on: ubuntu-latest + # Only restrict concurrency for non-PR jobs + concurrency: + group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages 🚀 + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.5.0 + with: + clean: false + branch: gh-pages + folder: docs From 02b06f8bff21eb601b4d4cd183e2fb05e908d73d Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:58:13 +0200 Subject: [PATCH 28/36] feat: clonality --- R/v1_airr_clonality.R | 157 ++++++++++---------------------------- R/v1_annotate_clonality.R | 124 ++++++++++++++++++++++++++++++ R/v1_core_clonality.R | 61 +++++++++++++++ man/airr_clonality.Rd | 58 +++++--------- man/annotate_clonality.Rd | 82 ++++++++++++++++++++ 5 files changed, 326 insertions(+), 156 deletions(-) create mode 100644 R/v1_annotate_clonality.R create mode 100644 R/v1_core_clonality.R create mode 100644 man/annotate_clonality.Rd diff --git a/R/v1_airr_clonality.R b/R/v1_airr_clonality.R index a5099cc7..2f47b578 100644 --- a/R/v1_airr_clonality.R +++ b/R/v1_airr_clonality.R @@ -15,7 +15,9 @@ #' @inheritParams airr_clonality_prop #' @inheritParams im_common_args #' -#' @seealso [immundata::ImmunData] +#' @seealso +#' * Per-repertoire summaries: [annotate_clonality] +#' * Data container: [immundata::ImmunData] #' #' @examples #' # Load data @@ -46,23 +48,14 @@ airr_clonality_line_impl <- function(idata, limit = 100000) { .keep_all = TRUE ) |> arrange(desc(!!immundata::imd_schema_sym("count"))) |> - slice_head(n = limit * n_repertoires) |> # Optimization before compute - does it make sense, though? - compute() |> # TODO: If we remove compute, the output breaks. Open an issue in duckplr - something wrong with row_number + mutate-by + collect() |> # TODO: .by doesn't work in slice_head in duckplyr. What to do instead then? + slice_head(n = limit * n_repertoires, by = !!immundata::imd_schema_sym("repertoire")) |> mutate( index = row_number(), .by = immundata::imd_schema("repertoire") ) |> - filter(index <= limit) |> select(-!!immundata::imd_schema_sym("receptor")) |> - left_join( - idata$repertoires |> select(-any_of(c( - immundata::imd_schema("n_barcodes"), - immundata::imd_schema("n_receptors") - ))), - by = immundata::imd_schema("repertoire") - ) |> - arrange(index) |> - collect() + arrange(index) } @@ -91,59 +84,28 @@ airr_clonality_line_impl <- function(idata, limit = 100000) { #' @rdname airr_clonality #' @concept Clonality #' @export -airr_clonality_line <- register_immunarch_method(airr_clonality_line_impl, "airr_clonality", "line") +airr_clonality_line <- register_immunarch_method( + core = airr_clonality_line_impl, + family = "airr_clonality", + name = "line", + need_repertoires = TRUE +) #' @keywords internal airr_clonality_rank_impl <- function(idata, - bins = c(10, 30, 100, 300, 1000, 10000, 100000), - output = c("stat", "annot")) { + bins = c(10, 30, 100, 300, 1000, 10000, 100000)) { checkmate::check_numeric(bins, lower = 1) - output <- match.arg(output) - bins <- sort(bins, decreasing = FALSE) - sql_expr <- paste0( - "CASE ", - paste0(map_chr( - bins, - ~ cli::format_inline("WHEN ROW_NUMBER() OVER (PARTITION BY {immundata::imd_schema('repertoire')} ORDER BY {immundata::imd_schema('proportion')} DESC) <= {.x} THEN {.x}") - ), collapse = " "), " ELSE NULL END" - ) - - clonality_df <- idata$annotations |> - select(all_of(c( - immundata::imd_schema("repertoire"), - immundata::imd_schema("receptor"), - immundata::imd_schema("proportion") - ))) |> - distinct(!!immundata::imd_schema_sym("repertoire"), - !!immundata::imd_schema_sym("receptor"), - .keep_all = TRUE - ) |> - arrange() |> - as_tbl() |> - mutate(clonal_rank_bin = dbplyr::sql(sql_expr)) |> - as_duckdb_tibble() |> - compute() + clonality_df <- core_clonality_rank(idata = idata, bins = bins) - if (output == "stat") { - clonality_df |> - summarise( - .by = c(immundata::imd_schema("repertoire"), "clonal_rank_bin"), - occupied_prop = sum(!!immundata::imd_schema_sym("proportion"), na.rm = TRUE) - ) |> - right_join(idata$repertoires, by = immundata::imd_schema("repertoire")) - } else { - ImmunData$new( - schema = idata$schema_receptor, - annotations = idata$annotations |> - left_join(clonality_df, - by = immundata::imd_schema("receptor") - ) + clonality_df |> + summarise( + .by = c(immundata::imd_schema("repertoire"), "clonal_rank_bin"), + occupied_prop = sum(!!immundata::imd_schema_sym("proportion"), na.rm = TRUE) ) - } } @@ -154,33 +116,31 @@ airr_clonality_rank_impl <- function(idata, #' @param bins Integer vector of rank thresholds (e.g., `c(10, 100, 1000)`). #' For each repertoire, receptors with ranks `<= bins[i]` contribute to bin #' `bins[i]`. Bins are sorted ascending internally. -#' @param output One of `"stat"` (default) to return per-repertoire bin -#' aggregates, or `"annot"` to return an `ImmunData` with an added -#' `clonal_rank_bin` column in `annotations`. #' #' @return #' #' ## `airr_clonality_rank` -#' If `output = "stat"`: a tibble with +#' A tibble with #' * `repertoire_id` #' * `clonal_rank_bin` — the rank threshold (e.g., `10`, `100`, …) #' * `occupied_prop` — sum of `proportion` within the bin #' * plus repertoire metadata columns from `idata$repertoires` #' -#' If `output = "annot"`: an `ImmunData` object where `annotations` includes -#' `clonal_rank_bin`. -#' #' @examples #' # #' # airr_clonality_rank #' # -#' rank_stat <- airr_clonality_rank(immdata, bins = c(10, 100), output = "stat") -#' rank_annot <- airr_clonality_rank(immdata, bins = c(10, 100), output = "annot") +#' rank_stat <- airr_clonality_rank(immdata, bins = c(10, 100)) #' #' @rdname airr_clonality #' @concept Clonality #' @export -airr_clonality_rank <- register_immunarch_method(airr_clonality_rank_impl, "airr_clonality", "rank") +airr_clonality_rank <- register_immunarch_method( + core = airr_clonality_rank_impl, + family = "airr_clonality", + name = "rank", + need_repertoires = TRUE +) #' @keywords internal @@ -191,53 +151,18 @@ airr_clonality_prop_impl <- function( Medium = 1e-4, Small = 1e-5, Rare = 1e-6 - ), - output = c("stat", "annot")) { + )) { checkmate::check_numeric(bins, lower = 0, min.len = 1) - output <- match.arg(output) - bins <- sort(bins, decreasing = TRUE) - sql_expr <- paste0( - "CASE ", - paste0(map2_chr( - bins, names(bins), - ~ sprintf("WHEN %s >= %s THEN '%s'", immundata::imd_schema("proportion"), .x, .y) - ), collapse = " "), " ELSE 'Ultra-rare' END" - ) + clonality_df <- core_clonality_prop(idata = idata, bins = bins) - clonality_df <- idata$annotations |> - select(all_of(c( - immundata::imd_schema("repertoire"), - immundata::imd_schema("receptor"), - immundata::imd_schema("proportion") - ))) |> - distinct(!!immundata::imd_schema_sym("repertoire"), - !!immundata::imd_schema_sym("receptor"), - .keep_all = TRUE - ) |> - duckplyr::as_tbl() |> - mutate(clonal_prop_bin = dbplyr::sql(sql_expr)) |> - duckplyr::as_duckdb_tibble() |> - compute() - - if (output == "stat") { - clonality_df |> - summarise( - .by = c(immundata::imd_schema("repertoire"), "clonal_prop_bin"), - occupied_prop = sum(!!immundata::imd_schema_sym("proportion"), na.rm = TRUE) - ) |> - right_join(idata$repertoires, by = immundata::imd_schema("repertoire")) - } else { - ImmunData$new( - schema = idata$schema_receptor, - annotations = idata$annotations |> - left_join(clonality_df, - by = immundata::imd_schema("receptor") - ) + clonality_df |> + summarise( + .by = c(immundata::imd_schema("repertoire"), "clonal_prop_bin"), + occupied_prop = sum(!!immundata::imd_schema_sym("proportion"), na.rm = TRUE) ) - } } @@ -249,30 +174,28 @@ airr_clonality_prop_impl <- function( #' @param bins A **named** numeric vector of thresholds (e.g., #' `c(Hyperexpanded = 1e-2, Large = 1e-3, ...)`). Names become bin labels and #' must be non-empty. Internally sorted in descending order. -#' @param output One of `"stat"` (default) to return per-repertoire bin -#' aggregates, or `"annot"` to return an `ImmunData` with an added -#' `clonal_prop_bin` column in `annotations`. #' #' @return #' #' ## `airr_clonality_prop` -#' If `output = "stat"`: a tibble with +#' A tibble with #' * `repertoire_id` #' * `clonal_prop_bin` — factor-like label from `names(bins)` or `"Ultra-rare"` #' * `occupied_prop` — sum of `proportion` within the bin #' * plus repertoire metadata columns from `idata$repertoires` #' -#' If `output = "annot"`: an `ImmunData` object where `annotations` includes -#' `clonal_prop_bin`. -#' #' @examples #' # #' # airr_clonality_prop #' # -#' prop_stat <- airr_clonality_prop(immdata, output = "stat") -#' prop_annot <- airr_clonality_prop(immdata, output = "annot") +#' prop_stat <- airr_clonality_prop(immdata) #' #' @rdname airr_clonality #' @concept Clonality #' @export -airr_clonality_prop <- register_immunarch_method(airr_clonality_prop_impl, "airr_clonality", "prop") +airr_clonality_prop <- register_immunarch_method( + core = airr_clonality_prop_impl, + family = "airr_clonality", + name = "prop", + need_repertoires = TRUE +) diff --git a/R/v1_annotate_clonality.R b/R/v1_annotate_clonality.R new file mode 100644 index 00000000..f7091fa5 --- /dev/null +++ b/R/v1_annotate_clonality.R @@ -0,0 +1,124 @@ +#' @title Annotate clonality — per-receptor labels for overabundance +#' +#' @description +#' `r lifecycle::badge("experimental")` +#' +#' A small family of helpers that **add clonality labels to each receptor** in +#' an [immundata::ImmunData] object. +#' +#' ## Available functions +#' * `annotate_clonality_rank()` — label by **rank bins** within each repertoire. +#' * `annotate_clonality_prop()` — label by **proportion bins** (named thresholds). +#' +#' @param idata An [immundata::ImmunData] object. +#' @inheritParams im_common_args +#' +#' @seealso +#' * Per-repertoire summaries: [airr_clonality] +#' * Data container: [immundata::ImmunData] +#' +#' @examples +#' \dontrun{ +#' idata <- get_test_idata() |> agg_repertoires("Therapy") +#' idata_rank <- annotate_clonality_rank(idata) +#' idata_prop <- annotate_clonality_prop(idata) +#' } +#' +#' @name annotate_clonality +#' @concept Clonality +NULL + + +#' @keywords internal +annotate_clonality_rank_impl <- function(idata, + bins = c(10, 30, 100, 300, 1000, 10000, 100000)) { + checkmate::check_numeric(bins, lower = 1) + + bins <- sort(bins, decreasing = FALSE) + + clonality_df <- core_clonality_rank(idata = idata, bins = bins) + + by_cols <- c(immundata::imd_schema("receptor"), immundata::imd_schema("repertoire")) + names(by_cols) <- c(immundata::imd_schema("receptor"), immundata::imd_schema("repertoire")) + annotate_immundata(idata, + clonality_df |> + select( + immundata::imd_schema("receptor"), + immundata::imd_schema("repertoire"), + clonal_rank_bin + ), + by = by_cols + ) +} + + +#' @description +#' `annotate_clonality_rank()` — for each repertoire, receptors are ordered by +#' within-repertoire abundance (proportion) and assigned a **rank bin** label. +#' +#' @inheritParams airr_clonality_rank +#' +#' @return +#' An [immundata::ImmunData] whose `$annotations` gains: +#' * `clonal_rank_bin` — integer-like label with the applied rank threshold +#' (outside all thresholds → `NA`). +#' +#' @rdname annotate_clonality +#' @concept Clonality +#' @export +annotate_clonality_rank <- register_immunarch_method( + core = annotate_clonality_rank_impl, + family = "annotate_clonality", + name = "rank", + need_repertoires = TRUE +) + + +#' @keywords internal +annotate_clonality_prop_impl <- function( + idata, bins = c( + Hyperexpanded = 1e-2, + Large = 1e-3, + Medium = 1e-4, + Small = 1e-5, + Rare = 1e-6 + )) { + checkmate::check_numeric(bins, lower = 0, min.len = 1) + + bins <- sort(bins, decreasing = TRUE) + + clonality_df <- core_clonality_prop(idata = idata, bins = bins) + + by_cols <- c(immundata::imd_schema("receptor"), immundata::imd_schema("repertoire")) + names(by_cols) <- c(immundata::imd_schema("receptor"), immundata::imd_schema("repertoire")) + annotate_immundata(idata, + clonality_df |> + select( + immundata::imd_schema("receptor"), + immundata::imd_schema("repertoire"), + clonal_prop_bin + ), + by = by_cols + ) +} + + +#' @description +#' `annotate_clonality_prop()` — label each receptor by **proportion bin** +#' using named thresholds (matched in descending order; else `"Ultra-rare"`). +#' +#' @inheritParams airr_clonality_prop +#' +#' @return +#' An [immundata::ImmunData] whose `$annotations` gains: +#' * `clonal_prop_bin` — label from `names(bins)` or `"Ultra-rare"`. +#' +#' @rdname annotate_clonality +#' @concept Clonality +#' @export +annotate_clonality_prop <- register_immunarch_method( + core = annotate_clonality_prop_impl, + family = "annotate_clonality", + name = "prop", + need_repertoires = TRUE +) diff --git a/R/v1_core_clonality.R b/R/v1_core_clonality.R new file mode 100644 index 00000000..fcb91328 --- /dev/null +++ b/R/v1_core_clonality.R @@ -0,0 +1,61 @@ +#' @keywords internal +core_clonality_rank <- function(idata, bins) { + checkmate::check_numeric(bins, lower = 1) + + bins <- sort(bins, decreasing = FALSE) + + sql_expr <- paste0( + "CASE ", + paste0(map_chr( + bins, + ~ cli::format_inline("WHEN ROW_NUMBER() OVER (PARTITION BY {immundata::imd_schema('repertoire')} ORDER BY {immundata::imd_schema('proportion')} DESC) <= {.x} THEN {.x}") + ), collapse = " "), " ELSE NULL END" + ) + + clonality_df <- idata$annotations |> + select(all_of(c( + immundata::imd_schema("repertoire"), + immundata::imd_schema("receptor"), + immundata::imd_schema("proportion") + ))) |> + distinct(!!immundata::imd_schema_sym("repertoire"), + !!immundata::imd_schema_sym("receptor"), + .keep_all = TRUE + ) |> + arrange() |> + as_tbl() |> + mutate(clonal_rank_bin = dbplyr::sql(sql_expr)) |> + as_duckdb_tibble() |> + compute() + + clonality_df +} + + +#' @keywords internal +core_clonality_prop <- function(idata, bins) { + sql_expr <- paste0( + "CASE ", + paste0(map2_chr( + bins, names(bins), + ~ sprintf("WHEN %s >= %s THEN '%s'", immundata::imd_schema("proportion"), .x, .y) + ), collapse = " "), " ELSE 'Ultra-rare' END" + ) + + clonality_df <- idata$annotations |> + select(all_of(c( + immundata::imd_schema("repertoire"), + immundata::imd_schema("receptor"), + immundata::imd_schema("proportion") + ))) |> + distinct(!!immundata::imd_schema_sym("repertoire"), + !!immundata::imd_schema_sym("receptor"), + .keep_all = TRUE + ) |> + duckplyr::as_tbl() |> + mutate(clonal_prop_bin = dbplyr::sql(sql_expr)) |> + duckplyr::as_duckdb_tibble() |> + compute() + + clonality_df +} diff --git a/man/airr_clonality.Rd b/man/airr_clonality.Rd index 17cd4c10..81174230 100644 --- a/man/airr_clonality.Rd +++ b/man/airr_clonality.Rd @@ -10,28 +10,23 @@ airr_clonality_line( idata, limit = 1e+05, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_clonality_rank( idata, bins = c(10, 30, 100, 300, 1000, 10000, 1e+05), - output = c("stat", "annot"), - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_clonality_prop( idata, bins = c(Hyperexpanded = 0.01, Large = 0.001, Medium = 1e-04, Small = 1e-05, Rare = 1e-06), - output = c("stat", "annot"), - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) } \arguments{ @@ -40,26 +35,16 @@ airr_clonality_prop( \item{limit}{Positive integer ≥ 10: maximum number of top receptors to keep \strong{per repertoire} (default \code{100000}).} -\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. -For \code{format="analysis"}, metadata is joined to the long table; for -\code{format="ml"}, it’s joined after pivoting to wide. Defaults to -\code{getOption("immundata.autojoin", FALSE)}.} +\item{autojoin}{Logical. If TRUE, join repertoire metadata by the schema repertoire id. +Change the default behaviour by calling \code{options(immunarch.autojoin = FALSE)}.} -\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet -columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} - -\item{features}{Character vector of \strong{feature keys} to keep when -\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key -looks like \verb{family.method|facet1=...;facet2=...} (e.g., -\code{airr_stats.genes|v_call=TRBV7-2}).} +\item{format}{String. One of \code{"long"} ("long" tibble with \code{imd_repertoire_id}, facet +columns, and \code{value}; useful for visualizations) or \code{"wide"} (wide/unmelted table of features, +with each row corresponding to a specific repertoire / pair of repertoires; useful for Machine Learning).} \item{bins}{A \strong{named} numeric vector of thresholds (e.g., \code{c(Hyperexpanded = 1e-2, Large = 1e-3, ...)}). Names become bin labels and must be non-empty. Internally sorted in descending order.} - -\item{output}{One of \code{"stat"} (default) to return per-repertoire bin -aggregates, or \code{"annot"} to return an \code{ImmunData} with an added -\code{clonal_prop_bin} column in \code{annotations}.} } \value{ \subsection{\code{airr_clonality_line}}{ @@ -75,30 +60,24 @@ A tibble with columns: \subsection{\code{airr_clonality_rank}}{ -If \code{output = "stat"}: a tibble with +A tibble with \itemize{ \item \code{repertoire_id} \item \code{clonal_rank_bin} — the rank threshold (e.g., \code{10}, \code{100}, …) \item \code{occupied_prop} — sum of \code{proportion} within the bin \item plus repertoire metadata columns from \code{idata$repertoires} } - -If \code{output = "annot"}: an \code{ImmunData} object where \code{annotations} includes -\code{clonal_rank_bin}. } \subsection{\code{airr_clonality_prop}}{ -If \code{output = "stat"}: a tibble with +A tibble with \itemize{ \item \code{repertoire_id} \item \code{clonal_prop_bin} — factor-like label from \code{names(bins)} or \code{"Ultra-rare"} \item \code{occupied_prop} — sum of \code{proportion} within the bin \item plus repertoire metadata columns from \code{idata$repertoires} } - -If \code{output = "annot"}: an \code{ImmunData} object where \code{annotations} includes -\code{clonal_prop_bin}. } } \description{ @@ -135,17 +114,18 @@ top_line <- airr_clonality_line(immdata, limit = 1000) # # airr_clonality_rank # -rank_stat <- airr_clonality_rank(immdata, bins = c(10, 100), output = "stat") -rank_annot <- airr_clonality_rank(immdata, bins = c(10, 100), output = "annot") +rank_stat <- airr_clonality_rank(immdata, bins = c(10, 100)) # # airr_clonality_prop # -prop_stat <- airr_clonality_prop(immdata, output = "stat") -prop_annot <- airr_clonality_prop(immdata, output = "annot") +prop_stat <- airr_clonality_prop(immdata) } \seealso{ -\link[immundata:ImmunData]{immundata::ImmunData} +\itemize{ +\item Per-repertoire summaries: \link{annotate_clonality} +\item Data container: \link[immundata:ImmunData]{immundata::ImmunData} +} } \concept{Clonality} diff --git a/man/annotate_clonality.Rd b/man/annotate_clonality.Rd new file mode 100644 index 00000000..1a39b0f0 --- /dev/null +++ b/man/annotate_clonality.Rd @@ -0,0 +1,82 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/v1_annotate_clonality.R +\name{annotate_clonality} +\alias{annotate_clonality} +\alias{annotate_clonality_rank} +\alias{annotate_clonality_prop} +\title{Annotate clonality — per-receptor labels for overabundance} +\usage{ +annotate_clonality_rank( + idata, + bins = c(10, 30, 100, 300, 1000, 10000, 1e+05), + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") +) + +annotate_clonality_prop( + idata, + bins = c(Hyperexpanded = 0.01, Large = 0.001, Medium = 1e-04, Small = 1e-05, Rare = + 1e-06), + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") +) +} +\arguments{ +\item{idata}{An \link[immundata:ImmunData]{immundata::ImmunData} object.} + +\item{bins}{A \strong{named} numeric vector of thresholds (e.g., +\code{c(Hyperexpanded = 1e-2, Large = 1e-3, ...)}). Names become bin labels and +must be non-empty. Internally sorted in descending order.} + +\item{autojoin}{Logical. If TRUE, join repertoire metadata by the schema repertoire id. +Change the default behaviour by calling \code{options(immunarch.autojoin = FALSE)}.} + +\item{format}{String. One of \code{"long"} ("long" tibble with \code{imd_repertoire_id}, facet +columns, and \code{value}; useful for visualizations) or \code{"wide"} (wide/unmelted table of features, +with each row corresponding to a specific repertoire / pair of repertoires; useful for Machine Learning).} +} +\value{ +An \link[immundata:ImmunData]{immundata::ImmunData} whose \verb{$annotations} gains: +\itemize{ +\item \code{clonal_rank_bin} — integer-like label with the applied rank threshold +(outside all thresholds → \code{NA}). +} + +An \link[immundata:ImmunData]{immundata::ImmunData} whose \verb{$annotations} gains: +\itemize{ +\item \code{clonal_prop_bin} — label from \code{names(bins)} or \code{"Ultra-rare"}. +} +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + +A small family of helpers that \strong{add clonality labels to each receptor} in +an \link[immundata:ImmunData]{immundata::ImmunData} object. +\subsection{Available functions}{ +\itemize{ +\item \code{annotate_clonality_rank()} — label by \strong{rank bins} within each repertoire. +\item \code{annotate_clonality_prop()} — label by \strong{proportion bins} (named thresholds). +} +} + +\code{annotate_clonality_rank()} — for each repertoire, receptors are ordered by +within-repertoire abundance (proportion) and assigned a \strong{rank bin} label. + +\code{annotate_clonality_prop()} — label each receptor by \strong{proportion bin} +using named thresholds (matched in descending order; else \code{"Ultra-rare"}). +} +\examples{ +\dontrun{ +idata <- get_test_idata() |> agg_repertoires("Therapy") +idata_rank <- annotate_clonality_rank(idata) +idata_prop <- annotate_clonality_prop(idata) +} + +} +\seealso{ +\itemize{ +\item Per-repertoire summaries: \link{airr_clonality} +\item Data container: \link[immundata:ImmunData]{immundata::ImmunData} +} +} +\concept{Clonality} From 94927f04d8b3e0d2ed596da6cd083c21b46e32d0 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:58:19 +0200 Subject: [PATCH 29/36] feat: stats --- R/v1_airr_stats.R | 50 +++++++++++++++++++++++++++++++++++------------ man/airr_stats.Rd | 31 +++++++++++------------------ 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/R/v1_airr_stats.R b/R/v1_airr_stats.R index e1bec2d0..ce4ffbcf 100644 --- a/R/v1_airr_stats.R +++ b/R/v1_airr_stats.R @@ -30,6 +30,10 @@ NULL airr_stats_chains_impl <- function(idata, locus_col = NA) { checkmate::assert_character(locus_col, null.ok = TRUE) + if (is.null(idata$repertoires)) { + cli::cli_abort("No repertoires in the input ImmunData. Run {.code agg_repertoires} first.") + } + if (is.na(locus_col)) { locus_col <- immundata::imd_schema("locus") @@ -50,13 +54,15 @@ airr_stats_chains_impl <- function(idata, locus_col = NA) { summarise( .by = all_of(by_cols), n_chains = n() - ) + ) |> + collect() chain_stats <- idata$repertoires |> + select(-idata$schema_repertoire) |> left_join(chain_stats, by = repertoire_id_col) |> collect() - if (!is.null(locus_col)) { + if (is.null(locus_col)) { chain_stats |> mutate(locus = NA) } else { chain_stats |> rename(locus = locus_col) @@ -89,20 +95,28 @@ airr_stats_chains_impl <- function(idata, locus_col = NA) { #' @rdname airr_stats #' @concept Key AIRR statistics #' @export -airr_stats_chains <- register_immunarch_method(airr_stats_chains_impl, "airr_stats", "chains") +airr_stats_chains <- register_immunarch_method( + core = airr_stats_chains_impl, + family = "airr_stats", + name = "chains" +) #' @keywords internal airr_stats_lengths_impl <- function(idata, seq_col = "cdr3_aa") { - length_tbl <- idata$annotations |> - distinct(!!rlang::sym(seq_col)) |> - mutate(seq_len = dd$length(!!rlang::sym(seq_col))) - idata$annotations |> - select(all_of(c(idata$schema_repertoire, seq_col))) |> - left_join(length_tbl, by = seq_col) |> - summarise(.by = all_of(c(idata$schema_repertoire, "seq_len")), n = n()) |> - collect() + dplyr::select(dplyr::all_of(c(immundata::imd_schema("repertoire"), seq_col))) |> + dplyr::mutate(seq_len = dd$length(!!rlang::sym(seq_col))) |> + dplyr::summarise( + n = dplyr::n(), + .by = dplyr::all_of(c(immundata::imd_schema("repertoire"), "seq_len")) + ) |> + collect() |> + dplyr::mutate( + prop = n / sum(n, na.rm = TRUE), # proportion within repertoire + pct = 100 * prop, + .by = immundata::imd_schema("repertoire") + ) } @@ -131,7 +145,12 @@ airr_stats_lengths_impl <- function(idata, seq_col = "cdr3_aa") { #' @rdname airr_stats #' @concept Key AIRR statistics #' @export -airr_stats_lengths <- register_immunarch_method(airr_stats_lengths_impl, "airr_stats", "lengths") +airr_stats_lengths <- register_immunarch_method( + core = airr_stats_lengths_impl, + family = "airr_stats", + name = "lengths", + required = "seq_col" +) #' @keywords internal @@ -206,4 +225,9 @@ airr_stats_genes_impl <- function(idata, gene_col = "v_call", level = c("recepto #' @rdname airr_stats #' @concept Key AIRR statistics #' @export -airr_stats_genes <- register_immunarch_method(airr_stats_genes_impl, "airr_stats", "genes") +airr_stats_genes <- register_immunarch_method( + core = airr_stats_genes_impl, + family = "airr_stats", + name = "genes", + required = "gene_col" +) diff --git a/man/airr_stats.Rd b/man/airr_stats.Rd index f194caf6..9ad793f6 100644 --- a/man/airr_stats.Rd +++ b/man/airr_stats.Rd @@ -10,17 +10,15 @@ airr_stats_chains( idata, locus_col = NA, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_stats_lengths( idata, seq_col = "cdr3_aa", - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_stats_genes( @@ -28,9 +26,8 @@ airr_stats_genes( gene_col = "v_call", level = c("receptor", "barcode"), by = c(NA, "locus"), - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) } \arguments{ @@ -39,18 +36,12 @@ airr_stats_genes( \item{locus_col}{Column in \code{idata$annotations} that stores the locus (e.g. \code{"locus"}). If \code{NULL} or missing, the result is not split by locus.} -\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. -For \code{format="analysis"}, metadata is joined to the long table; for -\code{format="ml"}, it’s joined after pivoting to wide. Defaults to -\code{getOption("immundata.autojoin", FALSE)}.} +\item{autojoin}{Logical. If TRUE, join repertoire metadata by the schema repertoire id. +Change the default behaviour by calling \code{options(immunarch.autojoin = FALSE)}.} -\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet -columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} - -\item{features}{Character vector of \strong{feature keys} to keep when -\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key -looks like \verb{family.method|facet1=...;facet2=...} (e.g., -\code{airr_stats.genes|v_call=TRBV7-2}).} +\item{format}{String. One of \code{"long"} ("long" tibble with \code{imd_repertoire_id}, facet +columns, and \code{value}; useful for visualizations) or \code{"wide"} (wide/unmelted table of features, +with each row corresponding to a specific repertoire / pair of repertoires; useful for Machine Learning).} \item{seq_col}{Character vector with names of the columns containing sequences.} From b50eae8ca7882ce6ae3002106e704486af432f60 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:58:25 +0200 Subject: [PATCH 30/36] feat: diversity --- R/v1_airr_diversity.R | 120 ++++++++++++++++++++++++++++++++++++++---- man/airr_diversity.Rd | 80 +++++++++++++++++----------- 2 files changed, 159 insertions(+), 41 deletions(-) diff --git a/R/v1_airr_diversity.R b/R/v1_airr_diversity.R index 516fb922..da0b01da 100644 --- a/R/v1_airr_diversity.R +++ b/R/v1_airr_diversity.R @@ -11,6 +11,7 @@ #' #' @param idata An `ImmunData` object. #' @inheritParams airr_diversity_dxx +#' @inheritParams airr_diversity_chao1 #' @inheritParams airr_diversity_shannon #' @inheritParams airr_diversity_pielou #' @inheritParams airr_diversity_hill @@ -30,7 +31,51 @@ NULL #' @keywords internal airr_diversity_dxx_impl <- function(idata, perc = 50) { - checkmate::assert_numeric(perc, null.ok = TRUE) + checkmate::assert_numeric(perc, any.missing = FALSE) + if (!all(perc > 0 & perc <= 100)) { + cli::cli_abort("{.code perc} must be in (0, 100].") + } + + rep_str <- immundata::imd_schema("repertoire") + rep_sym <- immundata::imd_schema_sym("repertoire") + rec_sym <- immundata::imd_schema_sym("receptor") + prop_str <- immundata::imd_schema("proportion") + prop_sym <- immundata::imd_schema_sym("proportion") + + base_tbl <- idata$annotations |> + dplyr::select(!!rec_sym, !!rep_sym, !!prop_sym) |> + dplyr::distinct(!!rec_sym, !!rep_sym, .keep_all = TRUE) |> + dplyr::arrange() + + k_sql <- sprintf( + "ROW_NUMBER() OVER (PARTITION BY %s ORDER BY %s DESC)", + rep_str, prop_str + ) + cum_sql <- sprintf( + "SUM(%s) OVER (PARTITION BY %s ORDER BY %s DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)", + prop_str, rep_str, prop_str + ) + + ranked <- base_tbl |> + duckplyr::as_tbl() |> + dplyr::mutate( + k = dbplyr::sql(k_sql), + cum = dbplyr::sql(cum_sql) + ) |> + duckplyr::as_duckdb_tibble() + + res <- purrr::map_dfr(perc, function(p) { + ranked |> + dplyr::filter(.data$cum >= p / 100) |> + dplyr::group_by(!!rep_sym) |> + dplyr::summarise(dxx = min(.data$k), .groups = "drop") |> + dplyr::mutate(perc = p) + }) |> + dplyr::select(!!rep_sym, .data$perc, .data$dxx) |> + dplyr::arrange(!!rep_sym, .data$perc) |> + collect() + + res } @@ -46,7 +91,7 @@ airr_diversity_dxx_impl <- function(idata, perc = 50) { #' #' ## `airr_diversity_dxx` #' A tibble with: -#' * `repertoire_id` +#' * `imd_repertoire_id` #' * `perc` #' * `dxx` — minimal count of top receptors to reach `perc%` #' * plus repertoire metadata from `idata$repertoires` @@ -64,6 +109,56 @@ airr_diversity_dxx_impl <- function(idata, perc = 50) { airr_diversity_dxx <- register_immunarch_method(airr_diversity_dxx_impl, "airr_diversity", "dxx") +#' @keywords internal +airr_diversity_chao1_impl <- function(idata) { + rep_col <- immundata::imd_schema("repertoire") + rep_sym <- immundata::imd_schema_sym("repertoire") + cnt_sym <- immundata::imd_schema_sym("count") + + # TODO: optimize this please, loading all the data in R is not good. + # TODO: check if no integer overflow + idata$annotations |> + select(!!rep_sym, !!cnt_sym) |> + collect() |> + summarise(counts = list(!!cnt_sym), .by = !!rep_sym) |> + mutate(ch = lapply(counts, chao1)) |> + transmute( + !!rep_col := !!rep_sym, + Estimator = vapply(ch, function(x) unname(x["Estimator.1"]), numeric(1)), + SD = vapply(ch, function(x) unname(x["SD.2"]), numeric(1)), + `Conf.95.lo` = vapply(ch, function(x) unname(x["Conf.95.lo.1"]), numeric(1)), + `Conf.95.hi` = vapply(ch, function(x) unname(x["Conf.95.hi.1"]), numeric(1)) + ) |> + collect() +} + +#' @description `airr_diversity_chao1` — Chao1 estimator is a nonparameteric +#' asymptotic estimator of species richness (number of species in a population). +#' One of the most used methods for estimating immune repertoire diversity. +#' +#' @return +#' +#' ## `airr_diversity_chao1` +#' A tibble with: +#' * `imd_repertoire_id` +#' * `Estimator` — number of species +#' * `SD` — standard deviation for the estimator value +#' * `Conf.95.lo` — CI 0.025 +#' * `Conf.95.hi` — CI 0.975 +#' * plus repertoire metadata from `idata$repertoires` +#' +#' @examples +#' # +#' # airr_diversity_chao1 +#' # +#' chao <- airr_diversity_chao1(immdata) +#' +#' @rdname airr_diversity +#' @concept Diversity +#' @export +airr_diversity_chao1 <- register_immunarch_method(airr_diversity_chao1_impl, "airr_diversity", "chao1") + + #' @keywords internal airr_diversity_shannon_impl <- function(idata) { idata$annotations |> @@ -79,7 +174,8 @@ airr_diversity_shannon_impl <- function(idata) { summarise( .by = !!immundata::imd_schema_sym("repertoire"), shannon = -sum(!!immundata::imd_schema_sym("proportion") * dd$log2(!!immundata::imd_schema_sym("proportion"))) - ) + ) |> + collect() } @@ -91,7 +187,7 @@ airr_diversity_shannon_impl <- function(idata) { #' #' ## `airr_diversity_shannon` #' A tibble with: -#' * `repertoire_id` +#' * `imd_repertoire_id` #' * `shannon` — entropy in bits #' #' @examples @@ -108,13 +204,15 @@ airr_diversity_shannon <- register_immunarch_method(airr_diversity_shannon_impl, #' @keywords internal airr_diversity_pielou_impl <- function(idata) { - shannon_values <- airr_diversity_shannon(idata) + shannon_values <- airr_diversity_shannon(idata, autojoin = FALSE) idata$repertoires |> + select(c(immundata::imd_schema("repertoire"), immundata::imd_schema("n_receptors"))) |> left_join(shannon_values, by = imd_schema("repertoire") ) |> - mutate(richness = dd$log2(!!immundata::imd_schema_sym("n_receptors")), pielou = shannon / richness) + mutate(richness = dd$log2(!!immundata::imd_schema_sym("n_receptors")), pielou = shannon / richness) |> + collect() } @@ -126,7 +224,7 @@ airr_diversity_pielou_impl <- function(idata) { #' #' ## `airr_diversity_pielou` #' A tibble with: -#' * `repertoire_id` +#' * `imd_repertoire_id` #' * `shannon` #' * `n_receptors` #' * `pielou` — evenness in `[0, 1]` (NA if `S ≤ 1`) @@ -157,7 +255,7 @@ airr_diversity_index_impl <- function(idata) { #' #' ## `airr_diversity_index` #' A tibble with: -#' * `repertoire_id` +#' * `imd_repertoire_id` #' * `q = 1` #' * `hill_number` #' * plus repertoire metadata from `idata$repertoires` @@ -223,7 +321,9 @@ airr_diversity_hill_impl <- function(idata, q = 0:5) { } } - idata$repertoires |> left_join(result, by = imd_schema("repertoire")) + idata$metadata |> + left_join(result, by = imd_schema("repertoire")) |> + collect() } @@ -239,7 +339,7 @@ airr_diversity_hill_impl <- function(idata, q = 0:5) { #' #' ## `airr_diversity_hill` #' A tibble with: -#' * `repertoire_id` +#' * `imd_repertoire_id` #' * `q` — Hill order #' * `hill_number` — true diversity of order `q` #' * plus repertoire metadata from `idata$repertoires` diff --git a/man/airr_diversity.Rd b/man/airr_diversity.Rd index 55b31bcc..b73dccf2 100644 --- a/man/airr_diversity.Rd +++ b/man/airr_diversity.Rd @@ -3,6 +3,7 @@ \name{airr_diversity} \alias{airr_diversity} \alias{airr_diversity_dxx} +\alias{airr_diversity_chao1} \alias{airr_diversity_shannon} \alias{airr_diversity_pielou} \alias{airr_diversity_index} @@ -12,38 +13,39 @@ airr_diversity_dxx( idata, perc = 50, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") +) + +airr_diversity_chao1( + idata, + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_diversity_shannon( idata, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_diversity_pielou( idata, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_diversity_index( idata, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_diversity_hill( idata, q = 0:5, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) } \arguments{ @@ -52,18 +54,12 @@ airr_diversity_hill( \item{perc}{A number or numeric vector in \verb{(0, 100]} (default \code{50}), e.g. \code{50} for D50, \code{20} for D20.} -\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. -For \code{format="analysis"}, metadata is joined to the long table; for -\code{format="ml"}, it’s joined after pivoting to wide. Defaults to -\code{getOption("immundata.autojoin", FALSE)}.} - -\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet -columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} +\item{autojoin}{Logical. If TRUE, join repertoire metadata by the schema repertoire id. +Change the default behaviour by calling \code{options(immunarch.autojoin = FALSE)}.} -\item{features}{Character vector of \strong{feature keys} to keep when -\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key -looks like \verb{family.method|facet1=...;facet2=...} (e.g., -\code{airr_stats.genes|v_call=TRBV7-2}).} +\item{format}{String. One of \code{"long"} ("long" tibble with \code{imd_repertoire_id}, facet +columns, and \code{value}; useful for visualizations) or \code{"wide"} (wide/unmelted table of features, +with each row corresponding to a specific repertoire / pair of repertoires; useful for Machine Learning).} \item{q}{A scalar or vector of non-negative orders. Defaults to \code{0:5}.} } @@ -72,18 +68,31 @@ looks like \verb{family.method|facet1=...;facet2=...} (e.g., A tibble with: \itemize{ -\item \code{repertoire_id} +\item \code{imd_repertoire_id} \item \code{perc} \item \code{dxx} — minimal count of top receptors to reach \verb{perc\%} \item plus repertoire metadata from \code{idata$repertoires} } } +\subsection{\code{airr_diversity_chao1}}{ + +A tibble with: +\itemize{ +\item \code{imd_repertoire_id} +\item \code{Estimator} — number of species +\item \code{SD} — standard deviation for the estimator value +\item \code{Conf.95.lo} — CI 0.025 +\item \code{Conf.95.hi} — CI 0.975 +\item plus repertoire metadata from \code{idata$repertoires} +} +} + \subsection{\code{airr_diversity_shannon}}{ A tibble with: \itemize{ -\item \code{repertoire_id} +\item \code{imd_repertoire_id} \item \code{shannon} — entropy in bits } } @@ -92,7 +101,7 @@ A tibble with: A tibble with: \itemize{ -\item \code{repertoire_id} +\item \code{imd_repertoire_id} \item \code{shannon} \item \code{n_receptors} \item \code{pielou} — evenness in \verb{[0, 1]} (NA if \verb{S ≤ 1}) @@ -103,7 +112,7 @@ A tibble with: A tibble with: \itemize{ -\item \code{repertoire_id} +\item \code{imd_repertoire_id} \item \code{q = 1} \item \code{hill_number} \item plus repertoire metadata from \code{idata$repertoires} @@ -114,7 +123,7 @@ A tibble with: A tibble with: \itemize{ -\item \code{repertoire_id} +\item \code{imd_repertoire_id} \item \code{q} — Hill order \item \code{hill_number} — true diversity of order \code{q} \item plus repertoire metadata from \code{idata$repertoires} @@ -135,6 +144,10 @@ top receptors needed to reach \verb{perc\%} of clonal space (by \code{proportion Great for spotting dominance/overexpansion and for quick, interpretable dashboards (e.g., D50 = receptors to cover half of the repertoire). +\code{airr_diversity_chao1} — Chao1 estimator is a nonparameteric +asymptotic estimator of species richness (number of species in a population). +One of the most used methods for estimating immune repertoire diversity. + \code{airr_diversity_shannon} — Shannon entropy (base 2) per repertoire computed from \code{proportion}. Ideal when you want a single evenness-aware diversity score; pair with Pielou/Hill for samples with very different richness. @@ -162,6 +175,11 @@ immdata <- get_test_idata() |> agg_repertoires("Therapy") d50 <- airr_diversity_dxx(immdata, perc = 50) d_multi <- airr_diversity_dxx(immdata, perc = c(20, 50, 80)) +# +# airr_diversity_chao1 +# +chao <- airr_diversity_chao1(immdata) + # # airr_diversity_shannon # From b4596f811600c63775b1c72ab67918b9da995a4c Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:58:33 +0200 Subject: [PATCH 31/36] feat: public --- man/airr_public.Rd | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/man/airr_public.Rd b/man/airr_public.Rd index 8ebf7da2..3ce4d64d 100644 --- a/man/airr_public.Rd +++ b/man/airr_public.Rd @@ -8,33 +8,25 @@ \usage{ airr_public_intersection( idata, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) airr_public_jaccard( idata, - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) } \arguments{ \item{idata}{An \code{ImmunData} object.} -\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. -For \code{format="analysis"}, metadata is joined to the long table; for -\code{format="ml"}, it’s joined after pivoting to wide. Defaults to -\code{getOption("immundata.autojoin", FALSE)}.} +\item{autojoin}{Logical. If TRUE, join repertoire metadata by the schema repertoire id. +Change the default behaviour by calling \code{options(immunarch.autojoin = FALSE)}.} -\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet -columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} - -\item{features}{Character vector of \strong{feature keys} to keep when -\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key -looks like \verb{family.method|facet1=...;facet2=...} (e.g., -\code{airr_stats.genes|v_call=TRBV7-2}).} +\item{format}{String. One of \code{"long"} ("long" tibble with \code{imd_repertoire_id}, facet +columns, and \code{value}; useful for visualizations) or \code{"wide"} (wide/unmelted table of features, +with each row corresponding to a specific repertoire / pair of repertoires; useful for Machine Learning).} } \value{ \subsection{\code{airr_public_intersection}}{ From 250cb0487527507ad13d48a84b36c85960c026ef Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 7 Oct 2025 17:58:55 +0200 Subject: [PATCH 32/36] chore: version bump, migration stuff --- DESCRIPTION | 6 +- NAMESPACE | 6 ++ R/aaa-registry.R | 147 ++++++++++++++++++++++++++----- R/globals.R | 8 +- R/immunarch-package.R | 3 + R/v1_migration_updates.R | 45 ++++++---- R/v1_migration_utils.R | 4 +- R/zzz.R | 55 ++++++------ man/im_common_args.Rd | 21 ++--- man/register_immunarch_method.Rd | 88 ++++++++++++++++++ 10 files changed, 299 insertions(+), 84 deletions(-) create mode 100644 man/register_immunarch_method.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 53f10884..ad020e0a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: immunarch Type: Package Title: Multi-Modal Immune Repertoire Analytics for Immunotherapy and Vaccine Design in R -Version: 0.9.1.9001 +Version: 0.10.0 Authors@R: c( person("Vadim I.", "Nazarov", , "support@immunomind.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-3659-2709")), @@ -19,12 +19,12 @@ Description: A comprehensive analytics framework for building reproducible pipel Think Scanpy or Seurat, but for AIRR data, a.k.a. Adaptive Immune Receptor Repertoire, VDJ-seq, RepSeq, or VDJ sequencing data. A successor to our previously published "tcR" R package (Nazarov 2015). License: Apache License (== 2.0) -URL: https://immunarch.com/, https://github.com/immunomind/immunarch +URL: https://immunomind.github.io/docs/, https://github.com/immunomind/immunarch BugReports: https://github.com/immunomind/immunarch/issues Depends: R (>= 4.1.0), ggplot2 (>= 3.1.0), - immundata (>= 0.0.3), + immundata (>= 0.0.5), patchwork Imports: dplyr, diff --git a/NAMESPACE b/NAMESPACE index 018fb042..e9f001af 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -49,6 +49,7 @@ S3method(vis,step_failure_ignored) export(airr_clonality_line) export(airr_clonality_prop) export(airr_clonality_rank) +export(airr_diversity_chao1) export(airr_diversity_dxx) export(airr_diversity_hill) export(airr_diversity_index) @@ -59,6 +60,8 @@ export(airr_public_jaccard) export(airr_stats_chains) export(airr_stats_genes) export(airr_stats_lengths) +export(annotate_clonality_prop) +export(annotate_clonality_rank) export(apply_asymm) export(apply_symm) export(bunch_translate) @@ -203,6 +206,7 @@ importFrom(dplyr,slice_head) importFrom(dplyr,summarise) importFrom(dplyr,tally) importFrom(dplyr,top_n) +importFrom(dplyr,transmute) importFrom(dplyr,ungroup) importFrom(dplyr,union) importFrom(dplyr,union_all) @@ -291,12 +295,14 @@ importFrom(stringr,str_sub) importFrom(stringr,str_trim) importFrom(tibble,rownames_to_column) importFrom(tibble,tibble) +importFrom(tidyr,as_tibble) importFrom(tidyr,drop_na) importFrom(tidyr,unite) importFrom(tidyr,unnest) importFrom(tidyselect,all_of) importFrom(tidyselect,any_of) importFrom(tidyselect,starts_with) +importFrom(utils,adist) importFrom(utils,capture.output) importFrom(utils,globalVariables) importFrom(utils,packageVersion) diff --git a/R/aaa-registry.R b/R/aaa-registry.R index 3d536317..140dcd98 100644 --- a/R/aaa-registry.R +++ b/R/aaa-registry.R @@ -3,28 +3,22 @@ IMMUNARCH_METHOD_REGISTRY <- new.env(parent = emptyenv()) #' Common arguments for immundata helpers #' @keywords internal -#' @param autojoin If TRUE, join repertoire metadata by the schema repertoire id. -#' For `format="analysis"`, metadata is joined to the long table; for -#' `format="ml"`, it’s joined after pivoting to wide. Defaults to -#' `getOption("immundata.autojoin", FALSE)`. -#' @param format One of `"analysis"` (long tibble with `repertoire_id`, facet -#' columns, and `value`) or `"ml"` (wide/unmelted table of features). -#' @param features Character vector of **feature keys** to keep when -#' `format="ml"`. If `NULL`, features are derived from the data. A feature key -#' looks like `family.method|facet1=...;facet2=...` (e.g., -#' `airr_stats.genes|v_call=TRBV7-2`). +#' @param autojoin Logical. If TRUE, join repertoire metadata by the schema repertoire id. +#' Change the default behaviour by calling `options(immunarch.autojoin = FALSE)`. +#' @param format String. One of `"long"` ("long" tibble with `imd_repertoire_id`, facet +#' columns, and `value`; useful for visualizations) or `"wide"` (wide/unmelted table of features, +#' with each row corresponding to a specific repertoire / pair of repertoires; useful for Machine Learning). im_common_args <- function( - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL) {} # nocov + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide")) {} # nocov -im_method <- function(core, family, name) { +im_method <- function(core, family, name, required_cols = NULL, need_repertoires = TRUE) { checkmate::assert_function(core, args = c("idata")) checkmate::assert_string(family) checkmate::assert_string(name) + checkmate::assert_logical(need_repertoires) - # Merge core formals with wrapper defaults to enable autocompletion core_fmls <- formals(core) if (!"idata" %in% names(core_fmls)) { cli::cli_abort("Core method must declare an {.code idata} argument.") @@ -33,6 +27,11 @@ im_method <- function(core, family, name) { cli::cli_abort("Core method must not declare {.code autojoin}, {.code format}, or {.code features}.") } + # required_cols = columns expected in idata$annotations + if (!is.null(required_cols)) { + checkmate::assert_character(required_cols, any.missing = FALSE) + } + wrapper <- function() { } formals(wrapper) <- c( core_fmls, @@ -43,25 +42,131 @@ im_method <- function(core, family, name) { body(wrapper) <- substitute( { format <- match.arg(format) - - # Pre: validate idata + schema checkmate::assert_r6(idata, "ImmunData") - # Build argument list for core from our own formals (now visible to the user) + if (need_repertoires) { + if (is.null(idata$schema_repertoire)) { + cli::cli_abort("Repertoire aggregation is needed for this function. Run {.code ?agg_repertoires} for more info.") + } + } + + # For each argument name in `required_cols`, fetch its runtime value + # and ensure the referenced columns exist in idata$annotations. + if (length(required_cols)) { + ann_cols <- colnames(idata$annotations) + for (.arg in required_cols) { + .val <- get(.arg, inherits = TRUE) + + # Just in case + if (is.null(.val) || (length(.val) == 1 && is.na(.val))) next + + # Allow symbols or character vectors + if (rlang::is_symbol(.val)) { + .val <- rlang::as_string(.val) + } + + if (!is.character(.val)) { + cli::cli_abort("Argument {.code {.arg}} must be a character (column name) or character vector; got a {.code {class(.val)[1]}}.") + } + + missing <- setdiff(.val, ann_cols) + if (length(missing)) { + suggest <- function(x, pool, n = 3) { + if (!length(pool)) { + return(character()) + } + d <- utils::adist(x, pool) + pool[order(d)][seq_len(min(n, length(pool)))] + } + hints <- unique(unlist(lapply(missing, suggest, pool = ann_cols, n = 3))) + cli::cli_abort("Passed column name(s) [{.code {missing}}] is not in the input ImmunData. Did you mean [{.code {hints}}]?") + } + } + } + + # Call core with its own formals .core_args <- mget(names(core_fmls), inherits = TRUE) out <- do.call(core, .core_args) + # Autojoin: join repertoire metadata if requested and applicable (!) + if (isTRUE(autojoin) && !is.null(idata$repertoires)) { + rep_col <- immundata::imd_schema("repertoire") + if (!is.null(rep_col) && rep_col %in% names(out)) { + out <- dplyr::left_join(out, idata$repertoires |> select(all_of(c(rep_col, idata$schema_repertoire))), by = rep_col) + } + } + out }, - list(core = core, core_fmls = core_fmls) + list(core = core, core_fmls = core_fmls, required_cols = required_cols) ) wrapper } -register_immunarch_method <- function(core, family, name, register_family = TRUE) { - fn <- im_method(core, family, name) +#' Register an Immunarch method (developer) +#' +#' `r lifecycle::badge("experimental")` +#' +#' Wrap a core implementation into a user-facing function and (optionally) +#' register it in the in-memory method registry. The wrapper **adds common +#' arguments** and **runs safety checks** so your core stays minimal. +#' +#' ## What your core must look like +#' * Signature: `function(idata, ...)` +#' * **Must not** declare `autojoin`, `format`, or `features` — these are added by the wrapper. +#' +#' ## What the wrapper adds +#' * Common args from `im_common_args()`: `autojoin`, `format`, `features` +#' (with `autojoin` default controlled by `getOption("immunarch.autojoin", FALSE)`). +#' * Validates `idata` is an [immundata::ImmunData] object. +#' * Ensures all columns in `required_cols` exist in `idata$annotations`. +#' * If `autojoin = TRUE` and the result is a data frame containing the repertoire id +#' column (`immundata::imd_schema("repertoire")`), joins repertoire metadata from +#' `idata$repertoires`. +#' +#' @param core A function with signature `function(idata, ...)`. This is your core +#' implementation; it must accept an `ImmunData` as the first argument and **must not** +#' declare `autojoin`, `format`, or `features`. +#' @param family String. Method family name used for dispatch (e.g., `"airr_stats"`). +#' @param name String. Method name within the family (e.g., `"lengths"`). +#' @param register_family Logical (default `TRUE`). If `TRUE`, attempts to create/ensure +#' the family environment by calling `register_airr_family()` when available. +#' @param required_cols Character vector of column names that **must** be present in +#' `idata$annotations`. Use this to declare the minimal input schema your core needs. +#' @param need_repertoires Logical. Use this to declare the necessity of having aggregated +#' repertoires. +#' +#' @return A **function** — the user-facing wrapper around `core`. Typical usage is to +#' assign it to the exported symbol of the method, e.g.: +#' `airr_stats_lengths <- register_immunarch_method(...)`. +#' +#' @examples +#' \dontrun{ +#' # Minimal core implementation (must accept `idata`) +#' airr_stats_lengths_impl <- function(idata, seq_col = "cdr3_aa") { +#' dplyr::as_tibble(idata$annotations) |> +#' dplyr::distinct(.data[[immundata::imd_schema("repertoire")]], .data[[seq_col]]) |> +#' dplyr::mutate(seq_len = nchar(.data[[seq_col]])) |> +#' dplyr::count(.data[[immundata::imd_schema("repertoire")]], seq_len, name = "n") +#' } +#' +#' # Register and expose a user-facing function +#' airr_stats_lengths <- register_immunarch_method( +#' core = airr_stats_lengths_impl, +#' family = "airr_stats", +#' name = "lengths", +#' required_cols = c("cdr3_aa", immundata::imd_schema("repertoire")) +#' ) +#' +#' # Optional: call via dispatcher +#' # make_airr_dispatcher("airr_stats")(idata = immdata, method = "lengths") +#' } +#' +#' @keywords internal +register_immunarch_method <- function(core, family, name, register_family = TRUE, required_cols = NULL, need_repertoires = TRUE) { + fn <- im_method(core, family, name, required_cols = required_cols, need_repertoires = need_repertoires) if (isTRUE(register_family) && exists("register_airr_family", mode = "function", inherits = TRUE)) { try(register_airr_family(family), silent = TRUE) diff --git a/R/globals.R b/R/globals.R index 7ffdbaa6..468d578a 100644 --- a/R/globals.R +++ b/R/globals.R @@ -2,7 +2,13 @@ utils::globalVariables(c( "index", "richness", "shannon", - "dd" + "dd", + "counts", + "annotate_immundata", + "ch", + "clonal_prop_bin", + "clonal_rank_bin", + "prop" )) #' @keywords internal diff --git a/R/immunarch-package.R b/R/immunarch-package.R index 76eddd95..0d1915b5 100644 --- a/R/immunarch-package.R +++ b/R/immunarch-package.R @@ -32,6 +32,7 @@ #' @importFrom dplyr select #' @importFrom dplyr slice_head #' @importFrom dplyr summarise +#' @importFrom dplyr transmute #' @importFrom dplyr union #' @importFrom dplyr union_all #' @importFrom duckplyr as_duckdb_tibble @@ -53,6 +54,8 @@ #' @importFrom rlang set_names #' @importFrom rlang sym #' @importFrom stats runif +#' @importFrom tidyr as_tibble +#' @importFrom utils adist #' @importFrom utils globalVariables #' @useDynLib immunarch, .registration = TRUE ## usethis namespace: end diff --git a/R/v1_migration_updates.R b/R/v1_migration_updates.R index 8d36616f..7019e278 100644 --- a/R/v1_migration_updates.R +++ b/R/v1_migration_updates.R @@ -1,17 +1,17 @@ #' @keywords internal -immunarch_v1_update_sep_2025 <- function() { - cli::cli_h1("{cli::col_green('immunarch')} {cli::col_yellow('0.9.x')} -- Critical Pre-release Notice") +immunarch_v1_update_oct_2025 <- function() { + cli::cli_h1("{cli::col_green('immunarch')} {cli::col_yellow('0.10.0')} -- Critical Pre-release Notice") - cli::cli_alert_warning("Update #1 [Sep 2025] -- Major changes are coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}!") + cli::cli_alert_warning("Update #1 [Oct 2025] -- Major changes are coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}!") cli::cli_text(cli::col_yellow(cli::spark_line(runif(110, 0, 1)))) cli::cli_par() cli::cli_text() cli::cli_text( - "Hi, this is Vadim Nazarov speaking -- author of {cli::col_green('immunarch')}. ", - "{cli::col_green('immunarch')} is finally graduating from out of the {cli::col_yellow('0.x.y')} development cycle. ", - "I'm preparing our {cli::col_yellow('1.0.0')} release, which will remain stable and free of sudden changes until we approach {cli::col_yellow('2.0.0')}, along with ", - "a scientific publication for proper citations. ", + "Hi, this is Vadim Nazarov speaking - author of {cli::col_green('immunarch')}. ", + "{cli::col_green('immunarch')} is finally graduating out of the {cli::col_yellow('0.x.y')} development cycle. ", + "I'm preparing our {cli::col_yellow('1.0.0')} release, which will remain stable and free of sudden changes until we approach {cli::col_yellow('2.0.0')}. ", + "A scientific publication will accompany it for proper citation. ", "Significant changes are coming, and I want to ensure you have everything you need to migrate to the new version." ) @@ -19,21 +19,28 @@ immunarch_v1_update_sep_2025 <- function() { cli::cli_text() cli::cli_text("Here's a preview of what's coming in {cli::col_green('immunarch')} {cli::col_yellow('1.0.0')}:") cli::cli_bullets(c( - "i" = "Some computationally intensive or advanced features (e.g., distance computations, graph-based analyses, dimensionality reduction techniques) will move to separate packages, making {cli::col_green('immunarch')} much more lightweight to install and manage;", - "i" = "New functions will be introduced instead of the left old ones to make code more readable and maintainable. Legacy functions will remain temporarily, but they won't be updated and will be removed by {cli::col_yellow('~2027')};", - "i" = "We will discontinue support for most custom file formats because the AIRR ecosystem is now mature enough that the majority of tools adhere to the AIRR standard;", - "i" = "The package will transition from data frames to the new {cli::col_blue('ImmunData')} structure -- better suited for handling modern larger, more complex, and multi-modal datasets (e.g., single-cell, spatial);", - "i" = "{cli::col_blue('ImmunData')} is available in the separate {cli::col_blue('immundata')} package, which you can already install via {cli::col_cyan('pak::pkg_install(\"immundata\")')};", - "i" = "The {cli::col_blue('ImmunData')}-based computations will be significantly faster, support datasets larger than RAM, and fully adhere to AIRR Community standards.", - "i" = "There currently only a handful functions which implement {cli::col_blue('ImmunData')}-based computations. However, if you want to start learning it, or you have a large-scale data, now it is the best time: the tutorials are available on {cli::col_cyan('https://github.com/immunomind/immundata') and {cli::col_cyan('https://immunomind.github.io/docs/')}" + "i" = "Some computationally intensive or advanced features (e.g., distance computations, graph-based analyses, dimensionality reduction techniques) will move to separate packages, making {cli::col_green('immunarch')} much lighter to install and manage.", + "i" = "New functions will replace older ones to make code more readable and maintainable. Legacy functions will remain temporarily, but they won't be updated and will be removed {cli::col_yellow('around 2027')}.", + "i" = "We will discontinue support for most custom file formats because the AIRR ecosystem is now mature enough; most tools adhere to the AIRR standard.", + "i" = "The package will transition from data frames to the new {cli::col_blue('ImmunData')} structure, better suited for handling larger, more complex, and multimodal datasets (e.g., single-cell, spatial).", + "i" = "{cli::col_blue('ImmunData')} is available in the separate {cli::col_blue('immundata')} package, which you can already install via {cli::col_cyan('pak::pkg_install(\"immundata\")')}.", + "i" = "The {cli::col_blue('ImmunData')}-based computations will be significantly faster, will support datasets larger than RAM, and will fully adhere to AIRR Community standards.", + "i" = "There are currently only a handful of functions that implement {cli::col_blue('ImmunData')}-based computations. However, if you want to start learning it, or you have large-scale data, now is the best time: tutorials are available at {.url https://github.com/immunomind/immundata} and {.url https://immunomind.github.io/docs/}." )) cli::cli_par() cli::cli_text() cli::cli_text( - "See the dedicated migration guide for migration on what you can do now and how to prepare for the future:" + "See the dedicated migration guide for what you can do now and how to prepare for the future:" ) - cli::cli_text(">> visit {cli::col_cyan('https://immunomind.github.io/docs/tutorials/migration')}") + cli::cli_text(">> visit {.url https://immunomind.github.io/docs/tutorials/migration}") + + cli::cli_par() + cli::cli_text() + cli::cli_text( + "See the comprehensive tutorial on how to analyse single-cell AIRR data:" + ) + cli::cli_text(">> visit {.url https://immunomind.github.io/docs/tutorials/single_cell}") cli::cli_par() cli::cli_text() @@ -42,9 +49,9 @@ immunarch_v1_update_sep_2025 <- function() { cli::cli_par() cli::cli_text() cli::cli_alert_info("Questions, comments, ideas? I'm available via:") - cli::cli_text(">> Support email: {cli::col_cyan('support@immunomind.com')}") - cli::cli_text(">> GitHub tickets: {cli::col_cyan('https://github.com/immunomind/immunarch')}") - cli::cli_text(">> LinkedIn: {cli::col_cyan('https://www.linkedin.com/in/vdnaz/')}") + cli::cli_text(">> Support email: {.url mailto:support@immunomind.com}") + cli::cli_text(">> GitHub tickets: {.url https://github.com/immunomind/immunarch}") + cli::cli_text(">> LinkedIn: {.url https://www.linkedin.com/in/vdnaz/}") cli::cli_par() cli::cli_text() diff --git a/R/v1_migration_utils.R b/R/v1_migration_utils.R index bdb2e275..79d0bb33 100644 --- a/R/v1_migration_utils.R +++ b/R/v1_migration_utils.R @@ -38,5 +38,7 @@ get_immunarch_news <- function(datepoint = "latest") { #' #' @export list_immunarch_news <- function() { - names(immunarch_v1_updates) + for (i in seq_along(names(immunarch_v1_updates))) { + cat(names(immunarch_v1_updates), " -> ", "run immunarch::get_immunarch_news(", '"', names(immunarch_v1_updates), '"', ")", sep = "") + } } diff --git a/R/zzz.R b/R/zzz.R index 75ae6e1a..b9a94425 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,35 +1,40 @@ #' Get a list of package updates #' @concept migration_utility immunarch_v1_updates <- c( - "Sep 2025" = immunarch_v1_update_sep_2025 + "Oct 2025" = immunarch_v1_update_oct_2025 ) .onAttach <- function(libname, pkgname) { - msg <- paste0( - "Hi, this is Vadim Nazarov speaking -- author of ", - cli::col_green("immunarch"), - ".\n", - cli::col_green("immunarch"), - " is evolving towards its 1.0 release. Soon it will be faster, more user-friendly, and ready for its long-awaited publication. Some functions will no longer be supported or will be replaced with new, more powerful methods.\n", - "\n -- Please click on ", - cli::col_cyan("{.run [get_immunarch_news()](immunarch::get_immunarch_news())}"), - " or run it in your R console to read the latest update and learn what has changed, what's new, how to migrate your code, and what changes are planned for the next update.\n", - "\n -- Click on ", - cli::col_cyan("{.run [list_immunarch_news()](immunarch::list_immunarch_news())}"), - " or run it to list all available updates and catch up on any you may have missed. Latest update: ", - cli::col_yellow("#1, Sep 2025"), - "\n", - "\n -- To import the package without this message, run ", - cli::col_cyan("suppressPackageStartupMessages(library(\"immunarch\"))"), - "\n", - "\nMigration guide is available online:\n\n-- in R: ", - "\n", - " {.url https://immunomind.github.io/docs/tutorials/migration}", - "\n\nThank you.\n", - "\n- Vadim I. Nazarov" + lines <- c( + paste0("Hi, this is Vadim Nazarov - author of ", cli::col_green("immunarch"), "."), + paste0( + cli::col_green("immunarch"), + " is moving toward its 1.0 release. It will be faster, more user-friendly, and ready for publication. ", + "Some functions will be deprecated or replaced with newer, more powerful methods." + ), + "", + "- Click {.run [get_immunarch_news()](immunarch::get_immunarch_news())} to read the latest update (what changed, what's new, how to migrate, what's next).", + "", + "- Click {.run [list_immunarch_news()](immunarch::list_immunarch_news())} to list all updates (latest: {cli::col_yellow('#1, Oct 2025')}).", + "", + "- Migration guide: {.url https://immunomind.github.io/docs/tutorials/migration}", + "", + "To load the package without this message: {.code suppressPackageStartupMessages(library('immunarch'))}", + "", + "- Vadim I. Nazarov" ) - cli::cli_inform(msg, class = "packageStartupMessage") + msg <- paste(lines, collapse = "\n") + cli::cli_inform(cli::format_inline(msg), class = "packageStartupMessage") +} + - # Show registered methods? +.onLoad <- function(libname, pkgname) { + op <- options() + op.immunarch <- list( + immunarch.autojoin = FALSE # default + ) + toset <- !(names(op.immunarch) %in% names(op)) + if (any(toset)) options(op.immunarch[toset]) + invisible() } diff --git a/man/im_common_args.Rd b/man/im_common_args.Rd index 94fb8612..247c712a 100644 --- a/man/im_common_args.Rd +++ b/man/im_common_args.Rd @@ -5,24 +5,17 @@ \title{Common arguments for immundata helpers} \usage{ im_common_args( - autojoin = getOption("immundata.autojoin", FALSE), - format = c("analysis", "ml"), - features = NULL + autojoin = getOption("immundata.autojoin", TRUE), + format = c("long", "wide") ) } \arguments{ -\item{autojoin}{If TRUE, join repertoire metadata by the schema repertoire id. -For \code{format="analysis"}, metadata is joined to the long table; for -\code{format="ml"}, it’s joined after pivoting to wide. Defaults to -\code{getOption("immundata.autojoin", FALSE)}.} +\item{autojoin}{Logical. If TRUE, join repertoire metadata by the schema repertoire id. +Change the default behaviour by calling \code{options(immunarch.autojoin = FALSE)}.} -\item{format}{One of \code{"analysis"} (long tibble with \code{repertoire_id}, facet -columns, and \code{value}) or \code{"ml"} (wide/unmelted table of features).} - -\item{features}{Character vector of \strong{feature keys} to keep when -\code{format="ml"}. If \code{NULL}, features are derived from the data. A feature key -looks like \verb{family.method|facet1=...;facet2=...} (e.g., -\code{airr_stats.genes|v_call=TRBV7-2}).} +\item{format}{String. One of \code{"long"} ("long" tibble with \code{imd_repertoire_id}, facet +columns, and \code{value}; useful for visualizations) or \code{"wide"} (wide/unmelted table of features, +with each row corresponding to a specific repertoire / pair of repertoires; useful for Machine Learning).} } \description{ Common arguments for immundata helpers diff --git a/man/register_immunarch_method.Rd b/man/register_immunarch_method.Rd new file mode 100644 index 00000000..275be471 --- /dev/null +++ b/man/register_immunarch_method.Rd @@ -0,0 +1,88 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/aaa-registry.R +\name{register_immunarch_method} +\alias{register_immunarch_method} +\title{Register an Immunarch method (developer)} +\usage{ +register_immunarch_method( + core, + family, + name, + register_family = TRUE, + required_cols = NULL, + need_repertoires = TRUE +) +} +\arguments{ +\item{core}{A function with signature \verb{function(idata, ...)}. This is your core +implementation; it must accept an \code{ImmunData} as the first argument and \strong{must not} +declare \code{autojoin}, \code{format}, or \code{features}.} + +\item{family}{String. Method family name used for dispatch (e.g., \code{"airr_stats"}).} + +\item{name}{String. Method name within the family (e.g., \code{"lengths"}).} + +\item{register_family}{Logical (default \code{TRUE}). If \code{TRUE}, attempts to create/ensure +the family environment by calling \code{register_airr_family()} when available.} + +\item{required_cols}{Character vector of column names that \strong{must} be present in +\code{idata$annotations}. Use this to declare the minimal input schema your core needs.} + +\item{need_repertoires}{Logical. Use this to declare the necessity of having aggregated +repertoires.} +} +\value{ +A \strong{function} — the user-facing wrapper around \code{core}. Typical usage is to +assign it to the exported symbol of the method, e.g.: +\code{airr_stats_lengths <- register_immunarch_method(...)}. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} +} +\details{ +Wrap a core implementation into a user-facing function and (optionally) +register it in the in-memory method registry. The wrapper \strong{adds common +arguments} and \strong{runs safety checks} so your core stays minimal. +\subsection{What your core must look like}{ +\itemize{ +\item Signature: \verb{function(idata, ...)} +\item \strong{Must not} declare \code{autojoin}, \code{format}, or \code{features} — these are added by the wrapper. +} +} + +\subsection{What the wrapper adds}{ +\itemize{ +\item Common args from \code{im_common_args()}: \code{autojoin}, \code{format}, \code{features} +(with \code{autojoin} default controlled by \code{getOption("immunarch.autojoin", FALSE)}). +\item Validates \code{idata} is an \link[immundata:ImmunData]{immundata::ImmunData} object. +\item Ensures all columns in \code{required_cols} exist in \code{idata$annotations}. +\item If \code{autojoin = TRUE} and the result is a data frame containing the repertoire id +column (\code{immundata::imd_schema("repertoire")}), joins repertoire metadata from +\code{idata$repertoires}. +} +} +} +\examples{ +\dontrun{ +# Minimal core implementation (must accept `idata`) +airr_stats_lengths_impl <- function(idata, seq_col = "cdr3_aa") { + dplyr::as_tibble(idata$annotations) |> + dplyr::distinct(.data[[immundata::imd_schema("repertoire")]], .data[[seq_col]]) |> + dplyr::mutate(seq_len = nchar(.data[[seq_col]])) |> + dplyr::count(.data[[immundata::imd_schema("repertoire")]], seq_len, name = "n") +} + +# Register and expose a user-facing function +airr_stats_lengths <- register_immunarch_method( + core = airr_stats_lengths_impl, + family = "airr_stats", + name = "lengths", + required_cols = c("cdr3_aa", immundata::imd_schema("repertoire")) +) + +# Optional: call via dispatcher +# make_airr_dispatcher("airr_stats")(idata = immdata, method = "lengths") +} + +} +\keyword{internal} From 4bf5976694a23d435afcb10b42068706b15d5ec6 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 7 Oct 2025 18:29:08 +0200 Subject: [PATCH 33/36] chore: fix README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f0813243..88b62017 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@

- Tutorials + Tutorials | API reference | From a3d6dd1e5c78d67166768b4dce9095d1cf33a1e2 Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Tue, 7 Oct 2025 18:50:55 +0200 Subject: [PATCH 34/36] chore: remove badge --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 88b62017..99acacfb 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,6 @@ CRAN Downloads (last week) - - Conda Downloads - Conda Version From 64def9ee57703f7a769db6c1fb19bd6a3f7bd3ac Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Thu, 9 Oct 2025 15:24:32 +0200 Subject: [PATCH 35/36] tests: remove tests, prepare for new v1 tests --- tests/testthat/helper-preload.R | 40 --- tests/testthat/test-align-lineage.R | 100 ------- tests/testthat/test-clonal-family.R | 115 -------- tests/testthat/test-clonality.R | 14 - tests/testthat/test-distance.R | 71 ----- tests/testthat/test-diversity.R | 48 ---- tests/testthat/test-dynamics.R | 71 ----- tests/testthat/test-explore.R | 35 --- tests/testthat/test-filter.R | 299 -------------------- tests/testthat/test-geneusage.R | 17 -- tests/testthat/test-germline.R | 76 ----- tests/testthat/test-kmers.R | 36 --- tests/testthat/test-overlap.R | 16 -- tests/testthat/test-pubrep.R | 22 -- tests/testthat/test-seqCluster.R | 48 ---- tests/testthat/test-somatic-hypermutation.R | 95 ------- tests/testthat/test-spectr.R | 16 -- 17 files changed, 1119 deletions(-) delete mode 100644 tests/testthat/helper-preload.R delete mode 100644 tests/testthat/test-align-lineage.R delete mode 100644 tests/testthat/test-clonal-family.R delete mode 100644 tests/testthat/test-clonality.R delete mode 100644 tests/testthat/test-distance.R delete mode 100644 tests/testthat/test-diversity.R delete mode 100644 tests/testthat/test-dynamics.R delete mode 100644 tests/testthat/test-explore.R delete mode 100644 tests/testthat/test-filter.R delete mode 100644 tests/testthat/test-geneusage.R delete mode 100644 tests/testthat/test-germline.R delete mode 100644 tests/testthat/test-kmers.R delete mode 100644 tests/testthat/test-overlap.R delete mode 100644 tests/testthat/test-pubrep.R delete mode 100644 tests/testthat/test-seqCluster.R delete mode 100644 tests/testthat/test-somatic-hypermutation.R delete mode 100644 tests/testthat/test-spectr.R diff --git a/tests/testthat/helper-preload.R b/tests/testthat/helper-preload.R deleted file mode 100644 index 7430608d..00000000 --- a/tests/testthat/helper-preload.R +++ /dev/null @@ -1,40 +0,0 @@ -apply_DF_DT <- function(df_data, dt_data, .fun, ...) { - res1 <- .fun(df_data, ...) - res2 <- .fun(dt_data, ...) - list(df = res1, dt = res2) -} - -vis_results <- function(res_list, ...) { - p_df <- vis(res_list$df, ...) - p_dt <- vis(res_list$dt, ...) - list(df = p_df, dt = p_dt) -} - -check_for_mutation <- function(.frame, .table) { - expect_equal(lapply(.frame, as.data.table), .table) -} - -# add pretfix -ap <- function(.name, .prefix) { - paste0(.prefix, .name) -} - -add_mock_sample <- function(.immdata, .sample_name, .meta = list(), .empty = FALSE) { - if (.empty) { - # copy only column headers - .immdata$data[[.sample_name]] <- .immdata$data[[1]][0, ] - } else { - # copy dataframe of 1st sample to the new sample - .immdata$data[[.sample_name]] <- .immdata$data[[1]] - } - - # .meta must be a named list containing metadata row (full or partial) for the sample - .meta[["Sample"]] <- .sample_name - .immdata$meta %<>% bind_rows(as.data.frame(.meta)) - - return(.immdata) -} - -data(immdata) -frame_data <- immdata$data -table_data <- lapply(frame_data, as.data.table) diff --git a/tests/testthat/test-align-lineage.R b/tests/testthat/test-align-lineage.R deleted file mode 100644 index 3b111f53..00000000 --- a/tests/testthat/test-align-lineage.R +++ /dev/null @@ -1,100 +0,0 @@ -data(bcrdata) -test_bcr_data <- bcrdata$data %>% top(1000) -test_input <- test_bcr_data %>% - seqCluster(seqDist(test_bcr_data), .fixed_threshold = 3) %>% - repGermline(.threads = 1) %>% - suppressWarnings() - -positive_test_cases <- list( - "Not empty result" = list( - args = list( - .data = test_input, - .min_lineage_sequences = 2, - .prepare_threads = 1, - .align_threads = 1 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result[["full_clones"]]) > 0, TRUE) - } - ), - "Multiple threads" = list( - args = list( - .data = test_input, - .min_lineage_sequences = 2 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result[["full_clones"]]) > 0, TRUE) - } - ), - "Dataframe only" = list( - args = list( - .data = test_input[["full_clones"]], - .min_lineage_sequences = 2, - .prepare_threads = 1, - .align_threads = 1 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result) > 0, TRUE) - } - ) -) - -for (i in seq_along(positive_test_cases)) { - # Arrange - test_name <- names(positive_test_cases)[i] - args <- positive_test_cases[[i]][["args"]] - assert_function <- positive_test_cases[[i]][["assert_function"]] - - # Act - result <- suppressWarnings(do.call(repAlignLineage, args)) - - # Assert - test_that( - test_name, - assert_function(result) - ) -} - -negative_test_cases <- list( - "List of lists" = list( - args = list( - .data = bcrdata - ) - ), - "Missing columns" = list( - args = list( - .data = test_bcr_data[["full_clones"]], - .prepare_threads = 1, - .align_threads = 1 - ) - ), - "Missing Cluster column" = list( - args = list( - .data = subset(test_input[["full_clones"]], select = -c(get("Cluster"))), - .prepare_threads = 1, - .align_threads = 1 - ) - ), - "Missing Germline.sequence column" = list( - args = list( - .data = subset(test_input[["full_clones"]], select = -c(get("Germline.sequence"))), - .prepare_threads = 1, - .align_threads = 1 - ) - ) -) - -for (i in seq_along(negative_test_cases)) { - # Arrange - test_name <- names(negative_test_cases)[i] - args <- negative_test_cases[[i]][["args"]] - - # Act, Assert - test_that( - test_name, - expect_error(suppressWarnings(do.call(repAlignLineage, args))) - ) -} diff --git a/tests/testthat/test-clonal-family.R b/tests/testthat/test-clonal-family.R deleted file mode 100644 index 8c09a65e..00000000 --- a/tests/testthat/test-clonal-family.R +++ /dev/null @@ -1,115 +0,0 @@ -data(bcrdata) -test_bcr_data <- bcrdata$data %>% top(1000) -test_input <- test_bcr_data %>% - seqCluster(seqDist(test_bcr_data), .fixed_threshold = 3) %>% - repGermline(.threads = 1) %>% - repAlignLineage(.min_lineage_sequences = 2, .prepare_threads = 1, .align_threads = 1) %>% - suppressWarnings() - -positive_test_cases <- list( - "Not empty result" = list( - args = list( - .data = test_input, - .threads = 1 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result[["full_clones"]]) > 0, TRUE) - } - ), - "Multiple threads" = list( - args = list( - .data = test_input, - .threads = 8 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result[["full_clones"]]) > 0, TRUE) - } - ), - "Dataframe only" = list( - args = list( - .data = test_input[["full_clones"]], - .threads = 1 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result) > 0, TRUE) - } - ), - "Vis groups" = list( - args = list( - .data = test_input, - .vis_groups = { - clone_ids <- test_input[["full_clones"]] %>% - unnest("Sequences") %>% - extract2("Clone.ID") - list( - Group1 = clone_ids[1], - Group2 = clone_ids[3], - Group3 = list(clone_ids[5], clone_ids[2]), - Group4 = c(clone_ids[7], clone_ids[4]) - ) - }, - .threads = 1 - ), - assert_function = function(result) { - types <- result[["full_clones"]] %>% - unnest("TreeStats") %>% - extract2("Type") - # check that correct number of clonotypes is assigned to each group - expect_equal(tabulate(match(types, "Group1")), 1) - expect_equal(tabulate(match(types, "Group2")), 1) - expect_equal(tabulate(match(types, "Group3")), 2) - expect_equal(tabulate(match(types, "Group4")), 2) - } - ) -) - -for (i in seq_along(positive_test_cases)) { - # Arrange - test_name <- names(positive_test_cases)[i] - args <- positive_test_cases[[i]][["args"]] - assert_function <- positive_test_cases[[i]][["assert_function"]] - - # Act - result <- do.call(repClonalFamily, args) - - # Assert - test_that( - test_name, - assert_function(result) - ) -} - -negative_test_cases <- list( - "List of lists" = list( - args = list( - .data = bcrdata - ) - ), - "Missing columns" = list( - args = list( - .data = test_bcr_data[["full_clones"]], - .threads = 1 - ) - ), - "Missing Alignment column" = list( - args = list( - .data = subset(test_input[["full_clones"]], select = -c(get("Alignment"))), - .threads = 1 - ) - ) -) - -for (i in seq_along(negative_test_cases)) { - # Arrange - test_name <- names(negative_test_cases)[i] - args <- negative_test_cases[[i]][["args"]] - - # Act, Assert - test_that( - test_name, - expect_error(do.call(repClonalFamily, args)) - ) -} diff --git a/tests/testthat/test-clonality.R b/tests/testthat/test-clonality.R deleted file mode 100644 index cf200984..00000000 --- a/tests/testthat/test-clonality.R +++ /dev/null @@ -1,14 +0,0 @@ -for (method in c("clonal.prop", "homeo", "top", "tail")) { - test_name <- paste0("method:", method) - - compute_res <- apply_DF_DT(frame_data, table_data, - repClonality, - .method = method - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) -} diff --git a/tests/testthat/test-distance.R b/tests/testthat/test-distance.R deleted file mode 100644 index c868bb7c..00000000 --- a/tests/testthat/test-distance.R +++ /dev/null @@ -1,71 +0,0 @@ -data(immdata) -short_immdata <- map(immdata$data, ~ .x %>% head(1000)) # smaller sample size saves time in computations - -f <- function(x, y) { - res <- matrix(nrow = length(x), ncol = length(y)) - for (i in seq_along(x)) { - res[i, ] <- abs(nchar(x[i]) - nchar(y)) - } - dimnames(res) <- list(x, y) - return(as.dist(res)) -} - -# Arrange -positive_test_cases <- list( - "Changing method" = list( - args = list( - .data = short_immdata[1], - .method = "lv" - ), - result = c(0, 6, 6, 0) - ), - "Changing column" = list( - args = list( - .data = short_immdata[1], - .col = "CDR3.aa", - .method = "lv" - ), - result = c(0, 6, 6, 0) - ), - "Custom_func" = list(args = list(.data = short_immdata[1], .method = f, .group_by_seqLength = FALSE), result = c(0, 3, 3, 0)), - "Group_by changing" = list(args = list(.data = short_immdata[1], .group_by = "V.name"), result = c(0, 21, 19, 18, 13, 21, 0, 18, 23, 19, 19, 18, 0, 16, 15, 18, 23, 16, 0, 15, 13, 19, 15, 15, 0)) -) - -negative_test_cases <- list( - "Immdata test" = list( - args = list( - .data = immdata - ) - ), - "Wrong col" = list( - args = list( - .data = short_immdata, - .col = "aa" - ) - ), - "Wrong method" = list( - args = list( - .data = short_immdata, - .method = "ddddd" - ), - "Wrong group_by" = list( - args = list( - .data = short_immdata, - .group_by = "ddddd" - ) - ) - ) -) - -# Act -args <- map(positive_test_cases, "args") -results <- map(positive_test_cases, "result") -positive_act_result <- map(args, ~ do.call(seqDist, .x)[[1]][10]) %>% - map(1) %>% - map(., ~ as.matrix(.x) %>% as.numeric()) -positive_test_values <- list(names(positive_test_cases), positive_act_result, results) -negative_args <- map(negative_test_cases, "args") -# Assert -pmap(positive_test_values, ~ test_that(..1, expect_equal(..2, ..3))) -## for negative tests act can be done only with assert -map2(names(negative_test_cases), negative_args, ~ test_that(.x, expect_error(do.call(seqDist, .y)))) diff --git a/tests/testthat/test-diversity.R b/tests/testthat/test-diversity.R deleted file mode 100644 index 55c7cfc3..00000000 --- a/tests/testthat/test-diversity.R +++ /dev/null @@ -1,48 +0,0 @@ -for (column in c("nt", "aa", "nt+v", "aa+v", "aa+v+j")) { - for (method in c("chao1", "hill", "div", "gini.simp", "inv.simp", "gini", "raref", "dxx", "d50")) { - if (method == "raref") { - for (norm_val in c(TRUE, FALSE)) { - test_name <- paste0("method:", method, ":", column, ".norm:", norm_val) - - compute_res <- apply_DF_DT(frame_data, table_data, - repDiversity, - .method = method, .col = column, .verbose = F, .norm = norm_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } - } else if (method == "dxx") { - for (perc_val in c(10, 25, 75)) { - test_name <- paste0("method:", method, ":", column, ".perc:", perc_val) - - compute_res <- apply_DF_DT(frame_data, table_data, - repDiversity, - .method = method, .col = column, .verbose = F, .perc = perc_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } - } else { - test_name <- paste0("method:", method, ":", column) - - compute_res <- apply_DF_DT(frame_data, table_data, - repDiversity, - .method = method, .col = column, .verbose = F - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } - } -} diff --git a/tests/testthat/test-dynamics.R b/tests/testthat/test-dynamics.R deleted file mode 100644 index 8fe12040..00000000 --- a/tests/testthat/test-dynamics.R +++ /dev/null @@ -1,71 +0,0 @@ -#' -#' -#' -#' trackClonotypes <- function (.data, .which = list(1, 15), .col = "aa", .norm = T) { -#' -#' -#' tc = trackClonotypes(immdata$data, list(1, 10), .col = "aa") -#' tc = trackClonotypes(immdata$data, list("MS1", 20), .col = "nt+v") -#' -#' tc = trackClonotypes(immdata$data, c("CASRGLITDTQYF", "CSASRGSPNEQYF"), .col = "aa") -#' -#' target = immdata$data[[1]] %>% select(CDR3.aa, V.name) %>% head(10) -#' tc = trackClonotypes(immdata$data, target) - - -for (norm_val in c(TRUE, FALSE)) { - for (method in list(list(1, 10), list(names(frame_data)[1], 20))) { - for (column in c("nt", "aa", "nt+v", "aa+v", "nt+j", "aa+j", "aa+v+j")) { - test_name <- paste0("method:1.norm:", norm_val, ".column:", column) - - compute_res <- apply_DF_DT(frame_data, table_data, - trackClonotypes, - .which = method, .col = column, .norm = norm_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - } - } - - target <- c("CASSLEETQYF", "CASSDSSGGANEQFF", "CASSLQETQYF", "CASSLDRETQYF", "CASSPGGGNQPQHF") - column <- "aa" - test_name <- paste0("methid:2.norm:", norm_val, ".column:", column) - - compute_res <- apply_DF_DT(frame_data, table_data, - trackClonotypes, - .which = target, .col = column, .norm = norm_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - method_list <- list() - method_list[["nt+v"]] <- immdata$data[[1]] %>% - select(CDR3.nt, V.name) %>% - head(10) - method_list[["aa+v"]] <- immdata$data[[1]] %>% - select(CDR3.aa, V.name) %>% - head(15) - method_list[["nt+v+j"]] <- immdata$data[[1]] %>% - select(CDR3.nt, V.name, J.name) %>% - head(10) - method_list[["aa"]] <- immdata$data[[1]] %>% - select(CDR3.aa) %>% - head(10) - method_list[["nt"]] <- immdata$data[[1]] %>% - select(CDR3.nt) %>% - head(10) - - for (method_name in names(method_list)) { - test_name <- paste0("methid:3.norm:", norm_val, ".which:", method_name) - - compute_res <- apply_DF_DT(frame_data, table_data, - trackClonotypes, - .which = method_list[[method_name]], .col = column, .norm = norm_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - } -} diff --git a/tests/testthat/test-explore.R b/tests/testthat/test-explore.R deleted file mode 100644 index c4f813d0..00000000 --- a/tests/testthat/test-explore.R +++ /dev/null @@ -1,35 +0,0 @@ -for (column in c("nt", "aa", "nt+v", "aa+v", "aa+v+j")) { - for (method in c("volume", "count", "len", "clones")) { - for (coding_val in c(TRUE, FALSE)) { - if (method == "len") { - if (column %in% c("nt", "aa")) { - test_name <- paste0("method:", method, ":", column, ".coding:", coding_val) - - compute_res <- apply_DF_DT(frame_data, table_data, - repExplore, - .method = method, .col = column, .coding = coding_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } - } else { - test_name <- paste0("method:", method, ":", column, ".coding:", coding_val) - - compute_res <- apply_DF_DT(frame_data, table_data, - repExplore, - .method = method, .col = column, .coding = coding_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } - } - } -} diff --git a/tests/testthat/test-filter.R b/tests/testthat/test-filter.R deleted file mode 100644 index 01f48ed1..00000000 --- a/tests/testthat/test-filter.R +++ /dev/null @@ -1,299 +0,0 @@ -test_cases <- list() - -data <- immdata$data -meta <- immdata$meta -original_samples_count <- nrow(meta) - -prepare_immdata <- function() { - return(list(data = data, meta = meta)) -} - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - prepare_immdata() %>% - add_mock_sample("S1", list(Status = "N")) - }, - method = "by.meta", query = list(Status = include("N")), - expected_samples = 1 -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - prepare_immdata() %>% - add_mock_sample("S1", list(Lane = "D")) - }, - method = "by.meta", query = list(Lane = exclude("D")), - expected_samples = original_samples_count -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - prepare_immdata() %>% - add_mock_sample("S1", list(Age = 1)) %>% - add_mock_sample("S2", list(Age = 2)) - }, - method = "by.meta", query = list(Age = lessthan(5)), - expected_samples = 2 -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - prepare_immdata() %>% - add_mock_sample("S1", list(Age = 95)) %>% - add_mock_sample("S2", list(Age = 99)) - }, - method = "by.meta", query = list(Age = interval(95, 100)), - expected_samples = 2 -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - prepare_immdata() %>% - add_mock_sample("S1", list(Age = 100)) - }, - method = "by.meta", query = list(Age = interval(95, 100)), - expected_samples = 0, - expect_warnings = TRUE -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - prepare_immdata() %>% - add_mock_sample("S1", list(Lane = "D")) %>% - add_mock_sample("S2", list(Lane = "E")) - }, - method = "by.meta", query = list(Lane = include("D", "E")), - expected_samples = 2 -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - prepare_immdata() %>% - add_mock_sample("S1", list(Lane = "D")) %>% - add_mock_sample("S2", list(Lane = "E")) - }, - method = "by.meta", query = list(Lane = exclude("D", "E")), - expected_samples = original_samples_count -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - prepare_immdata() %>% - add_mock_sample("S1", list(Lane = "D", Age = 95)) %>% - add_mock_sample("S2", list(Lane = "E", Age = 96)) - }, - method = "by.meta", query = list(Lane = include("D", "E"), Age = morethan(95)), - expected_samples = 1 -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - immdata <- prepare_immdata() %>% - add_mock_sample("S1") - immdata$data[["S1"]] %<>% rbind(immdata$data[["S1"]][rep(1, 10000), ]) - return(immdata) - }, - method = "by.repertoire", query = list(n_clonotypes = morethan(10000)), - expected_samples = 1 -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - immdata <- prepare_immdata() - immdata %<>% add_mock_sample("S1") - immdata$data[["S1"]] <- immdata$data[["S1"]][1, ] - immdata$data[["S1"]][["Clones"]] <- 50 - immdata %<>% add_mock_sample("S2") - immdata$data[["S2"]] <- immdata$data[["S2"]][1:2, ] - immdata$data[["S2"]][1, ][["Clones"]] <- 50 - immdata$data[["S2"]][2, ][["Clones"]] <- 50 - return(immdata) - }, - method = "by.repertoire", query = list(n_clones = lessthan(100)), - expected_samples = 1 -) - -# repeat the last 2 test cases, but abbreviate method as "by.rep" -for (i in 1:2) { - test_cases[[length(test_cases) + 1]] <- test_cases[[length(test_cases) - 1]] - test_cases[[length(test_cases)]][["method"]] <- "by.rep" -} - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - immdata <- prepare_immdata() %>% - add_mock_sample("S1", .empty = TRUE) - immdata$data[["S1"]] %<>% - bind_rows(as.data.frame(list(CDR3.aa = "partial"))) %>% - bind_rows(as.data.frame(list(CDR3.aa = "out_of_frame"))) %>% - bind_rows(as.data.frame(list(CDR3.aa = "other"))) - return(immdata) - }, - method = "by.clonotype", query = list(CDR3.aa = exclude("partial", "out_of_frame")), - expected_samples = original_samples_count + 1, - expected_sample_rows = list(S1 = 1) -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - immdata <- prepare_immdata() %>% - add_mock_sample("S1", .empty = TRUE) - immdata$data[["S1"]] %<>% - bind_rows(as.data.frame(list(Clones = 1000))) %>% - bind_rows(as.data.frame(list(Clones = 1500))) %>% - bind_rows(as.data.frame(list(Clones = 2000))) - return(immdata) - }, - method = "by.clonotype", query = list(Clones = interval(1000, 2000)), - expected_samples = 1, - expected_sample_rows = list(S1 = 2), - expect_warnings = TRUE -) - -mock_genes <- function() { - immdata <- prepare_immdata() %>% - add_mock_sample("S1", .empty = TRUE) - # delete all other samples - immdata$data <- immdata$data[names(immdata$data) == "S1"] - immdata$meta %<>% filter(Sample == "S1") - - immdata$data[["S1"]] %<>% - bind_rows(as.data.frame(list(V.name = "TRBV1"))) %>% - bind_rows(as.data.frame(list(V.name = "TRAV1"))) %>% - bind_rows(as.data.frame(list(V.name = "TRAV2"))) %>% - bind_rows(as.data.frame(list(V.name = "TRAV11"))) - return(immdata) -} - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = mock_genes, - method = "by.clonotype", query = list(V.name = exclude("TRBV1", "TRAV1")), - expected_samples = 1, - expected_sample_rows = list(S1 = 2) -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = mock_genes, - method = "by.clonotype", query = list(V.name = exclude("TRBV1", "TRAV1")), match = "exact", - expected_samples = 1, - expected_sample_rows = list(S1 = 2) -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = mock_genes, - method = "by.clonotype", query = list(V.name = exclude("TRBV1", "TRAV1")), match = "startswith", - expected_samples = 1, - expected_sample_rows = list(S1 = 1) -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = mock_genes, - method = "by.clonotype", query = list(V.name = include("TRBV1", "TRAV1")), match = "startswith", - expected_samples = 1, - expected_sample_rows = list(S1 = 3) -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = mock_genes, - method = "by.clonotype", query = list(CDR3.aa = exclude("DUMMY")), match = "startswith", - expected_samples = mock_genes() %>% .$data %>% length(), - expected_sample_rows = list(S1 = 4) -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = mock_genes, - method = "by.clonotype", query = list(V.name = exclude("V1")), match = "substring", - expected_samples = 1, - expected_sample_rows = list(S1 = 1) -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = mock_genes, - method = "by.clonotype", query = list(V.name = include("V1")), match = "substring", - expected_samples = 1, - expected_sample_rows = list(S1 = 3) -) - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = mock_genes, - method = "by.clonotype", query = list(CDR3.aa = exclude("DUMMY")), match = "substring", - expected_samples = mock_genes() %>% .$data %>% length(), - expected_sample_rows = list(S1 = 4) -) - -# repeat the last 10 test cases, but abbreviate method as "by.cl" -for (i in 1:10) { - test_cases[[length(test_cases) + 1]] <- test_cases[[length(test_cases) - 9]] - test_cases[[length(test_cases)]][["method"]] <- "by.cl" -} - -test_cases[[length(test_cases) + 1]] <- list( - data_factory = function() { - immdata <- prepare_immdata() %>% - add_mock_sample("S1", .empty = TRUE) - immdata$data <- immdata$data[names(immdata$data) == "S1"] - immdata$meta %<>% filter(Sample == "S1") - immdata$data[["S1"]] %<>% - bind_rows(as.data.frame(list(V.name = "TRBV1", J.name = "TRAJ1"))) %>% - bind_rows(as.data.frame(list(V.name = "TRAV1", J.name = "TRAJ11"))) %>% - bind_rows(as.data.frame(list(V.name = "TRAV2", J.name = "TRAJ1"))) %>% - bind_rows(as.data.frame(list(V.name = "TRAV11", J.name = "TRBJ2"))) - return(immdata) - }, - method = "by.clonotype", - query = list(V.name = include("AV1"), J.name = include("AJ")), - match = "substring", - expected_samples = 1, - expected_sample_rows = list(S1 = 1) -) - -for (i in seq_along(test_cases)) { - # Arrange - data_factory <- test_cases[[i]][["data_factory"]] - method <- test_cases[[i]][["method"]] - query <- test_cases[[i]][["query"]] - match <- test_cases[[i]][["match"]] - expected_samples <- test_cases[[i]][["expected_samples"]] - expected_sample_rows <- test_cases[[i]][["expected_sample_rows"]] - # expected_sample_rows is named list, contains sample names and expected rows; - # if not specified, don't check sample rows - if (is.null(expected_sample_rows)) { - expected_sample_rows <- list() - } - expect_warnings <- test_cases[[i]][["expect_warnings"]] - if (is.null(expect_warnings)) { - options(warn = 0) - } else { - options(warn = -1) - } - - test_name <- paste0("method:", method, ".case:", i) - immdata <- data_factory() - frame_with_meta <- immdata - table_with_meta <- list(data = lapply(immdata$data, as.data.table), meta = immdata$meta) - - # Act - if (is.null(match)) { - compute_res <- apply_DF_DT(frame_with_meta, table_with_meta, - repFilter, - .method = method, .query = query - ) - } else { - compute_res <- apply_DF_DT(frame_with_meta, table_with_meta, - repFilter, - .method = method, .query = query, .match = match - ) - } - - # Assert - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]]$data %>% length(), expected_samples) - expect_equal(compute_res[[1]]$meta %>% nrow(), expected_samples) - for (j in seq_along(expected_sample_rows)) { - sample_name <- names(expected_sample_rows)[[j]] - expected_rows <- expected_sample_rows[[j]] - expect_equal(compute_res[[1]]$data[[sample_name]] %>% nrow(), expected_rows) - } - expect_equal(lapply(compute_res[[1]]$data, as.data.table), compute_res[[2]]$data) - }) -} diff --git a/tests/testthat/test-geneusage.R b/tests/testthat/test-geneusage.R deleted file mode 100644 index 1ef289cc..00000000 --- a/tests/testthat/test-geneusage.R +++ /dev/null @@ -1,17 +0,0 @@ -for (quant in c(NA, "count")) { - for (type in c("segment", "allele", "family")) { - for (ambig in c("inc", "exc", "maj")) { - for (norm_val in c(TRUE, FALSE)) { - test_name <- paste0("quant:", quant, "_type:", type, "_ambig:", ambig, "_norm:", norm_val) - - compute_res <- apply_DF_DT(frame_data, table_data, - geneUsage, - .quant = quant, .ambig = ambig, .type = type, .norm = norm_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - } - } - } -} diff --git a/tests/testthat/test-germline.R b/tests/testthat/test-germline.R deleted file mode 100644 index 124ddd62..00000000 --- a/tests/testthat/test-germline.R +++ /dev/null @@ -1,76 +0,0 @@ -data(bcrdata) -test_bcr_data <- bcrdata$data %>% top(1000) - -positive_test_cases <- list( - "Not empty result" = list( - args = list( - .data = test_bcr_data, - .threads = 1 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result[["full_clones"]]) > 0, TRUE) - } - ), - "Multiple threads" = list( - args = list( - .data = test_bcr_data - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result[["full_clones"]]) > 0, TRUE) - } - ), - "Dataframe only" = list( - args = list( - .data = test_bcr_data[["full_clones"]], - .threads = 1 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result) > 0, TRUE) - } - ) -) - -for (i in seq_along(positive_test_cases)) { - # Arrange - test_name <- names(positive_test_cases)[i] - args <- positive_test_cases[[i]][["args"]] - assert_function <- positive_test_cases[[i]][["assert_function"]] - - # Act - result <- suppressWarnings(do.call(repGermline, args)) - - # Assert - test_that( - test_name, - assert_function(result) - ) -} - -negative_test_cases <- list( - "List of lists" = list( - args = list( - .data = bcrdata - ) - ), - "Missing column" = list( - args = list( - .data = subset(test_bcr_data[["full_clones"]], select = -c(get("FR1.nt"))), - .threads = 1 - ) - ) -) - -for (i in seq_along(negative_test_cases)) { - # Arrange - test_name <- names(negative_test_cases)[i] - args <- negative_test_cases[[i]][["args"]] - - # Act, Assert - test_that( - test_name, - expect_error(suppressWarnings(do.call(repGermline, args))) - ) -} diff --git a/tests/testthat/test-kmers.R b/tests/testthat/test-kmers.R deleted file mode 100644 index 3c32fd19..00000000 --- a/tests/testthat/test-kmers.R +++ /dev/null @@ -1,36 +0,0 @@ -for (coding_val in c(TRUE, FALSE)) { - for (k_size in c(1, 3, 5, 10)) { - for (column in c("nt", "aa")) { - test_name <- paste0("kmer:", k_size, ":", column, ".coding:", coding_val) - - compute_res <- apply_DF_DT(frame_data[[1]], table_data[[1]], - getKmers, - .k = k_size, .col = column, .coding = coding_val - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - - if (column == "aa") { - for (method in c("freq", "prob", "wei", "self")) { - for (remove_stop in c(TRUE, FALSE)) { - test_name <- paste0("kmer:", k_size, ".method:", method, ".stop:", remove_stop, ".coding:", coding_val) - - profile_res1 <- kmer_profile(compute_res[[1]], .method = method, .remove.stop = remove_stop) - profile_res2 <- kmer_profile(compute_res[[2]], .method = method, .remove.stop = remove_stop) - - test_that(ap(test_name, "compute_"), { - expect_equal(profile_res1, profile_res2) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } - } - } - } - } -} diff --git a/tests/testthat/test-overlap.R b/tests/testthat/test-overlap.R deleted file mode 100644 index a6619953..00000000 --- a/tests/testthat/test-overlap.R +++ /dev/null @@ -1,16 +0,0 @@ -for (column in c("nt", "aa", "nt+v", "aa+v", "aa+v+j")) { - for (method in c("public", "overlap", "jaccard", "tversky", "cosine", "morisita", "inc+public", "inc+jaccard", "inc+morisita")) { - test_name <- paste0("method:", method, ":", column) - - compute_res <- apply_DF_DT(frame_data, table_data, - repOverlap, - .method = method, .col = column, .verbose = F, .verbose.inc = F - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } -} diff --git a/tests/testthat/test-pubrep.R b/tests/testthat/test-pubrep.R deleted file mode 100644 index e2b3bab6..00000000 --- a/tests/testthat/test-pubrep.R +++ /dev/null @@ -1,22 +0,0 @@ -for (column in c("nt", "aa", "nt+v", "aa+v", "nt+j", "aa+j", "aa+v+j")) { - for (quant in c("count", "prop")) { - for (coding_val in c(TRUE, FALSE)) { - for (min_samples in c(1, 3)) { - for (max_samples in c(5, NA)) { - test_name <- paste0("column:", column, ".quant:", quant, ".coding:", coding_val, ".min:", min_samples, ".max:", max_samples) - - compute_res <- apply_DF_DT(frame_data, table_data, - pubRep, - .col = column, .quant = quant, .coding = coding_val, .min.samples = min_samples, .max.samples = max_samples, .verbose = F - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } - } - } - } -} diff --git a/tests/testthat/test-seqCluster.R b/tests/testthat/test-seqCluster.R deleted file mode 100644 index ccdae7a6..00000000 --- a/tests/testthat/test-seqCluster.R +++ /dev/null @@ -1,48 +0,0 @@ -data(immdata) - -dist_test <- seqDist(immdata$data[1]) - - -# Arrange - -negative_test_cases <- list( - "Wrong data" = list( - args = list( - .data = immdata[1:2], - .dist = dist_test - ) - ), - "No matching col" = list( - args = list( - .data = immdata$data[[1]] %>% mutate("CDR3.nt" = NULL), - .dist = dist_test - ) - ), - "Wrong samples" = list( - args = list( - .data = immdata$data[3], - .dist = dist_test - ) - ), - "Multiple thresholds" = list( - args = list( - .data = immdata$data[1], - .dist = dist_test, - .fixed_threshold = 10, - .nt_similarity = 3 - ) - ), - "No thresholds" = list( - args = list( - .data = immdata$data[1], - .dist = dist_test, - .fixed_threshold = NULL - ) - ) -) - -negative_args <- map(negative_test_cases, "args") - -# Act, Assert - -map2(names(negative_test_cases), negative_args, ~ test_that(.x, expect_error(do.call(seqCluster, .y)))) diff --git a/tests/testthat/test-somatic-hypermutation.R b/tests/testthat/test-somatic-hypermutation.R deleted file mode 100644 index 74aac8f5..00000000 --- a/tests/testthat/test-somatic-hypermutation.R +++ /dev/null @@ -1,95 +0,0 @@ -data(bcrdata) -test_bcr_data <- bcrdata$data %>% top(1000) -test_input <- test_bcr_data %>% - seqCluster(seqDist(test_bcr_data), .fixed_threshold = 3) %>% - repGermline(.threads = 1) %>% - repAlignLineage(.min_lineage_sequences = 2, .prepare_threads = 1, .align_threads = 1) %>% - repClonalFamily(.threads = 1) %>% - suppressWarnings() - -positive_test_cases <- list( - "Not empty result" = list( - args = list( - .data = test_input, - .threads = 1 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result[["full_clones"]]) > 0, TRUE) - } - ), - "Multiple threads" = list( - args = list( - .data = test_input, - .threads = 8 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result[["full_clones"]]) > 0, TRUE) - } - ), - "Dataframe only" = list( - args = list( - .data = test_input[["full_clones"]], - .threads = 1 - ), - assert_function = function(result) { - expect_equal(immunarch:::has_no_data(result), FALSE) - expect_equal(nrow(result) > 0, TRUE) - } - ) -) - -for (i in seq_along(positive_test_cases)) { - # Arrange - test_name <- names(positive_test_cases)[i] - args <- positive_test_cases[[i]][["args"]] - assert_function <- positive_test_cases[[i]][["assert_function"]] - - # Act - result <- do.call(repSomaticHypermutation, args) - - # Assert - test_that( - test_name, - assert_function(result) - ) -} - -negative_test_cases <- list( - "List of lists" = list( - args = list( - .data = bcrdata - ) - ), - "Missing columns" = list( - args = list( - .data = test_bcr_data[["full_clones"]], - .threads = 1 - ) - ), - "Missing Sequences column" = list( - args = list( - .data = subset(test_input[["full_clones"]], select = -c(get("Sequences"))), - .threads = 1 - ) - ), - "Missing Germline.Input column" = list( - args = list( - .data = subset(test_input[["full_clones"]], select = -c(get("Germline.Input"))), - .threads = 1 - ) - ) -) - -for (i in seq_along(negative_test_cases)) { - # Arrange - test_name <- names(negative_test_cases)[i] - args <- negative_test_cases[[i]][["args"]] - - # Act, Assert - test_that( - test_name, - expect_error(do.call(repSomaticHypermutation, args)) - ) -} diff --git a/tests/testthat/test-spectr.R b/tests/testthat/test-spectr.R deleted file mode 100644 index ef41c108..00000000 --- a/tests/testthat/test-spectr.R +++ /dev/null @@ -1,16 +0,0 @@ -for (column in c("nt", "aa", "nt+v", "aa+v", "nt+j", "aa+j")) { - for (quant in c("id", "count")) { - test_name <- paste0("quant:", quant, ":", column) - - compute_res <- apply_DF_DT(frame_data[[1]], table_data[[1]], - spectratype, - .quant = quant, .col = column - ) - test_that(ap(test_name, "compute_"), { - expect_equal(compute_res[[1]], compute_res[[2]]) - }) - - # vis_res = vis_results(compute_res) - # test_that(ap(test_name, "vis_"), { expect_equal(vis_res[[1]], vis_res[[2]]) }) - } -} From a53242eec494f8ca128e571fe0bb0ca98833bffb Mon Sep 17 00:00:00 2001 From: Vadim Nazarov <2979713+vadimnazarov@users.noreply.github.com> Date: Thu, 9 Oct 2025 23:48:49 +0200 Subject: [PATCH 36/36] fix: CRAN fixes --- .Rbuildignore | 1 + DESCRIPTION | 2 +- R/aaa-registry.R | 4 +-- R/v0_annotation.R | 2 +- R/v1_airr_clonality.R | 28 +++++++-------- R/v1_airr_diversity.R | 38 ++++++++++---------- R/v1_airr_public.R | 10 +++--- R/v1_airr_stats.R | 14 ++++---- R/v1_annotate_clonality.R | 16 ++++----- README.md | 2 +- man/airr_clonality.Rd | 28 +++++++-------- man/airr_diversity.Rd | 38 ++++++++++---------- man/airr_public.Rd | 10 +++--- man/airr_stats.Rd | 14 ++++---- man/annotate_clonality.Rd | 16 ++++----- man/dbLoad.Rd | 2 +- man/register_immunarch_method.Rd | 4 +-- vignettes/immunarch.Rmd | 61 ++------------------------------ 18 files changed, 117 insertions(+), 173 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 012bf463..2b42f0ac 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -27,3 +27,4 @@ ^wip-.* ^vignettes/articles$ ^vignettes/.quarto$ +^CRAN-SUBMISSION$ diff --git a/DESCRIPTION b/DESCRIPTION index ad020e0a..0123266b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -18,7 +18,7 @@ Description: A comprehensive analytics framework for building reproducible pipel clonality/diversity, V(D)J usage, similarity, annotation, tracking, and many more. Think Scanpy or Seurat, but for AIRR data, a.k.a. Adaptive Immune Receptor Repertoire, VDJ-seq, RepSeq, or VDJ sequencing data. A successor to our previously published "tcR" R package (Nazarov 2015). -License: Apache License (== 2.0) +License: Apache License (>= 2.0) URL: https://immunomind.github.io/docs/, https://github.com/immunomind/immunarch BugReports: https://github.com/immunomind/immunarch/issues Depends: diff --git a/R/aaa-registry.R b/R/aaa-registry.R index 140dcd98..10c6f1bf 100644 --- a/R/aaa-registry.R +++ b/R/aaa-registry.R @@ -115,7 +115,7 @@ im_method <- function(core, family, name, required_cols = NULL, need_repertoires #' #' ## What your core must look like #' * Signature: `function(idata, ...)` -#' * **Must not** declare `autojoin`, `format`, or `features` — these are added by the wrapper. +#' * **Must not** declare `autojoin`, `format`, or `features` - these are added by the wrapper. #' #' ## What the wrapper adds #' * Common args from `im_common_args()`: `autojoin`, `format`, `features` @@ -138,7 +138,7 @@ im_method <- function(core, family, name, required_cols = NULL, need_repertoires #' @param need_repertoires Logical. Use this to declare the necessity of having aggregated #' repertoires. #' -#' @return A **function** — the user-facing wrapper around `core`. Typical usage is to +#' @return A **function** - the user-facing wrapper around `core`. Typical usage is to #' assign it to the exported symbol of the method, e.g.: #' `airr_stats_lengths <- register_immunarch_method(...)`. #' diff --git a/R/v0_annotation.R b/R/v0_annotation.R index 99170735..1c90d389 100644 --- a/R/v0_annotation.R +++ b/R/v0_annotation.R @@ -21,7 +21,7 @@ if (getRversion() >= "2.15.1") { #' #' VDJDB - #' -#' McPAS-TCR - +#' McPAS-TCR - #' #' TBAdb from PIRD - #' diff --git a/R/v1_airr_clonality.R b/R/v1_airr_clonality.R index 2f47b578..7b011f30 100644 --- a/R/v1_airr_clonality.R +++ b/R/v1_airr_clonality.R @@ -1,4 +1,4 @@ -#' @title Clonality — receptor overabundance statistics for immune repertoires +#' @title Clonality - receptor overabundance statistics for immune repertoires #' #' @description #' `r lifecycle::badge("experimental")` @@ -59,20 +59,20 @@ airr_clonality_line_impl <- function(idata, limit = 100000) { } -#' @description `airr_clonality_line` — build ranked abundance lines: for each +#' @description `airr_clonality_line` - build ranked abundance lines: for each #' repertoire, take the top `limit` receptors by `count` and attach repertoire -#' metadata. Useful for per-repertoire rank–abundance plots. +#' metadata. Useful for per-repertoire rank-abundance plots. #' -#' @param limit Positive integer ≥ 10: maximum number of top receptors to keep +#' @param limit Positive integer >= 10: maximum number of top receptors to keep #' **per repertoire** (default `100000`). #' #' @return #' #' ## `airr_clonality_line` #' A tibble with columns: -#' * `repertoire_id` — repertoire identifier -#' * `index` — rank within repertoire (1 = most abundant) -#' * `count` — receptor count used for ranking +#' * `repertoire_id` - repertoire identifier +#' * `index` - rank within repertoire (1 = most abundant) +#' * `count` - receptor count used for ranking #' * plus any repertoire metadata columns carried from `idata$repertoires` #' #' @examples @@ -109,7 +109,7 @@ airr_clonality_rank_impl <- function(idata, } -#' @description `airr_clonality_rank` — aggregate clonal space by **rank bins**. +#' @description `airr_clonality_rank` - aggregate clonal space by **rank bins**. #' Receptors are ordered by `proportion` within each repertoire; each receptor #' is assigned to the smallest threshold in `bins` that contains its rank. #' @@ -122,8 +122,8 @@ airr_clonality_rank_impl <- function(idata, #' ## `airr_clonality_rank` #' A tibble with #' * `repertoire_id` -#' * `clonal_rank_bin` — the rank threshold (e.g., `10`, `100`, …) -#' * `occupied_prop` — sum of `proportion` within the bin +#' * `clonal_rank_bin` - the rank threshold (e.g., `10`, `100`, ...) +#' * `occupied_prop` - sum of `proportion` within the bin #' * plus repertoire metadata columns from `idata$repertoires` #' #' @examples @@ -166,9 +166,9 @@ airr_clonality_prop_impl <- function( } -#' @description `airr_clonality_prop` — aggregate clonal space by **proportion bins**. +#' @description `airr_clonality_prop` - aggregate clonal space by **proportion bins**. #' Each receptor is assigned to a named bin according to its `proportion` -#' (e.g., `Hyperexpanded ≥ 1e-2`, `Large ≥ 1e-3`, …). Thresholds are matched in +#' (e.g., `Hyperexpanded >= 1e-2`, `Large >= 1e-3`, ...). Thresholds are matched in #' descending order; unmatched receptors fall into `"Ultra-rare"`. #' #' @param bins A **named** numeric vector of thresholds (e.g., @@ -180,8 +180,8 @@ airr_clonality_prop_impl <- function( #' ## `airr_clonality_prop` #' A tibble with #' * `repertoire_id` -#' * `clonal_prop_bin` — factor-like label from `names(bins)` or `"Ultra-rare"` -#' * `occupied_prop` — sum of `proportion` within the bin +#' * `clonal_prop_bin` - factor-like label from `names(bins)` or `"Ultra-rare"` +#' * `occupied_prop` - sum of `proportion` within the bin #' * plus repertoire metadata columns from `idata$repertoires` #' #' @examples diff --git a/R/v1_airr_diversity.R b/R/v1_airr_diversity.R index da0b01da..02a7d52b 100644 --- a/R/v1_airr_diversity.R +++ b/R/v1_airr_diversity.R @@ -1,4 +1,4 @@ -#' @title Diversity — estimating the heterogeneity of immune repertoires +#' @title Diversity - estimating the heterogeneity of immune repertoires #' #' @description #' `r lifecycle::badge("experimental")` @@ -79,7 +79,7 @@ airr_diversity_dxx_impl <- function(idata, perc = 50) { } -#' @description `airr_diversity_dxx` — **coverage diversity**: minimal number of +#' @description `airr_diversity_dxx` - **coverage diversity**: minimal number of #' top receptors needed to reach `perc%` of clonal space (by `proportion`). #' Great for spotting dominance/overexpansion and for quick, interpretable dashboards #' (e.g., D50 = receptors to cover half of the repertoire). @@ -93,7 +93,7 @@ airr_diversity_dxx_impl <- function(idata, perc = 50) { #' A tibble with: #' * `imd_repertoire_id` #' * `perc` -#' * `dxx` — minimal count of top receptors to reach `perc%` +#' * `dxx` - minimal count of top receptors to reach `perc%` #' * plus repertoire metadata from `idata$repertoires` #' #' @examples @@ -132,7 +132,7 @@ airr_diversity_chao1_impl <- function(idata) { collect() } -#' @description `airr_diversity_chao1` — Chao1 estimator is a nonparameteric +#' @description `airr_diversity_chao1` - Chao1 estimator is a nonparameteric #' asymptotic estimator of species richness (number of species in a population). #' One of the most used methods for estimating immune repertoire diversity. #' @@ -141,10 +141,10 @@ airr_diversity_chao1_impl <- function(idata) { #' ## `airr_diversity_chao1` #' A tibble with: #' * `imd_repertoire_id` -#' * `Estimator` — number of species -#' * `SD` — standard deviation for the estimator value -#' * `Conf.95.lo` — CI 0.025 -#' * `Conf.95.hi` — CI 0.975 +#' * `Estimator` - number of species +#' * `SD` - standard deviation for the estimator value +#' * `Conf.95.lo` - CI 0.025 +#' * `Conf.95.hi` - CI 0.975 #' * plus repertoire metadata from `idata$repertoires` #' #' @examples @@ -179,7 +179,7 @@ airr_diversity_shannon_impl <- function(idata) { } -#' @description `airr_diversity_shannon` — Shannon entropy (base 2) per repertoire +#' @description `airr_diversity_shannon` - Shannon entropy (base 2) per repertoire #' computed from `proportion`. Ideal when you want a single evenness-aware #' diversity score; pair with Pielou/Hill for samples with very different richness. #' @@ -188,7 +188,7 @@ airr_diversity_shannon_impl <- function(idata) { #' ## `airr_diversity_shannon` #' A tibble with: #' * `imd_repertoire_id` -#' * `shannon` — entropy in bits +#' * `shannon` - entropy in bits #' #' @examples #' # @@ -216,8 +216,8 @@ airr_diversity_pielou_impl <- function(idata) { } -#' @description `airr_diversity_pielou` — Pielou’s evenness `H / log2(S)` with -#' richness `S`. Best when you need a **size-normalized** evenness score that’s +#' @description `airr_diversity_pielou` - Pielou's evenness `H / log2(S)` with +#' richness `S`. Best when you need a **size-normalized** evenness score that's #' comparable across repertoires with different receptor counts. #' #' @return @@ -227,7 +227,7 @@ airr_diversity_pielou_impl <- function(idata) { #' * `imd_repertoire_id` #' * `shannon` #' * `n_receptors` -#' * `pielou` — evenness in `[0, 1]` (NA if `S ≤ 1`) +#' * `pielou` - evenness in `[0, 1]` (NA if `S <= 1`) #' #' @examples #' # @@ -247,9 +247,9 @@ airr_diversity_index_impl <- function(idata) { } -#' @description `airr_diversity_index` — convenience alias for Hill number with +#' @description `airr_diversity_index` - convenience alias for Hill number with #' `q = 1` (`exp(Shannon)` using natural log). A solid **default single metric** -#' that’s relatively robust to rare-count noise and easy to compare across samples. +#' that's relatively robust to rare-count noise and easy to compare across samples. #' #' @return #' @@ -327,8 +327,8 @@ airr_diversity_hill_impl <- function(idata, q = 0:5) { } -#' @description `airr_diversity_hill` — Hill numbers (“true diversity”) for -#' orders `q ∈ {0, 1, 2, …}`: `q=0` richness, `q=1` exp(Shannon), `q>1` +#' @description `airr_diversity_hill` - Hill numbers ("true diversity") for +#' orders `q \eqn{\in}{in} {0, 1, 2, ...}`: `q=0` richness, `q=1` exp(Shannon), `q>1` #' emphasizes abundant receptors. Perfect when you want a **diversity profile** #' that tunes sensitivity to rare vs. abundant clonotypes. #' @@ -340,8 +340,8 @@ airr_diversity_hill_impl <- function(idata, q = 0:5) { #' ## `airr_diversity_hill` #' A tibble with: #' * `imd_repertoire_id` -#' * `q` — Hill order -#' * `hill_number` — true diversity of order `q` +#' * `q` - Hill order +#' * `hill_number` - true diversity of order `q` #' * plus repertoire metadata from `idata$repertoires` #' #' @examples diff --git a/R/v1_airr_public.R b/R/v1_airr_public.R index 7e4a619e..1eb65992 100644 --- a/R/v1_airr_public.R +++ b/R/v1_airr_public.R @@ -1,4 +1,4 @@ -#' @title Public indices — pairwise repertoire overlap +#' @title Public indices - pairwise repertoire overlap #' #' @description #' `r lifecycle::badge("experimental")` @@ -54,9 +54,9 @@ airr_public_intersection_impl <- function(idata) { result_matrix } -#' @description `airr_public_intersection` — number of **shared receptors** between +#' @description `airr_public_intersection` - number of **shared receptors** between #' each pair of repertoires (intersection size). Handy for quick overlap heatmaps, -#' QC of replicate similarity, or spotting donor-shared “public” clonotypes. +#' QC of replicate similarity, or spotting donor-shared "public" clonotypes. #' #' @return #' @@ -119,8 +119,8 @@ airr_public_jaccard_impl <- function(idata) { } -#' @description `airr_public_jaccard` — **Jaccard similarity** of receptor -#' sets between repertoires (`|A∩B| / |A∪B|`). Best when comparing cohorts with +#' @description `airr_public_jaccard` - **Jaccard similarity** of receptor +#' sets between repertoires (\eqn{A \cap B}{A cap B} / \eqn{A \cup B}{A cup B}). Best when comparing cohorts with #' different sizes to get a scale-invariant overlap score. #' #' @inheritParams im_common_args diff --git a/R/v1_airr_stats.R b/R/v1_airr_stats.R index ce4ffbcf..feac3bee 100644 --- a/R/v1_airr_stats.R +++ b/R/v1_airr_stats.R @@ -83,7 +83,7 @@ airr_stats_chains_impl <- function(idata, locus_col = NA) { #' #' ## `airr_stats_chains` Returns a tibble with columns: #' * `repertoire_id` -- repertoire identifier -#' * `locus` -- TRA, TRB, IGH … (present only if `locus_col` is supplied) +#' * `locus` -- TRA, TRB, IGH, ... (present only if `locus_col` is supplied) #' * `n_chains` -- number of chains #' #' @examples @@ -178,7 +178,7 @@ airr_stats_genes_impl <- function(idata, gene_col = "v_call", level = c("recepto collect() } -#' @description `airr_stats_genes` — count V(D)J gene segments per repertoire, +#' @description `airr_stats_genes` - count V(D)J gene segments per repertoire, #' optionally split by locus and using either receptor counts or barcode/UMI #' counts as the measure. Profiles V/D/J gene usage to characterize repertoire #' composition and germline biases, with optional locus split. Useful for @@ -201,11 +201,11 @@ airr_stats_genes_impl <- function(idata, gene_col = "v_call", level = c("recepto #' @return #' #' ## `airr_stats_genes` A tibble with columns: -#' * `repertoire_id` — repertoire identifier -#' * *(optional)* `locus` — TRA, TRB, IGH … (present only when `by = "locus"` +#' * `repertoire_id` - repertoire identifier +#' * *(optional)* `locus` - TRA, TRB, IGH, ... (present only when `by = "locus"` #' and the locus column exists) -#' * `` — the gene segment value (e.g., V gene) -#' * `n` — the measure: +#' * `` - the gene segment value (e.g., V gene) +#' * `n` - the measure: #' - if `level = "receptor"`: number of receptors carrying the gene segment #' - if `level = "barcode"`: sum of counts across receptors for the segment #' @@ -219,7 +219,7 @@ airr_stats_genes_impl <- function(idata, gene_col = "v_call", level = c("recepto #' # V gene usage by summed cell/UMI counts (if a count column is present) #' airr_stats_genes(immdata, gene_col = "v_call", level = "barcode") #' -#' # Split by locus (TRA/TRB/… if locus column exists) +#' # Split by locus (TRA/TRB/... if locus column exists) #' airr_stats_genes(immdata, gene_col = "v_call", level = "receptor", by = "locus") #' #' @rdname airr_stats diff --git a/R/v1_annotate_clonality.R b/R/v1_annotate_clonality.R index f7091fa5..73a0452b 100644 --- a/R/v1_annotate_clonality.R +++ b/R/v1_annotate_clonality.R @@ -1,4 +1,4 @@ -#' @title Annotate clonality — per-receptor labels for overabundance +#' @title Annotate clonality - per-receptor labels for overabundance #' #' @description #' `r lifecycle::badge("experimental")` @@ -7,8 +7,8 @@ #' an [immundata::ImmunData] object. #' #' ## Available functions -#' * `annotate_clonality_rank()` — label by **rank bins** within each repertoire. -#' * `annotate_clonality_prop()` — label by **proportion bins** (named thresholds). +#' * `annotate_clonality_rank()` - label by **rank bins** within each repertoire. +#' * `annotate_clonality_prop()` - label by **proportion bins** (named thresholds). #' #' @param idata An [immundata::ImmunData] object. #' @inheritParams im_common_args @@ -53,15 +53,15 @@ annotate_clonality_rank_impl <- function(idata, #' @description -#' `annotate_clonality_rank()` — for each repertoire, receptors are ordered by +#' `annotate_clonality_rank()` - for each repertoire, receptors are ordered by #' within-repertoire abundance (proportion) and assigned a **rank bin** label. #' #' @inheritParams airr_clonality_rank #' #' @return #' An [immundata::ImmunData] whose `$annotations` gains: -#' * `clonal_rank_bin` — integer-like label with the applied rank threshold -#' (outside all thresholds → `NA`). +#' * `clonal_rank_bin` - integer-like label with the applied rank threshold +#' (outside all thresholds -> `NA`). #' #' @rdname annotate_clonality #' @concept Clonality @@ -104,14 +104,14 @@ annotate_clonality_prop_impl <- function( #' @description -#' `annotate_clonality_prop()` — label each receptor by **proportion bin** +#' `annotate_clonality_prop()` - label each receptor by **proportion bin** #' using named thresholds (matched in descending order; else `"Ultra-rare"`). #' #' @inheritParams airr_clonality_prop #' #' @return #' An [immundata::ImmunData] whose `$annotations` gains: -#' * `clonal_prop_bin` — label from `names(bins)` or `"Ultra-rare"`. +#' * `clonal_prop_bin` - label from `names(bins)` or `"Ultra-rare"`. #' #' @rdname annotate_clonality #' @concept Clonality diff --git a/README.md b/README.md index 99acacfb..2acccc21 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@

Tutorials | - API reference + API reference | Ecosystem | diff --git a/man/airr_clonality.Rd b/man/airr_clonality.Rd index 81174230..4ee7aa34 100644 --- a/man/airr_clonality.Rd +++ b/man/airr_clonality.Rd @@ -5,7 +5,7 @@ \alias{airr_clonality_line} \alias{airr_clonality_rank} \alias{airr_clonality_prop} -\title{Clonality — receptor overabundance statistics for immune repertoires} +\title{Clonality - receptor overabundance statistics for immune repertoires} \usage{ airr_clonality_line( idata, @@ -32,7 +32,7 @@ airr_clonality_prop( \arguments{ \item{idata}{An \code{ImmunData} object.} -\item{limit}{Positive integer ≥ 10: maximum number of top receptors to keep +\item{limit}{Positive integer >= 10: maximum number of top receptors to keep \strong{per repertoire} (default \code{100000}).} \item{autojoin}{Logical. If TRUE, join repertoire metadata by the schema repertoire id. @@ -51,9 +51,9 @@ must be non-empty. Internally sorted in descending order.} A tibble with columns: \itemize{ -\item \code{repertoire_id} — repertoire identifier -\item \code{index} — rank within repertoire (1 = most abundant) -\item \code{count} — receptor count used for ranking +\item \code{repertoire_id} - repertoire identifier +\item \code{index} - rank within repertoire (1 = most abundant) +\item \code{count} - receptor count used for ranking \item plus any repertoire metadata columns carried from \code{idata$repertoires} } } @@ -63,8 +63,8 @@ A tibble with columns: A tibble with \itemize{ \item \code{repertoire_id} -\item \code{clonal_rank_bin} — the rank threshold (e.g., \code{10}, \code{100}, …) -\item \code{occupied_prop} — sum of \code{proportion} within the bin +\item \code{clonal_rank_bin} - the rank threshold (e.g., \code{10}, \code{100}, ...) +\item \code{occupied_prop} - sum of \code{proportion} within the bin \item plus repertoire metadata columns from \code{idata$repertoires} } } @@ -74,8 +74,8 @@ A tibble with A tibble with \itemize{ \item \code{repertoire_id} -\item \code{clonal_prop_bin} — factor-like label from \code{names(bins)} or \code{"Ultra-rare"} -\item \code{occupied_prop} — sum of \code{proportion} within the bin +\item \code{clonal_prop_bin} - factor-like label from \code{names(bins)} or \code{"Ultra-rare"} +\item \code{occupied_prop} - sum of \code{proportion} within the bin \item plus repertoire metadata columns from \code{idata$repertoires} } } @@ -89,17 +89,17 @@ A family of functions to quantify \strong{receptor overabundance} per repertoire Supported methods are the following. } -\code{airr_clonality_line} — build ranked abundance lines: for each +\code{airr_clonality_line} - build ranked abundance lines: for each repertoire, take the top \code{limit} receptors by \code{count} and attach repertoire -metadata. Useful for per-repertoire rank–abundance plots. +metadata. Useful for per-repertoire rank-abundance plots. -\code{airr_clonality_rank} — aggregate clonal space by \strong{rank bins}. +\code{airr_clonality_rank} - aggregate clonal space by \strong{rank bins}. Receptors are ordered by \code{proportion} within each repertoire; each receptor is assigned to the smallest threshold in \code{bins} that contains its rank. -\code{airr_clonality_prop} — aggregate clonal space by \strong{proportion bins}. +\code{airr_clonality_prop} - aggregate clonal space by \strong{proportion bins}. Each receptor is assigned to a named bin according to its \code{proportion} -(e.g., \verb{Hyperexpanded ≥ 1e-2}, \verb{Large ≥ 1e-3}, …). Thresholds are matched in +(e.g., \code{Hyperexpanded >= 1e-2}, \code{Large >= 1e-3}, ...). Thresholds are matched in descending order; unmatched receptors fall into \code{"Ultra-rare"}. } \examples{ diff --git a/man/airr_diversity.Rd b/man/airr_diversity.Rd index b73dccf2..f6e7b710 100644 --- a/man/airr_diversity.Rd +++ b/man/airr_diversity.Rd @@ -8,7 +8,7 @@ \alias{airr_diversity_pielou} \alias{airr_diversity_index} \alias{airr_diversity_hill} -\title{Diversity — estimating the heterogeneity of immune repertoires} +\title{Diversity - estimating the heterogeneity of immune repertoires} \usage{ airr_diversity_dxx( idata, @@ -70,7 +70,7 @@ A tibble with: \itemize{ \item \code{imd_repertoire_id} \item \code{perc} -\item \code{dxx} — minimal count of top receptors to reach \verb{perc\%} +\item \code{dxx} - minimal count of top receptors to reach \verb{perc\%} \item plus repertoire metadata from \code{idata$repertoires} } } @@ -80,10 +80,10 @@ A tibble with: A tibble with: \itemize{ \item \code{imd_repertoire_id} -\item \code{Estimator} — number of species -\item \code{SD} — standard deviation for the estimator value -\item \code{Conf.95.lo} — CI 0.025 -\item \code{Conf.95.hi} — CI 0.975 +\item \code{Estimator} - number of species +\item \code{SD} - standard deviation for the estimator value +\item \code{Conf.95.lo} - CI 0.025 +\item \code{Conf.95.hi} - CI 0.975 \item plus repertoire metadata from \code{idata$repertoires} } } @@ -93,7 +93,7 @@ A tibble with: A tibble with: \itemize{ \item \code{imd_repertoire_id} -\item \code{shannon} — entropy in bits +\item \code{shannon} - entropy in bits } } @@ -104,7 +104,7 @@ A tibble with: \item \code{imd_repertoire_id} \item \code{shannon} \item \code{n_receptors} -\item \code{pielou} — evenness in \verb{[0, 1]} (NA if \verb{S ≤ 1}) +\item \code{pielou} - evenness in \verb{[0, 1]} (NA if \code{S <= 1}) } } @@ -124,8 +124,8 @@ A tibble with: A tibble with: \itemize{ \item \code{imd_repertoire_id} -\item \code{q} — Hill order -\item \code{hill_number} — true diversity of order \code{q} +\item \code{q} - Hill order +\item \code{hill_number} - true diversity of order \code{q} \item plus repertoire metadata from \code{idata$repertoires} } } @@ -139,29 +139,29 @@ A family of functions to quantify \strong{receptor diversity} per repertoire. A Supported methods are the following. } -\code{airr_diversity_dxx} — \strong{coverage diversity}: minimal number of +\code{airr_diversity_dxx} - \strong{coverage diversity}: minimal number of top receptors needed to reach \verb{perc\%} of clonal space (by \code{proportion}). Great for spotting dominance/overexpansion and for quick, interpretable dashboards (e.g., D50 = receptors to cover half of the repertoire). -\code{airr_diversity_chao1} — Chao1 estimator is a nonparameteric +\code{airr_diversity_chao1} - Chao1 estimator is a nonparameteric asymptotic estimator of species richness (number of species in a population). One of the most used methods for estimating immune repertoire diversity. -\code{airr_diversity_shannon} — Shannon entropy (base 2) per repertoire +\code{airr_diversity_shannon} - Shannon entropy (base 2) per repertoire computed from \code{proportion}. Ideal when you want a single evenness-aware diversity score; pair with Pielou/Hill for samples with very different richness. -\code{airr_diversity_pielou} — Pielou’s evenness \code{H / log2(S)} with -richness \code{S}. Best when you need a \strong{size-normalized} evenness score that’s +\code{airr_diversity_pielou} - Pielou's evenness \code{H / log2(S)} with +richness \code{S}. Best when you need a \strong{size-normalized} evenness score that's comparable across repertoires with different receptor counts. -\code{airr_diversity_index} — convenience alias for Hill number with +\code{airr_diversity_index} - convenience alias for Hill number with \code{q = 1} (\code{exp(Shannon)} using natural log). A solid \strong{default single metric} -that’s relatively robust to rare-count noise and easy to compare across samples. +that's relatively robust to rare-count noise and easy to compare across samples. -\code{airr_diversity_hill} — Hill numbers (“true diversity”) for -orders \verb{q ∈ \{0, 1, 2, …\}}: \code{q=0} richness, \code{q=1} exp(Shannon), \code{q>1} +\code{airr_diversity_hill} - Hill numbers ("true diversity") for +orders \verb{q \eqn{\in}{in} \{0, 1, 2, ...\}}: \code{q=0} richness, \code{q=1} exp(Shannon), \code{q>1} emphasizes abundant receptors. Perfect when you want a \strong{diversity profile} that tunes sensitivity to rare vs. abundant clonotypes. } diff --git a/man/airr_public.Rd b/man/airr_public.Rd index 3ce4d64d..f6cde9c2 100644 --- a/man/airr_public.Rd +++ b/man/airr_public.Rd @@ -4,7 +4,7 @@ \alias{airr_public} \alias{airr_public_intersection} \alias{airr_public_jaccard} -\title{Public indices — pairwise repertoire overlap} +\title{Public indices - pairwise repertoire overlap} \usage{ airr_public_intersection( idata, @@ -52,12 +52,12 @@ A family of functions to quantify \strong{public or shared receptors} between re Supported methods are the following. } -\code{airr_public_intersection} — number of \strong{shared receptors} between +\code{airr_public_intersection} - number of \strong{shared receptors} between each pair of repertoires (intersection size). Handy for quick overlap heatmaps, -QC of replicate similarity, or spotting donor-shared “public” clonotypes. +QC of replicate similarity, or spotting donor-shared "public" clonotypes. -\code{airr_public_jaccard} — \strong{Jaccard similarity} of receptor -sets between repertoires (\verb{|A∩B| / |A∪B|}). Best when comparing cohorts with +\code{airr_public_jaccard} - \strong{Jaccard similarity} of receptor +sets between repertoires (\eqn{A \cap B}{A cap B} / \eqn{A \cup B}{A cup B}). Best when comparing cohorts with different sizes to get a scale-invariant overlap score. } \examples{ diff --git a/man/airr_stats.Rd b/man/airr_stats.Rd index 9ad793f6..b3bba5b1 100644 --- a/man/airr_stats.Rd +++ b/man/airr_stats.Rd @@ -65,7 +65,7 @@ split is ignored.} \subsection{\code{airr_stats_chains} Returns a tibble with columns:}{ \itemize{ \item \code{repertoire_id} -- repertoire identifier -\item \code{locus} -- TRA, TRB, IGH … (present only if \code{locus_col} is supplied) +\item \code{locus} -- TRA, TRB, IGH, ... (present only if \code{locus_col} is supplied) \item \code{n_chains} -- number of chains } } @@ -80,11 +80,11 @@ split is ignored.} \subsection{\code{airr_stats_genes} A tibble with columns:}{ \itemize{ -\item \code{repertoire_id} — repertoire identifier -\item \emph{(optional)} \code{locus} — TRA, TRB, IGH … (present only when \code{by = "locus"} +\item \code{repertoire_id} - repertoire identifier +\item \emph{(optional)} \code{locus} - TRA, TRB, IGH, ... (present only when \code{by = "locus"} and the locus column exists) -\item \verb{} — the gene segment value (e.g., V gene) -\item \code{n} — the measure: +\item \verb{} - the gene segment value (e.g., V gene) +\item \code{n} - the measure: \itemize{ \item if \code{level = "receptor"}: number of receptors carrying the gene segment \item if \code{level = "barcode"}: sum of counts across receptors for the segment @@ -113,7 +113,7 @@ fingerprint of repertoire prep and selection. Helpful for detecting primer/UMI biases, comparing cohorts, and deriving length-based features for models. -\code{airr_stats_genes} — count V(D)J gene segments per repertoire, +\code{airr_stats_genes} - count V(D)J gene segments per repertoire, optionally split by locus and using either receptor counts or barcode/UMI counts as the measure. Profiles V/D/J gene usage to characterize repertoire composition and germline biases, with optional locus split. Useful for @@ -143,7 +143,7 @@ airr_stats_genes(immdata, gene_col = "v_call", level = "receptor") # V gene usage by summed cell/UMI counts (if a count column is present) airr_stats_genes(immdata, gene_col = "v_call", level = "barcode") -# Split by locus (TRA/TRB/… if locus column exists) +# Split by locus (TRA/TRB/... if locus column exists) airr_stats_genes(immdata, gene_col = "v_call", level = "receptor", by = "locus") } diff --git a/man/annotate_clonality.Rd b/man/annotate_clonality.Rd index 1a39b0f0..be815b2c 100644 --- a/man/annotate_clonality.Rd +++ b/man/annotate_clonality.Rd @@ -4,7 +4,7 @@ \alias{annotate_clonality} \alias{annotate_clonality_rank} \alias{annotate_clonality_prop} -\title{Annotate clonality — per-receptor labels for overabundance} +\title{Annotate clonality - per-receptor labels for overabundance} \usage{ annotate_clonality_rank( idata, @@ -38,13 +38,13 @@ with each row corresponding to a specific repertoire / pair of repertoires; usef \value{ An \link[immundata:ImmunData]{immundata::ImmunData} whose \verb{$annotations} gains: \itemize{ -\item \code{clonal_rank_bin} — integer-like label with the applied rank threshold -(outside all thresholds → \code{NA}). +\item \code{clonal_rank_bin} - integer-like label with the applied rank threshold +(outside all thresholds -> \code{NA}). } An \link[immundata:ImmunData]{immundata::ImmunData} whose \verb{$annotations} gains: \itemize{ -\item \code{clonal_prop_bin} — label from \code{names(bins)} or \code{"Ultra-rare"}. +\item \code{clonal_prop_bin} - label from \code{names(bins)} or \code{"Ultra-rare"}. } } \description{ @@ -54,15 +54,15 @@ A small family of helpers that \strong{add clonality labels to each receptor} in an \link[immundata:ImmunData]{immundata::ImmunData} object. \subsection{Available functions}{ \itemize{ -\item \code{annotate_clonality_rank()} — label by \strong{rank bins} within each repertoire. -\item \code{annotate_clonality_prop()} — label by \strong{proportion bins} (named thresholds). +\item \code{annotate_clonality_rank()} - label by \strong{rank bins} within each repertoire. +\item \code{annotate_clonality_prop()} - label by \strong{proportion bins} (named thresholds). } } -\code{annotate_clonality_rank()} — for each repertoire, receptors are ordered by +\code{annotate_clonality_rank()} - for each repertoire, receptors are ordered by within-repertoire abundance (proportion) and assigned a \strong{rank bin} label. -\code{annotate_clonality_prop()} — label each receptor by \strong{proportion bin} +\code{annotate_clonality_prop()} - label each receptor by \strong{proportion bin} using named thresholds (matched in descending order; else \code{"Ultra-rare"}). } \examples{ diff --git a/man/dbLoad.Rd b/man/dbLoad.Rd index 88b3c41a..f3c5f988 100644 --- a/man/dbLoad.Rd +++ b/man/dbLoad.Rd @@ -38,7 +38,7 @@ Currently we support three popular databases: VDJDB - \url{https://github.com/antigenomics/vdjdb-db} -McPAS-TCR - \url{http://friedmanlab.weizmann.ac.il/McPAS-TCR/} +McPAS-TCR - \url{https://friedmanlab.weizmann.ac.il/McPAS-TCR/} TBAdb from PIRD - \url{https://db.cngb.org/pird/} } diff --git a/man/register_immunarch_method.Rd b/man/register_immunarch_method.Rd index 275be471..a76dc663 100644 --- a/man/register_immunarch_method.Rd +++ b/man/register_immunarch_method.Rd @@ -32,7 +32,7 @@ the family environment by calling \code{register_airr_family()} when available.} repertoires.} } \value{ -A \strong{function} — the user-facing wrapper around \code{core}. Typical usage is to +A \strong{function} - the user-facing wrapper around \code{core}. Typical usage is to assign it to the exported symbol of the method, e.g.: \code{airr_stats_lengths <- register_immunarch_method(...)}. } @@ -46,7 +46,7 @@ arguments} and \strong{runs safety checks} so your core stays minimal. \subsection{What your core must look like}{ \itemize{ \item Signature: \verb{function(idata, ...)} -\item \strong{Must not} declare \code{autojoin}, \code{format}, or \code{features} — these are added by the wrapper. +\item \strong{Must not} declare \code{autojoin}, \code{format}, or \code{features} - these are added by the wrapper. } } diff --git a/vignettes/immunarch.Rmd b/vignettes/immunarch.Rmd index db75e0fe..4617b0f2 100644 --- a/vignettes/immunarch.Rmd +++ b/vignettes/immunarch.Rmd @@ -9,62 +9,7 @@ output: html_document %\VignettePackage{immunarch} --> -

-

🧬 immunarch --- Multi-modal immune repertoire analysis in R

-
- ---- - - - -

- Tutorials - | - API reference - | - Ecosystem - | - Publication (coming soon...) -

- ---- +# 🧬 immunarch – Multi-modal immune repertoire analysis in R `immunarch` brings a comprehensive analytics toolkit to build reproducible analysis pipelines for Adaptive Immune Receptor Repertoire (AIRR) data with a particular focus on designing personalized immunotherapies and vaccines. Key features are: @@ -189,9 +134,7 @@ airr_diversity_pielou(immdata) # Use your own data by reading sample files from the metadata file mdtable <- read_metadata("data/metadata.csv") immdata <- read_repertoires("", metadata = mdtable) -``` -```r eval=FALSE # Use your own data by reading sample files directly mdtable <- read_metadata("data/metadata.csv") immdata <- read_repertoires("data/*.tsv.gz", metadata = mdtable) @@ -246,7 +189,7 @@ We are always open to contributions. There are three ways to contribute: 2. Create an issue or find one [here](https://github.com/immunomind/immunarch/issues), fork the repository and make a pull request with the bugfix or improvement. -3. Find an existing issue and help others. +3. Find an existing issue and help others resolve this. ## 🏷 About