Skip to content

Create SVG instruction notebook: code - #1056

Merged
jashapiro merged 22 commits into
masterfrom
jashapiro/1046-svg-instruction
Aug 20, 2026
Merged

Create SVG instruction notebook: code#1056
jashapiro merged 22 commits into
masterfrom
jashapiro/1046-svg-instruction

Conversation

@jashapiro

Copy link
Copy Markdown
Member

Here I am adding the initial notebook for spatially variable genes as part of #1046

It is a bit rougher than I might have liked, but because I will be out for a few days, I wanted to get what I have up for initial comments as at least a draft.

As discussed, I am doing Moran's I & nnsvg analysis, with a little bit of intro to Voyager and SpatialFeatureExperiment structure to start out. I also have some comparisons between the two methods, and looking at SVGs vs. biological variation, which I want to talk a bit more about (how might technical variation be spatial?)

I have not yet decided which chunks will be live and not, so if you have particular ones that you think absolutely should or should not be, please feel free to comment on that!

Here is a rendered version for easier viewing.
04-spatially_variable_genes.nb.html

@sjspielman sjspielman assigned sjspielman and unassigned sjspielman Aug 4, 2026
@sjspielman
sjspielman self-requested a review August 4, 2026 12:20
@sjspielman sjspielman removed their assignment Aug 4, 2026

@sjspielman sjspielman 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.

Overall seems like a solid draft, and I left comments for recommended live chunks.

The main concern I have is doubling down on comparisons for p-values that we know aren't going to be very good, with mcmc. This seems especially tricky if we have concerns that the moran's test pvalues aren't robust. We can tackle both at once with some pre-computed pvalues from a thorough mcmc and both see: here's how you would actually get solid mcmc pvalues, and from these we can maybe get a sense of how robust the moran's test once are.

Otherwise, I'm not convinced that the comparisons are meaningful to interpret at all since they rely on us trusting the pvalues.

Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment on lines +190 to +193
You'll notice that the new column names include the sample_id, which is a bit annoying, but it is necessary to keep things separate if we have multiple samples.

Let's first look at the distribution of Moran's I values across all (highly variable) genes:

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.

Let's toss in a chunk to update names() here for typo reduction later?

Comment thread spatial/04-spatially_variable_genes.Rmd
Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment thread spatial/04-spatially_variable_genes.Rmd
Comment on lines +279 to +283

```{r moran_significant}
moran_df <- moran_df |>
dplyr::mutate(
moran_test_p_adjust = p.adjust(moran_test_p, method = "BH"),

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 might make an implementation comment here that we need to do this on an ungrouped data frame for the correction to work properly

Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment thread spatial/04-spatially_variable_genes.Rmd
Comment thread spatial/04-spatially_variable_genes.Rmd
Comment thread spatial/04-spatially_variable_genes.Rmd
Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment thread spatial/setup/osteo/Snakefile Outdated
@jashapiro

Copy link
Copy Markdown
Member Author

Thanks for the review!

I have now added a small script and updates to the Snakemake files to pre-calculate the Moran Monte Carlo statistics with 100K replicates, which we now load in separately for a bit more comparison. Doing it this way allow seeing that the parametric statistic overestimates significance compared to the MC method (though probably not too bad, all things considered).

I did not yet update to include the actual output file in the analysis directory, mostly because I could not decide whether to put it in the repo or only on S3. The file is not very large (215KB), and could be much smaller if we stored it gzipped (~30KB). So part of me wants to just keep it in the repo, but that also seems kind of silly.

Other changes include small updates to plots, one of which is adding the correlation stats at the end directly to the plots with the annotate() function. Just for fun.

Attached is an updated rendered notebook:
04-spatially_variable_genes.nb.html

@jashapiro
jashapiro requested a review from sjspielman August 11, 2026 21:05
@jashapiro
jashapiro marked this pull request as ready for review August 14, 2026 20:23
@sjspielman

Copy link
Copy Markdown
Contributor

@jashapiro it doesn't look like the HTML has output from the chunks.. are you able to regenerate it? Thanks!

@sjspielman sjspielman 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.

Overall I think this looks great, no major comments. I would like to see a rendered notebook though before I approve to look that over in case there's something not apparent here.

Comment thread spatial/setup/osteo/.gitignore Outdated
Comment thread spatial/setup/osteo/calculate-moran.R Outdated
make_option(
opt = c("-t", "--threads"),
type = "integer",
default = 8,

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 might make this default 4, since we're overriding it in practice anyways. This doesnt matter too much though.

Suggested change
default = 8,
default = 4,

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.

FYI I opened #1064

Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
dplyr::count(moran_test_sig, moran_mc_sig)
```

Either way, we get the vast majority of genes as "significant" which is not too surprising.

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.

Why isn't this surprising, just because we might expect that HVGs overlap with SVGs?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Mostly because we can see from previous analysis that there is a lot of spatial variation in expression patterns. Once we condition on having high levels of variation, it seems almost certain that it will be spatially variable.

Again, most of them!
So most genes are significantly spatially variable, which is perhaps not a huge surprise.

Other stats we can look at include `prop_sv`, which is the proportion of variation that is attributable to spatial variation.

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.

breadcrumb for future text - does nnSVG model other kinds of variation, or is just spatial + residual? I don't remember myself...

Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment on lines +448 to +451
label = paste0(
"Spearman correlation: ",
cor(svg_df$moran_i, svg_df$nnsvg_propsv, method = 'spearman')
)

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.

this is a great case where I agree with paste and not glue! sometimes it happens 😉

@jashapiro

Copy link
Copy Markdown
Member Author

it doesn't look like the HTML has output from the chunks.. are you able to regenerate it? Thanks!

Sorry about that. This one should:
04-spatially_variable_genes.nb.html

Comment thread spatial/setup/osteo/calculate-moran.R
Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Co-authored-by: Stephanie J. Spielman <stephanie.spielman@gmail.com>
Co-authored-by: Joshua Shapiro <josh.shapiro@ccdatalab.org>

@sjspielman sjspielman 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.

Rendered notebook looks good! Just caught a few small plot styling spots.

Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
@jashapiro

Copy link
Copy Markdown
Member Author

Thanks for the review.

I added TODOs for text areas I want to be sure to address.

One question I asked above and did want to resolve in this PR was the following, if you have thoughts:

I did not yet update to include the actual output file in the analysis directory, mostly because I could not decide whether to put it in the repo or only on S3. The file is not very large (215KB), and could be much smaller if we stored it gzipped (~30KB). So part of me wants to just keep it in the repo, but that also seems kind of silly.

@jashapiro
jashapiro requested a review from sjspielman August 19, 2026 17:34

@sjspielman sjspielman 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.

I did not yet update to include the actual output file in the analysis directory, mostly because I could not decide whether to put it in the repo or only on S3. The file is not very large (215KB), and could be much smaller if we stored it gzipped (~30KB). So part of me wants to just keep it in the repo, but that also seems kind of silly.

Woops, thanks for the ping on this comment! I think it's fine to just keep it in S3.

Everything looks good to me, except one big comment that we are missing a seed in the MCMC script which seems important to have and regenerate the tsv with! I don't need to see again though.

This includes all of the spots where we have data.


## Identify Spatially Variable Genes

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.

parallel (but feel free to ignore this since headers may be changing with the next PR anyways!)

Suggested change
## Identify Spatially Variable Genes
## Identifying Spatially Variable Genes

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.

Just realized this script is missing a seed! We definitely want that...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

added

@jashapiro jashapiro left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

realized I left a bunch of comments pending

Comment thread spatial/04-spatially_variable_genes.Rmd Outdated
Comment on lines +178 to +180
### Moran's I

The measure of spatial covariation we will use is Moran's I.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'll make it italics, which doesn't really help, I know but I don't want to make it code, since it isn't that.

sfe <- Voyager::runMoransI(sfe)
```

This gives us an I value for each gene as well as the kurtosis of the gene's expression (how fat the tails are) as a value `K`.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

added a todo

We could do better with more replicates, but that takes a very long time to run... so we pre-calculated a set with 100,000 replicates.

```{r read-moran_mc100k}
moran_mc100k_df <- readr::read_tsv(moran_mc100k_tsv) |>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'd rather read it here. While it doesn't matter in this case, there are often good (memory) reasons not to load all data at the top. While I think we tend to load things at the top most of the time, I don't think it is something we specifically call out for structure.

dplyr::count(moran_test_sig, moran_mc_sig)
```

Either way, we get the vast majority of genes as "significant" which is not too surprising.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Mostly because we can see from previous analysis that there is a lot of spatial variation in expression patterns. Once we condition on having high levels of variation, it seems almost certain that it will be spatially variable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

added

@jashapiro
jashapiro merged commit 77c81d0 into master Aug 20, 2026
5 checks passed
@jashapiro
jashapiro deleted the jashapiro/1046-svg-instruction branch August 20, 2026 12:03
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.

2 participants