Initial osteocar reference comparison - #1426
Conversation
allyhawkins
left a comment
There was a problem hiding this comment.
I think this is a good start, but I had a few suggestions to add to the notebook just to help add more context and make the one large heatmap a little easier to interpret.
| patient_mets_aggr$labels$full, | ||
| patient_prim_aggr$labels$full | ||
| ) | ||
| pheatmap::pheatmap( |
There was a problem hiding this comment.
Can we subset this to only show shared labels in the first place? I want to know if they have the same label in both references, are they similar. If they are different labels then they are probably distinct so we they just add noise to the heatmap and make it harder to interpret.
There was a problem hiding this comment.
I actually don't think you need this heatmap at all. It's fine to keep, but if the labels don't match up then the value is going to be 0 anyways so it doesn't totally make sense to me to show both?
| ) | ||
| ``` | ||
|
|
||
| There's a 1:1 match of proliferative here only, but the noise around other cell types suggests that there are distinct expression profiles between shared cell types across these references. |
There was a problem hiding this comment.
Sure there's only a 1:1 match for proliferative, but I see some fairly strong signals for 4 out of the 6 tumor classes. It would be helpful to see a table of how many of each cell type is present in the original dataset alongside this just for added context. As in, how much of the population is assigned to this "Interactive" population vs the proliferative population?
|
|
||
| ## Conclusions | ||
|
|
||
| Given the differences between primary/metastasis references for both patients and xenografts, it seems worth doing some initial exploration of annotation performance with `SingleR` next. |
There was a problem hiding this comment.
I think I would still run these together as a single reference with distinct labels. So you would attach primary- or met- to each of the labels prior to running. Then you can see which labels are assigned and if you get predominantly primary or met or an even mix of both within a single sample. You could then compare that to running as a single reference with harmonized labels where you don't distinguish between primary and met when building the reference model.
|
|
||
|
|
||
| # export reformatted object if requested | ||
| if (!is.null(opts$output_sce_file)) { |
There was a problem hiding this comment.
This seems strange to have a script solely for converting objects to SCE and then only do it optionally? I might make the output file required and remove the nesting you have here.
There was a problem hiding this comment.
I see that you want to expand this script to convert to anndata here too, but I think I would still remove this as being optional and do both conversions automatically.
| Rscript ${script_dir}/convert-osteocar.R --input_ref_file $mets_qs2 --output_sce_file $mets_sce | ||
| Rscript ${script_dir}/convert-osteocar.R --input_ref_file $prim_qs2 --output_sce_file $prim_sce | ||
| Rscript ${script_dir}/convert-osteocar.R --input_ref_file $xeno_mets_qs2 --output_sce_file $xeno_mets_sce | ||
| Rscript ${script_dir}/convert-osteocar.R --input_ref_file $xeno_prim_qs2 --output_sce_file $xeno_prim_sce |
There was a problem hiding this comment.
This is fine, but there's gotta be a way in bash to turn this into a loop that's not terribly ugly and minimizes the duplication. Maybe try this?
| Rscript ${script_dir}/convert-osteocar.R --input_ref_file $xeno_prim_qs2 --output_sce_file $xeno_prim_sce | |
| input_files=("$mets_qs2" "$prim_qs2" "$xeno_mets_qs2" "$xeno_prim_qs2") | |
| output_files=( | |
| "${ref_dir}/patient_mets_sce.rds" | |
| "${ref_dir}/patient_prim_sce.rds" | |
| "${ref_dir}/xeno_mets_sce.rds" | |
| "${ref_dir}/xeno_prim_sce.rds" | |
| ) | |
| for i in "${!input_files[@]}"; do | |
| Rscript "${script_dir}/convert-osteocar.R" \ | |
| --input_ref_file "${input_files[$i]}" \ | |
| --output_sce_file "${output_files[$i]}" | |
| done |
|
Changes include:
|
allyhawkins
left a comment
There was a problem hiding this comment.
This looks good to me. My comments are all fairly minor so I don't need to see this again. I think the biggest thing is just to make sure you add in an explanation at the top about what Ann_Level1 and Ann_Level2 are and then you probably don't need two copies of the same heatmap and can just show the shared cells.
| --- | ||
|
|
||
| There are several different references in `OsteoCar`, and while we can generally map them to our sample propertoes, we have some sample which don't neatly line up. | ||
| For example, `OsteoCar` has patient primary and metastatic (lung only) references, but we have a sample from metastatic tissue in bone which differs from the metastatic reference. |
There was a problem hiding this comment.
A question for the future, is it really just one sample or is it multiple samples?
There was a problem hiding this comment.
Definitely a typo, it's multiple......
> sample_df |> dplyr::filter(primary_or_metastasis=="Metastasis") |> dplyr::count(tissue_location)
# A tibble: 10 × 2
tissue_location n
<chr> <int>
1 Back 2
2 Femur 2
3 Kidney 1
4 Left Lung 1
5 Left upper lobe lung 1
6 Lung 29
7 Paraspinal 1
8 Right Lung 1
9 Right upper lobe lung 2
10 Thigh 1
| ) | ||
| ``` | ||
|
|
||
| The majority of cell types, including all classes of tumor cells, appear to be shared, but this does not guarantee they have similar expression. |
There was a problem hiding this comment.
It's been a while since I've read this paper, but can you remind me exactly which of these cell types they are calling "tumor" cell types vs. normal cell types? I'm actually surprised that the osteoblasts and chondrocytes population aren't overlapping with tumor, so I want to double check thats the case? Or is tumor vs normal represented by a different column in the data?
| ```{r} | ||
| #| fig.height: 8 | ||
| #| fig.width: 10 | ||
| make_barplot(prim_coldata, mets_coldata) |> |
There was a problem hiding this comment.
Ah I see now which categories are which. Thank you for adding this since it's helpful to see them grouped by broad cell type.
| We compare the references to one another to see how similar the cell type distributions and expression signatures are. | ||
| As these references are quite large, they have to be aggregated before use, but we'll also explore their raw data too. |
There was a problem hiding this comment.
Can you add a note here about what's in Ann_Level1 vs Ann_Level2? That might help with some of the confusion I was experiencing (but have since resolved).
| patient_mets_aggr$labels$full, | ||
| patient_prim_aggr$labels$full | ||
| ) | ||
| pheatmap::pheatmap( |
There was a problem hiding this comment.
I actually don't think you need this heatmap at all. It's fine to keep, but if the labels don't match up then the value is going to be 0 anyways so it doesn't totally make sense to me to show both?
| Now, only the cell types shared between the references: | ||
|
|
||
| ```{r} | ||
| shared_matched <- matched[shared, shared] |
There was a problem hiding this comment.
This is much more helpful because you can see the cell types that don't have any match that should have a match, which look to be mostly tumor cells. This tells me there probably is a difference in the marker gene expression for tumor cell subpopulations between primary and mets that we should be sure to consider.
| if (facet) { | ||
| p_counts <- p_counts + facet_wrap(vars(Ann_Level1), scales = "free", nrow=3) | ||
| p_props <- p_props + facet_wrap(vars(Ann_Level1), scales = "free", nrow=3) | ||
| } |
There was a problem hiding this comment.
| if (facet) { | |
| p_counts <- p_counts + facet_wrap(vars(Ann_Level1), scales = "free", nrow=3) | |
| p_props <- p_props + facet_wrap(vars(Ann_Level1), scales = "free", nrow=3) | |
| } | |
| p_counts <- p_counts + facet_wrap(vars(Ann_Level1), scales = "free", nrow=3) | |
| p_props <- p_props + facet_wrap(vars(Ann_Level1), scales = "free", nrow=3) | |
It looks like you don't actually use the facet option, so you can probably remove it.
| ## Functions | ||
|
|
||
| ```{r} | ||
| make_barplot <- function(prim_coldata, mets_coldata, facet = TRUE) { |
There was a problem hiding this comment.
| make_barplot <- function(prim_coldata, mets_coldata, facet = TRUE) { | |
| make_barplot <- function(prim_coldata, mets_coldata) { |
I like keeping it because this function does specific things to help you identify cases when cell types are effectively equivalent between references but the labels don't match - that's really its main purpose, but here we're using to compare references more directly. So, we actually do learn something from this heatmap - that a cell type labeled X in one reference apparently does not really correspond to cell type wit different label Y in the other. I will add this additional textual context to explain why to keep ot. |
Towards #1424
Purpose/implementation Section
The goal of this PR is to begin comparing references to each other. Originally I had one pretty large notebook, but I am breaking it up into multiple notebooks for easier review so there's more to come.
As such, this PR contains the following:
Here is this PR's rendered notebook:
02-compare-references.nb.html
Author checklists
Analysis module and review
README.mdhas been updated to reflect code changes in this pull request.Reproducibility checklist
Dockerfile.environment.ymlfile.renv.lockfile.