Skip to content

Added new DifferentialProximityAnalysis method. #147

Open
ludvigla wants to merge 10 commits into
mainfrom
pna-2835
Open

Added new DifferentialProximityAnalysis method. #147
ludvigla wants to merge 10 commits into
mainfrom
pna-2835

Conversation

@ludvigla

Copy link
Copy Markdown
Collaborator

Description

This PR adds a new DifferentialProximityAnalysis.Matrix method for sparse matrices. The method can be invoked from DifferentialProximityAnalysis.Seurat by setting method = "seurat" (default).

This new method pivots the long formatted proximity table into a sparse matrix and uses FindMarkers to compute the test statistics. The main difference is that missing observations are set to 0, meaning that each group will have a value for all cells in that group. This should be much more robust to ensure that the results reflect population differences and not differences between smaller subsets. This strategy can also pick up differences where one of the two test groups has no observations, which we previously missed.

This PR also refactors the existing DifferentialProximityAnalysis.data.frame method (invoked by setting method = "legacy" on Seurat objects) and adds a few minor improvements for speed optimization and pre-filtering similar to what FindMarkers does.

Fixes: PNA-2835

Type of change

  • Bug fix (non-breaking change which fixes an issue).
  • New feature (non-breaking change which adds functionality).
  • Breaking change (fix or feature that would cause existing functionality to not work as expected).
  • This change requires a documentation update.

How Has This Been Tested?

TODO

PR checklist:

  • My changes generate no new warnings.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have documented any significant changes to the code in CHANGELOG.md

Comment thread R/differential_proximity_analysis.R Outdated
Comment thread R/differential_proximity_analysis.R Outdated
Comment thread R/differential_proximity_analysis.R Outdated
Comment thread R/differential_proximity_analysis.R Outdated
Comment thread R/differential_proximity_analysis.R Outdated
group_vars = NULL,
proximity_metric = "join_count_z",
p_adjust_method = c("bonferroni", "holm", "hochberg", "hommel", "BH", "BY", "fdr"),
diff_trehsold = 0.1,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if the default threshold is perhaps a bit too strict? Many of the changes we see are quite small but significant. Maybe the FBS team has some input hree?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah I think you might be right. I just used the default in FindMarkers, but that's for log2FC differences which are probably greater than differences in medians.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think something like 0.01 could be suitable?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Based on my little experience so far, when we get a diff_median < 0.1, it is considered quite low. But this number is not log2FC as ludvig mentioned.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The main speed up that you see with FindMarkers comes from the filters used and this particular one is quite effective. Setting it to 0.1 will make the function feel a lot faster :-)

@maxkarlsson maxkarlsson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks great! I have some comments on some parameters that would be great to discuss.

Comment thread R/differential_analysis_utils.R Outdated
Comment thread R/differential_analysis_utils.R Outdated
#' @noRd
.finalize_da_results <- function(res_list, p_adjust_method, group_vars = NULL) {
bind_rows(res_list) %>%
group_by(pick(all_of(c("target", group_vars)))) %>%

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we really perform p-value adjustment per group? I know there are often different opinions about this - but the effect here would be lower p-values --> more sensitivity and potential false positives. What is your take?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah that's a very good question. I was hoping you'd bring this up. I guess it depends on what you do with the results.

If you split the tests across many groups (e.g. cell types), you will most likely lose a bunch of hits if you adjust across all tests. In practice, I think you would most likely focus on a single cell type at the time, and then it might be better to adjust only within that cell type population.

Let's say we run the differential test between stimulated and control in 10 cell types, but we are only interested in B cells. Alternatively, we subset the Seurat object to only include B cells and then run the test we would get very different adjusted p-values for the B cell population. Both approaches are valid. I think there's a risk that you'll get very few significant hits if you do the testing across 10 cell type populations.

What I do think we could do is to only group by the optional group_vars when doing the adjustment. Currently, if you have more than 1 target, the adjustment will be done per target (e.g. stimulated1 and stimulated2 against the reference). In practice, you would probably evaluate the results within the context of both stimulation conditions, so we should do the adjustment across all conditions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sounds good! I guess it is always possible for a user to override the p-value adjustment after the fact if they disagree

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

it is a balance, indeed. Adjusting across all groups seems sometimes very harsh; often resulting in nothing being significant. On the other hand, I agree it is is the most correct adjustment. Perhaps with the increased filtering that comes with these updates we also soften the effect of the adjustment at bit? I would tend to keep it as it is now but evaluate this? Open for other ideas though, it's a tricky one.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In our particular case we will also have the terrible situation of p >> n when dealing with proximity scores, and the p variables aren't independent from each other and the n cells aren't independent either! So talking p-values is kinda statistically fudgy regardless of adjustment. Whatever is a better user experience could take precedence perhaps.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah I feel like they are mostly there fore convenience to filter the data. Not sure what the best solution is.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I would think the adjustments in general should be done globally for a given hypothesis test

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I also agree, but the problem with proximity scores is that we are comparing so many pairs of proteins potentially across many different groups, so the p-value adjustment will remove a lot of hits. I think it comes down to what we want users to get. Should they get more results to evaluate further?

Comment thread R/differential_proximity_analysis.R Outdated
Comment thread R/differential_proximity_analysis.R Outdated
Comment thread R/differential_proximity_analysis.R Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants