Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add conditional print method for objects that contain alternative experiments #89

Open
wants to merge 148 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 103 commits
Commits
Show all changes
148 commits
Select commit Hold shift + click to select a range
5ac207e
test change print_method.R
Biomiha Aug 23, 2023
c1db700
Update print_method.R
Biomiha Aug 23, 2023
5a5b71b
Update print_method.R
Biomiha Aug 23, 2023
67a48f0
Update print_method.R
Biomiha Aug 23, 2023
430cdff
Update print_method.R
Biomiha Aug 27, 2023
5aaba6a
Update print_method.R
Biomiha Aug 28, 2023
672ef06
Update print_method.R
Biomiha Aug 28, 2023
af9204b
Update print_method.R
Biomiha Aug 28, 2023
a8f1bb2
Update print_method.R
Biomiha Aug 28, 2023
97dfdc9
Update print_method.R
Biomiha Aug 28, 2023
7f41b60
Update print_method.R
Biomiha Aug 28, 2023
d4d45c4
Update print_method.R
Biomiha Aug 28, 2023
ec37354
Update print_method.R
Biomiha Aug 29, 2023
4344098
Update print_method.R
Biomiha Aug 29, 2023
bef9d3a
Update print_method.R
Biomiha Aug 29, 2023
fd1c9bd
Update print_method.R
Biomiha Aug 29, 2023
5dbdd24
Update test-methods.R
Biomiha Aug 29, 2023
8dbb158
Update test-methods.R
Biomiha Aug 29, 2023
6a9d4f6
Update test-methods.R
Biomiha Aug 30, 2023
41b2844
Update utilities.R
Biomiha Sep 1, 2023
1e93081
Update utilities.R
Biomiha Sep 2, 2023
65bda14
Update utilities.R
Biomiha Sep 9, 2023
b4e3665
Update methods.R
Biomiha Sep 9, 2023
79c2001
Update methods.R
Biomiha Sep 9, 2023
6bd2829
Update methods.R
Biomiha Sep 9, 2023
a68f140
Update test-methods.R
Biomiha Sep 9, 2023
b6334a0
Update utilities.R
Biomiha Sep 9, 2023
f860dd5
Merge branch 'master' into altExp_methods
Biomiha Sep 9, 2023
a3596a1
Update utilities.R
Biomiha Sep 27, 2023
06ff606
Update utilities.R
Biomiha Sep 27, 2023
6c9d669
Update utilities.R
Biomiha Sep 27, 2023
263d481
Update utilities.R
Biomiha Sep 27, 2023
86ce152
Update methods.R
Biomiha Sep 27, 2023
3b94f11
Update methods.R
Biomiha Sep 27, 2023
5859139
Update utilities.R
Biomiha Sep 27, 2023
fb08e11
Update utilities.R
Biomiha Sep 27, 2023
5287d24
Update utilities.R
Biomiha Sep 27, 2023
b8bb0a4
Update methods.R
Biomiha Sep 27, 2023
33c8ab5
Update methods.R
Biomiha Sep 27, 2023
0d8f2ce
Update methods.R
Biomiha Sep 27, 2023
6d1b241
Update methods.R
Biomiha Sep 27, 2023
da5545d
Update methods.R
Biomiha Sep 27, 2023
1024f9e
Update utilities.R
Biomiha Sep 27, 2023
d31fd7a
Update methods.R
Biomiha Sep 27, 2023
d018a60
Update utilities.R
Biomiha Sep 27, 2023
5956947
Update utilities.R
Biomiha Sep 27, 2023
d3be263
Update methods.R
Biomiha Sep 27, 2023
ab81fb0
Update methods.R
Biomiha Sep 27, 2023
eafe321
Update methods.R
Biomiha Sep 27, 2023
e39791f
Update methods.R
Biomiha Sep 27, 2023
0cea6fe
Update utilities.R
Biomiha Sep 27, 2023
3fa4f8d
Update utilities.R
Biomiha Sep 27, 2023
3d3db34
Update methods.R
Biomiha Sep 27, 2023
7091049
Update utilities.R
Biomiha Sep 27, 2023
2d7673a
Update utilities.R
Biomiha Sep 27, 2023
e64de6e
Update methods.R
Biomiha Sep 27, 2023
19c65f6
Update utilities.R
Biomiha Sep 27, 2023
e97ee07
Update utilities.R
Biomiha Sep 27, 2023
4fa5053
Update dplyr_methods.R
Biomiha Sep 27, 2023
ca7b27b
Update dplyr_methods.R
Biomiha Sep 27, 2023
203e1f2
Update utilities.R
Biomiha Sep 27, 2023
8fe1ee2
Update utilities.R
Biomiha Sep 27, 2023
6493ad9
Update methods.R
Biomiha Sep 29, 2023
5a64c2d
Update utilities.R
Biomiha Sep 29, 2023
ca20f90
Update methods.R
Biomiha Sep 29, 2023
ed0400e
Update methods.R
Biomiha Sep 30, 2023
376b260
Update methods.R
Biomiha Sep 30, 2023
1c8a03d
Update methods.R
Biomiha Sep 30, 2023
7c774bf
Update methods.R
Biomiha Sep 30, 2023
a2cf4ab
Update utilities.R
Biomiha Oct 1, 2023
8df074a
Update utilities.R
Biomiha Oct 1, 2023
8965104
Update test-methods.R
Biomiha Oct 1, 2023
fe2ca4e
Update test-methods.R
Biomiha Oct 1, 2023
e678767
Update methods.R
Biomiha Oct 1, 2023
5dfc7be
Update methods.R
Biomiha Oct 1, 2023
2050f5d
Merge branch 'stemangiola:master' into altExp_methods
Biomiha Oct 19, 2023
2b908a2
Update utilities.R
Biomiha Oct 19, 2023
8e0501c
Update utilities.R
Biomiha Oct 19, 2023
830529f
Update utilities.R
Biomiha Oct 19, 2023
d89e38f
Update utilities.R
Biomiha Oct 20, 2023
2600e46
Update utilities.R
Biomiha Oct 20, 2023
3272e66
Update utilities.R
Biomiha Oct 20, 2023
347d0cf
Update utilities.R
Biomiha Oct 20, 2023
4f6f1cb
Update utilities.R
Biomiha Oct 20, 2023
fc4351b
Update utilities.R
Biomiha Oct 20, 2023
a7dd8af
Update utilities.R
Biomiha Oct 20, 2023
8d46133
Update methods.R
Biomiha Oct 23, 2023
608d85b
Update methods.R
Biomiha Oct 23, 2023
9ea6dce
Update methods.R
Biomiha Oct 23, 2023
4bf0c59
Update methods.R
Biomiha Oct 25, 2023
93e517d
Update methods.R
Biomiha Oct 25, 2023
2a4ea90
Update methods.R
Biomiha Oct 25, 2023
34047d3
Update methods.R
Biomiha Oct 26, 2023
5c62b25
Update methods.R
Biomiha Oct 27, 2023
a7f2046
Update methods.R
Biomiha Oct 27, 2023
4797b81
Update methods.R
Biomiha Oct 27, 2023
2fb771a
Update methods.R
Biomiha Oct 29, 2023
cd53a86
Update test-methods.R
Biomiha Oct 29, 2023
a8dc2a8
Update methods.R
Biomiha Oct 31, 2023
6df2a39
Update methods.R
Biomiha Oct 31, 2023
61c18d7
Update methods.R
Biomiha Oct 31, 2023
f400720
Update methods.R
Biomiha Oct 31, 2023
d1e9ebc
Update methods.R
Biomiha Oct 31, 2023
94fc572
Update methods.R
Biomiha Nov 1, 2023
de152a3
Update utilities.R
Biomiha Nov 2, 2023
4107221
Update utilities.R
Biomiha Nov 2, 2023
c7f84c4
Update methods.R
Biomiha Nov 2, 2023
5b82e36
Update utilities.R
Biomiha Nov 2, 2023
e363132
Update utilities.R
Biomiha Nov 2, 2023
5002180
Update methods.R
Biomiha Nov 2, 2023
98a5584
Update introduction.Rmd
Biomiha Nov 2, 2023
a592c71
Update introduction.Rmd
Biomiha Nov 2, 2023
06aa1ec
Update methods.R
Biomiha Nov 3, 2023
8776694
Update methods.R
Biomiha Nov 3, 2023
462a9b5
Update introduction.Rmd
Biomiha Nov 3, 2023
aa97269
Update methods.R
Biomiha Nov 3, 2023
767b2b5
Update methods.R
Biomiha Nov 3, 2023
8c0e87a
Update test-ggplotly_methods.R
Biomiha Nov 3, 2023
8aede5a
Update test-methods.R
Biomiha Nov 9, 2023
858828d
Update plotly_methods.R
Biomiha Nov 9, 2023
550c3b4
Update plotly_methods.R
Biomiha Nov 12, 2023
b5c5f43
Merge branch 'master' into altExp_methods
Biomiha Nov 12, 2023
c68e190
Merge branch 'master' into rebase-solve-conflicts
stemangiola Dec 6, 2023
961e442
Merge plot_ly to work
Biomiha Jan 1, 2024
d26e02a
Merge pull request #1 from stemangiola/rebase-solve-conflicts
Biomiha Jan 1, 2024
e269004
delete unnecessary plot
Biomiha Jan 1, 2024
7013e1c
Merge branch 'master' into altExp_methods
Biomiha Jan 1, 2024
a641911
add error handling in yaml
Biomiha Jan 1, 2024
2ad486a
add CMD check
Biomiha Jan 1, 2024
4be74fc
Update methods.R
Biomiha Jan 3, 2024
3fe42a9
Minor bug fixes to utilities
Biomiha Feb 3, 2024
443fda8
Replace deprecated function `when` with if else statements
Biomiha Feb 4, 2024
124ddd6
Update methods.R
Biomiha Feb 4, 2024
27b7623
Update utilities.R
Biomiha Feb 4, 2024
0b2d328
Sync abundance functions with master repo
Biomiha Feb 4, 2024
5593de0
Sync with master repo
Biomiha Feb 4, 2024
86734ba
Correct variables_genes issue
Biomiha Feb 4, 2024
6e9a84a
Sync with master repo
Biomiha Feb 4, 2024
e1624fe
Sync with master repo
Biomiha Feb 4, 2024
faf5fe0
Merge branch 'master' into altExp_methods
Biomiha Feb 4, 2024
222aeea
Correct unique features
Biomiha Feb 4, 2024
d1ce30f
Can it pass checks?
Biomiha Feb 6, 2024
ec24c7a
Merge branch 'stemangiola:master' into altExp_methods
Biomiha Feb 11, 2024
ace24f7
Add files via upload
Biomiha Feb 11, 2024
7ea1982
Remove MASS import requirement
Biomiha Feb 11, 2024
6ee25e3
Add n_extra desc
Biomiha Feb 11, 2024
aac9c73
Update tibble_methods.R
Biomiha Feb 18, 2024
27059cc
testthat methods
Biomiha Feb 18, 2024
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
260 changes: 168 additions & 92 deletions R/methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,25 @@ setMethod("join_features", "SingleCellExperiment", function(.data,
# CRAN Note
.cell <- NULL
.feature <- NULL

arg_list <- c(mget(ls(environment(), sorted=F)), match.call(expand.dots=F)$...)
all_assays <- get_all_assays(.data)$assay_id
if(is.null(arg_list$assays)) assays_from_join_call <- all_assays
# Shape is long
if (shape == "long") {

# Suppress generic data frame creation message produced by left_join
suppressMessages({
.data <-
.data %>%
left_join(
by=c_(.data)$name,
get_abundance_sc_long(
.data=.data,
features=features,
all=all,
exclude_zeros=exclude_zeros)) %>%
select(!!c_(.data)$symbol, .feature,
contains(".abundance"), everything())
.data <-
.data %>%
left_join(
by=c_(.data)$name,
get_abundance_sc_long(
.data=.data,
features=features,
all=all,
exclude_zeros=exclude_zeros,
...)) %>%
select(!!c_(.data)$symbol, .feature,
contains(".abundance"), everything())
})

# Provide data frame creation and abundance column message
Expand All @@ -79,14 +81,16 @@ setMethod("join_features", "SingleCellExperiment", function(.data,
.data

# Shape if wide
} else {
} else if (shape == "wide"){
if(is.null(arg_list$assays)) stop("Please provide assays")
.data %>%
left_join(
by=c_(.data)$name,
get_abundance_sc_wide(
.data=.data,
features=features,
all=all, ...))
all=all,
...))
}
})

Expand Down Expand Up @@ -138,86 +142,158 @@ tidy.SingleCellExperiment <- function(object) {
#' @importFrom SummarizedExperiment assays assays<- assayNames
#' @importFrom S4Vectors split
#' @importFrom stringr str_remove
#' @importFrom dplyr group_split
#' @importFrom dplyr full_join
#' @importFrom dplyr left_join
#' @importFrom dplyr group_by
#' @importFrom dplyr pick
#' @importFrom dplyr group_rows
#' @importFrom dplyr group_keys
#' @importFrom dplyr bind_rows
#' @importFrom dplyr pull
#' @importFrom tidyr unite
#' @importFrom tidyr separate
#' @importFrom purrr reduce
#' @importFrom purrr map
#' @importFrom purrr set_names
#' @importFrom purrr list_transpose
#'
#'
#' @export
setMethod("aggregate_cells", "SingleCellExperiment", function(.data,
.sample=NULL, slot="data", assays=NULL,
aggregation_function=Matrix::rowSums,
...) {

# Fix NOTEs
feature <- NULL
.sample <- enquo(.sample)

# Subset only wanted assays
if (!is.null(assays)) {
assays(.data) <- assays(.data)[assays]
}
setMethod("aggregate_cells", "SingleCellExperiment", function(.data,
.sample = NULL, assays = NULL,
aggregation_function = Matrix::rowSums,
...) {
# Fix NOTEs
feature <- NULL
.sample <- enquo(.sample)

arg_list <- c(mget(ls(environment(), sorted = F)), match.call(expand.dots = F)$...)
assays_to_use <- eval(arg_list$assays)
if (is.null(assays_to_use)) assays_to_use <- tail(names(assays(.data)), n = 1)

sample_groups <- .data |>
as_tibble() |>
group_by(pick({{ .sample }}))

sample_group_idx <- sample_groups |>
group_rows()

sample_group_keys <- sample_groups |>
group_keys()

grouping_factor =
.data |>
colData() |>
as_tibble() |>
select(!!.sample) |>
suppressMessages() |>
unite("my_id_to_split_by___", !!.sample, sep = "___") |>
pull(my_id_to_split_by___) |>
as.factor()

list_count_cells = table(grouping_factor) |> as.list()

# New method
list_assays =
.data |>
assays() |>
as.list() |>
map(~ .x |> splitColData(grouping_factor)) |>
unlist(recursive=FALSE)

list_assays =
list_assays |>
map2(names(list_assays), ~ {
# Get counts
.x %>%
aggregation_function(na.rm=TRUE) %>%
enframe(
name =".feature",
value="x") %>% # sprintf("%s", .y)) %>%

# In case we don't have rownames
mutate(.feature=as.character(.feature))
}) |>
enframe(name = ".sample") |>

# Clean groups
mutate(assay_name = assayNames(!!.data) |> rep(each=length(levels(grouping_factor)))) |>
mutate(.sample = .sample |> str_remove(assay_name) |> str_remove("\\.")) |>
group_split(.sample) |>
map(~ .x |> unnest(value) |> pivot_wider(names_from = assay_name, values_from = x) ) |>

# Add cell count
map2(
list_count_cells,
~ .x |> mutate(.aggregated_cells = .y)
)


do.call(rbind, list_assays) |>

left_join(
.data |>
colData() |>
as_tibble() |>
subset(!!.sample) |>
unite("my_id_to_split_by___", !!.sample, remove=FALSE, sep = "___"),
by= join_by(".sample" == "my_id_to_split_by___")
) |>

as_SummarizedExperiment(
.sample=.sample,
.transcript=.feature,
.abundance=!!as.symbol(names(.data@assays)))
.sample_names <- colnames(sample_group_keys)

grouping_factor_names <- sample_group_keys |>
unite(col = "grouping_factor", !!.sample, sep = "___") |>
pull(grouping_factor)

sce_split <- map(.x = seq_along(sample_group_idx), .f = \(.num) .data[, sample_group_idx[[.num]]]) |>
purrr::set_names(grouping_factor_names)

grouping_factor <-
.data |>
colData() |>
as_tibble() |>
select(!!.sample) |>
suppressMessages() |>
unite("my_id_to_split_by___", !!.sample, sep = "___") |>
pull(my_id_to_split_by___) |>
as.factor()

list_count_cells <- table(grouping_factor) |>
enframe(name = "grouping_factor", value = ".aggregated_cells") |>
mutate(.aggregated_cells = as.integer(.aggregated_cells))

feature_df <- get_all_features(.data)
selected_features <- feature_df[feature_df$assay_id %in% assays_to_use, ]
selected_experiments_list <- split(x = selected_features, f = as.character(selected_features$exp_id))
if ("Main" %in% names(selected_experiments_list)) selected_experiments_list <- selected_experiments_list[c("Main", setdiff(names(selected_experiments_list), "Main"))]

aggregate_assays_fun <- function(exp) {
selected_exp <- unique(exp$exp_id)
selected_assays <- exp |> distinct(assay_name, .keep_all = TRUE)
if (selected_exp == "Main") {
aggregate_sce_fun <- function(sce) {
aggregated_vals <- assays(sce)[selected_assays$assay_name] |>
as.list() |>
map(.f = \(.list) aggregation_function(.list))
map(.x = seq_along(aggregated_vals), \(.num) enframe(x = aggregated_vals[[.num]], name = ".feature", value = selected_assays$assay_id[[.num]])) |>
suppressMessages(reduce(full_join))
}
aggregated_list <- lapply(sce_split, aggregate_sce_fun) |>
purrr::list_transpose() |>
map(.f = \(.list) .list |> bind_rows(.id = "grouping_factor"))
interim_res <- map(.x = seq_along(aggregated_list), .f = \(.num) aggregated_list[[.num]] |>
separate(col = grouping_factor, into = .sample_names, sep = "___")) |>
purrr::set_names(nm = selected_exp)
map(.x = seq_along(interim_res), .f = \(.num) interim_res[[.num]] |> mutate(assay_type = names(interim_res)[[.num]])) |>
purrr::reduce(full_join) |>
mutate(assay_type = ifelse(assay_type == "Main", yes = "RNA", no = assay_type)) |>
select(assay_type, everything())
} else {
aggregate_sce_fun <- function(sce) {
aggregated_vals <- assays(altExps(sce)[[selected_exp]])[selected_assays$assay_name] |>
as.list() |>
set_names(selected_assays$assay_id) |>
map(.f = \(.list) aggregation_function(.list))
map(.x = seq_along(aggregated_vals), \(.num) enframe(x = aggregated_vals[[.num]], name = ".feature", value = selected_assays$assay_id[[.num]])) |>
suppressMessages(reduce(full_join))
}
aggregated_list <- lapply(sce_split, aggregate_sce_fun) |>
list_transpose() |>
map(.f = \(.list) .list |> bind_rows(.id = "grouping_factor"))
interim_res <- map(.x = seq_along(aggregated_list), .f = \(.num) aggregated_list[[.num]] |>
separate(col = grouping_factor, into = .sample_names, sep = "___")) |>
purrr::set_names(nm = selected_exp)
map(.x = seq_along(interim_res), .f = \(.num) interim_res[[.num]] |>
mutate(assay_type = names(interim_res)[[.num]])) |>
purrr::reduce(full_join) |>
mutate(assay_type = ifelse(assay_type == "Main", yes = "RNA", no = assay_type)) |>
select(assay_type, everything())
}
}
se <- lapply(selected_experiments_list, aggregate_assays_fun) |>
purrr::reduce(full_join) |>
suppressMessages()

if(se |>
distinct(assay_type, .feature) |>
pull(.feature) |>
duplicated() |>
any()) {
warning("tidySingleCellExperiment says: The selected assays have overlapping feature names. The feature names have been combined with the selected assay_type, to keep the rownames of the SingleCellExperiment unique. You can find the original feature names in the orig.feature.names column of the rowData slot of your object.")
Copy link
Owner

Choose a reason for hiding this comment

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

Amazing we are close.

Please let's stick with the tidyomics style feature_original (no dots in names, no abbreviations).

Copy link
Author

Choose a reason for hiding this comment

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

Good point. Done.

orig_features <- se |>
distinct(assay_type, .feature)
dup_features <- orig_features |>
filter(duplicated(.feature)) |>
pull(.feature)
se <- se |>
mutate(.feature = case_when(.feature %in% dup_features ~ str_c(assay_type, .feature, sep = ".."), .default = .feature))
}

se <- se |>
tidybulk::as_SummarizedExperiment(
.sample = .sample_names,
.transcript = .feature,
.abundance = setdiff(colnames(se), c("assay_type", .sample_names, ".feature")))
if(exists("assay_type", where = as.data.frame(colData(se)))) {
rowData(se) <- rownames(se) |>
enframe(name = NULL, value = "rowname") |>
mutate(assay_type = unique(colData(se)$assay_type)) |>
tibble::column_to_rownames() |>
as.data.frame() |>
as(Class = "DataFrame")
colData(se)$assay_type <- NULL
}
if(rownames(se) |> grep(pattern = "\\.\\.") |> any()) {
rowData(se) <- rowData(se) |>
as.data.frame() |>
rownames_to_column() |>
mutate(orig.feature.names = rowname,
orig.feature.names = str_remove_all(string = orig.feature.names, pattern = ".+(?=\\.\\.)"),
orig.feature.names = str_remove_all(string = orig.feature.names, pattern = "^\\..")) |>
column_to_rownames() |>
as(Class = "DataFrame")
}
Copy link
Owner

Choose a reason for hiding this comment

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

Can you add what this function is doing and why, in a comment above it?

As a general comment, please comment on all your code blocks, so a developer in 5-10 years can navigate the code without having to interpret it. 🙏

Copy link
Author

@Biomiha Biomiha Nov 1, 2023

Choose a reason for hiding this comment

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

I have now added plenty of comments to the method. Hopefully it should be clear what each code chunk is doing but do let me know if anything needs clarifying. I will also add descriptions to the other functions I've tweaked to clarify (e.g. join_features).

return(se)
})
Loading
Loading