Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ..Rcheck/00check.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
* using log directory ‘/Users/bianjh/Documents/Projects/Development/SCOT/..Rcheck’
* using R version 4.5.1 (2025-06-13)
* using platform: aarch64-apple-darwin20
* R was compiled by
Apple clang version 16.0.0 (clang-1600.0.26.6)
GNU Fortran (GCC) 14.2.0
* running under: macOS Tahoe 26.4.1
* using session charset: UTF-8
* checking for file ‘./DESCRIPTION’ ... ERROR
Required fields missing or empty:
‘Author’ ‘Maintainer’
* DONE
Status: 1 ERROR
86 changes: 12 additions & 74 deletions CITATION.cff

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ Config/testthat/edition: 3
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.3
Config/roxygen2/version: 8.0.0
63 changes: 39 additions & 24 deletions R/convert_human_gene_list.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,44 @@
#' @export
#'
#' @return Character vector of mapped mouse genes
convert_human_gene_list <- function(genes) {
# data variables must be initialized to silence the R CMD check note:
# 'no visible binding for global variable'
gns <- NULL
convert_human_gene_list <- function(genes = NULL) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this function currently only supports mouse -> human perhaps the name should reflect that. in the future we can add a more generic function that handles any-to-any genome.

Suggested change
convert_human_gene_list <- function(genes = NULL) {
convert_mouse_to_human_gene_list <- function(genes = NULL) {

result <- character(0)

# TODO: make this function generic enough to convert any genome to any other
egs <- AnnotationDbi::mapIds(
org.Hs.eg.db::org.Hs.eg.db,
gns,
"ENTREZID",
"SYMBOL"
)
mapped <- AnnotationDbi::select(
Orthology.eg.db::Orthology.eg.db,
egs,
"Mus.musculus",
"Homo.sapiens"
)
mapped$MUS <- AnnotationDbi::mapIds(
org.Mm.eg.db::org.Mm.eg.db,
as.character(mapped$Mus.musculus),
"SYMBOL",
"ENTREZID"
)
return(as.character(unlist(mapped$MUS)))
# Validate input: must be character vector
if (!is.character(genes)) {
stop(paste0(
"Input 'genes' must be a character vector, not ",
paste(class(genes), collapse = " ")
))
} else if (length(genes) == 0L) {
warning("Input 'genes' is empty; returning character(0)")
} else {
# Map human SYMBOL to ENTREZID
egs <- AnnotationDbi::mapIds(
org.Hs.eg.db::org.Hs.eg.db,
genes,
"ENTREZID",
"SYMBOL"
)

# Map human ENTREZID to mouse ENTREZID
mapped <- AnnotationDbi::select(
Orthology.eg.db::Orthology.eg.db,
as.character(egs),
"Mus.musculus",
"Homo.sapiens"
)

# Map mouse ENTREZID to SYMBOL
mapped$MUS <- AnnotationDbi::mapIds(
org.Mm.eg.db::org.Mm.eg.db,
as.character(mapped$Mus.musculus),
"SYMBOL",
"ENTREZID"
)

result <- as.character(unlist(mapped$MUS))
}

return(result)
}
25 changes: 14 additions & 11 deletions R/make_volcano_plot.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#' differential expression table generated by Seurat
#'
#' @param de_table Differential expression table generated by Seurat containing
#' p_val, pct.1, pct.2 avg_log2FC and p_val_adj
#' p_val, pct.1, pct.2 avg_log_2_fc and p_val_adj
#' @param logfc Boolean to color genes meeting logfc threshold of 1.5
#' @param pval Boolean to color genes meeting p-value threshold of 0.05
#' @param significant Boolean to color genes that meet both logfc and p-value
Expand All @@ -26,33 +26,36 @@ make_volcano_plot <- function(
) {
log10_p <- -log10(de_table$p_val_adj)
log10_p[which(de_table$p_val_adj == 0)] <- 500
avg_log2FC <- de_table$avg_log2FC
avg_log_2_fc <- de_table$avg_log_2_fc
gene <- rownames(de_table)
significance <- vector(length = length(log10_p))
significance[] <- "NotSignificant"
if (logfc == TRUE) {
significance[which(abs(de_table$avg_log2FC) > 1.5)] <- "avg_log2FC > 1.5"
significance[which(
abs(de_table$avg_log_2_fc) > 1.5
)] <- "avg_log_2_fc > 1.5"
}
if (isTRUE(pval)) {
significance[which(de_table$p_val_adj < 0.05)] <- "p_val_adj < 0.05"
}
if (isTRUE(significant)) {
significance[which(
abs(de_table$avg_log2FC) > 1.5 &
abs(de_table$avg_log_2_fc) > 1.5 &
de_table$p_val_adj < 0.05
)] <- "p_val_adj < 0.05 & avg_log2FC > 1.5"
)] <- "p_val_adj < 0.05 & avg_log_2_fc > 1.5"
}
df <- as.data.frame(cbind(avg_log2FC, log10_p, significance, gene))
df <- as.data.frame(cbind(avg_log_2_fc, log10_p, significance, gene))
colnames(df) <- c("avg_log_2_fc", "log10_p", "significance", "gene")
rownames(df) <- rownames(de_table)
df[, 1] <- as.numeric(df[, 1])
df[, 2] <- as.numeric(df[, 2])
df[, 3] <- factor(
df[, 3],
levels = c(
"NotSignificant",
"avg_log2FC > 1.5",
"avg_log_2_fc > 1.5",
"p_val_adj < 0.05",
"p_val_adj < 0.05 & avg_log2FC > 1.5"
"p_val_adj < 0.05 & avg_log_2_fc > 1.5"
)
)
data_subset <- NULL
Expand All @@ -68,13 +71,13 @@ make_volcano_plot <- function(

volcano <- ggplot2::ggplot(
df,
ggplot2::aes(x = avg_log2FC, y = log10_p, col = significance)
ggplot2::aes(x = avg_log_2_fc, y = log10_p, col = significance)
) +
ggplot2::geom_point() +
# geom_vline(xintercept = 0, color = "black", linewidth = 1.5)+
ggplot2::xlim(
-ceiling(max(abs(df$avg_log2FC))),
ceiling(max(abs(df$avg_log2FC)))
-ceiling(max(abs(df$avg_log_2_fc))),
ceiling(max(abs(df$avg_log_2_fc)))
)

if (!is.null(data_subset)) {
Expand Down
23 changes: 21 additions & 2 deletions R/seurat_clustering.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@
#' @return The updated Seurat single cell object with recalculated PCA,
#' neighbors, UMAP and clusters
seurat_clustering <- function(so_in, npcs_in, resolution = 0.8, algorithm = 3) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should consider renaming this function to a verb. see https://style.tidyverse.org/functions.html @wong-nw

# Validate npcs_in: must be a positive integer >= 3 (for UMAP n.components)
if (!is.numeric(npcs_in) || npcs_in != as.integer(npcs_in) || npcs_in <= 0) {
rlang::abort("npcs_in must be a positive integer")
}

if (npcs_in < 3) {
rlang::abort("npcs_in must be at least 3 for UMAP computation")
}

# Validate resolution: must be positive
if (!is.numeric(resolution) || resolution <= 0) {
rlang::abort("resolution must be a positive numeric value")
}

# Validate algorithm: must be 1, 2, or 3
if (!is.numeric(algorithm) || !(algorithm %in% c(1, 2, 3))) {
rlang::abort("algorithm must be 1 (Louvain), 2 (Leiden), or 3 (SLM)")
}

Comment on lines +18 to +36

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice input validation!

so <- Seurat::RunPCA(
object = so_in,
features = Seurat::VariableFeatures(object = so_in),
Expand All @@ -24,8 +43,8 @@ seurat_clustering <- function(so_in, npcs_in, resolution = 0.8, algorithm = 3) {
so <- Seurat::FindNeighbors(so, dims = 1:npcs_in)
so <- Seurat::FindClusters(
so,
resolution = 0.8,
algorithm = 3,
resolution = resolution,
algorithm = algorithm,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch! using parameters is important

verbose = TRUE
)
so <- Seurat::RunUMAP(so, dims = 1:npcs_in, n.components = 3)
Expand Down
7 changes: 0 additions & 7 deletions R/split_featurePlot.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ split_featurePlot <- function(
) {
plot_list <- list()
plot_output <- list()
if (is.null(reduction)) {
embed <- so@reductions[[SeuratObject::DefaultDimReduc(so)]]@cell.embeddings
} else {
embed <- Seurat::Embeddings(so, reduction = reduction)
}

# TODO refactor with map or lapply
for (feature in features) {
Expand All @@ -61,8 +56,6 @@ split_featurePlot <- function(
order = order,
reduction = reduction
) +
ggplot2::xlim(range(embed[, 1])) +
ggplot2::ylim(range(embed[, 2])) +
ggplot2::ggtitle(ident)
}
}
Expand Down
1 change: 1 addition & 0 deletions man/SCOT-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/convert_human_gene_list.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/make_volcano_plot.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/reexports.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Loading