cepip relates a gene of interest (GOI) to the mean expression of its partner genes, cell by cell, and finds where that relationship changes.
y ~ x + s(x), is fitted by REML with the basis
dimension k chosen by the lowest penalized residual sum of squares
(PRSS).Steps 1 to 3 are the published CEP-IP. The package does not transform
the data, so x and y must be on the scale you
want to analyse (the SEA-AD analysis used ln(CP10K + 1)).
cepip_toy holds 1,200 simulated cells from 12
donors.
d <- cepip_toy
d$y <- cepip_composite(d, paste0("P", 1:8))
res <- cepip(d$x, d$y, donor = d$donor, id = d$id, cmrf = TRUE, tests = FALSE)
#> CEP-IP: 1200 cells, 12 donors
#> GAM: k = 7 | DE = 0.7492
#> IP: x = 2.4135 [2.3525, 2.4756] | y = 1.1938 | IPRS = 0.656 (Strong)
#> SKCS-core: 665 cells | TREP 574
#> Band: delta_base = 0.16097 | candidates 190
#> CMRF: Original + Refined 647 | Recovered 165 | Original only 18 | Excluded 370
#> Validation1: DE = 0.8804 | agreement 96.0%
#> Done in 2 s.
res
#> CEP-IP analysis of 1200 cells from 12 donors
#> GAM: k = 7, DE = 0.7492, TREP cells = 895
#> IP: x = 2.4135 (95% CI 2.3525 to 2.4756), y = 1.1938, IPRS = 0.656 (Strong)
#> SKCS-core cells: 665
#> CMRF classes:
#> Original + Refined 647
#> Recovered 165
#> Original only 18
#> Excluded 370
#> Module: 812 cells
#> Validation1: DE = 0.8804, label agreement 96.0%With donor, the GAMs include a donor random intercept
and weight each cell by 1 / (cells of its donor). Without
donor, every cell has weight 1, as in the published
CEP-IP.
The Pre-IP and Post-IP labels use the response axis by default (y
< IPy is Pre-IP). The published CEP-IP analyses split on the GOI
axis, which ip_axis = "x" reproduces.
The band is widest at the IP. Its half-width is delta_base x (1 +
kappa x K(u)), where K is a Gaussian kernel with standard deviation
bw centred at the IP. cepip_band() is fast, so
several settings can be compared before running the gate.
cepip_cmrf() uses kappa = 0.5 and bw = 0.1 when no band is
given.
b <- cepip_band(res$skcs, res$ip, kappa = 0.5, bw = 0.1)
plot_band(b)
#> Warning in ggplot2::annotate("label", x = uq[2], y = mean(c(at("a_lo", uq[2]),
#> : Ignoring unknown parameters: `label.size`
#> Warning in ggplot2::annotate("label", x = uq[c(1, 3)] + c(-off, off), y =
#> (at("a_lo", : Ignoring unknown parameters: `label.size`The four groups are Module Post-IP (PostIP), Module
Pre-IP (PreIP), non-Module Post-IP (NMPost)
and non-Module Pre-IP (NMPre). Without CMRF, the TREP cells
take the place of the Module.
dp <- cepip_donor(res)
head(dp)
#> donor n_total n_PostIP pct_PostIP n_PreIP pct_PreIP n_NMPost pct_NMPost
#> 1 D01 100 30 30 38 38 3 3
#> 2 D02 100 37 37 30 30 5 5
#> 3 D03 100 42 42 37 37 3 3
#> 4 D04 100 39 39 26 26 9 9
#> 5 D05 100 35 35 33 33 10 10
#> 6 D06 100 29 29 37 37 8 8
#> n_NMPre pct_NMPre pct_module
#> 1 29 29 68
#> 2 28 28 67
#> 3 18 18 79
#> 4 26 26 65
#> 5 22 22 68
#> 6 26 26 66cepip_deg() compares two groups with a paired design
across donors. It needs log1p-normalized expression (genes x cells) with
the cell ids as column names.
deg <- cepip_deg(res, expr, contrast = c("PostIP_vs_PreIP", "PostIP_vs_NMPost"))
plot_deg(deg, "PostIP_vs_PreIP")cepip_associate() relates a donor-level measure to
outcomes with ordinary least squares on z-scores, adjusting for
covariates.
tab <- merge(dp, donor_metadata, by = "donor")
as <- cepip_associate(tab, "pct_PostIP", outcomes = c("MMSE", "Braak"),
covariates = c("age", "sex", "PMI"))
plot_associate(as)Which groups to compare, the outcomes and the covariates depend on the question and on the data available. The defaults of the DEG step (5% expressing cells, at least 3 cells per donor and group, at least 5 paired donors, FDR < 0.05 and |log2FC| >= 0.25) are those of the SEA-AD analysis.
cepip_screen() screens candidate GOIs for partner genes
by Spearman rs and Kendall tau-b. By default a GOI is screened when it
is expressed in at least 25% of the cells with a mean of at least 0.3
over the expressing cells, and a partner passes at rs >= 0.6 and
tau-b >= 0.5. These defaults suit ln(CP10K + 1) data from one cell
population; adjust them for other data.
The example data of the paper are the Micro-PVM_3-SEAAD cells of the
Seattle Alzheimer’s Disease Brain Cell Atlas (SEA-AD) with MT-CO3 >
0, and the cells of the housekeeping-gene control arm. They are
downloaded once with cepip_example(). Use of the SEA-AD
data is subject to the Allen Institute Terms of Use and Citation
Policy.
pv <- cepip_example("pvm3")
MT8 <- c("MT-ATP6", "MT-CO2", "MT-ND3", "MT-ND4", "MT-CYB", "MT-ND1", "MT-ND2", "MT-CO1")
d <- pv[pv$region_set == "NeoC", ]
res <- cepip(d[["MT-CO3"]], cepip_composite(d, MT8), donor = d$donor, id = d$barcode,
cmrf = TRUE, ip_k = 10, y_spine = d$composite_part8, workers = 4)
cepip_save(list(NeoC = res), "PVM_3")The script
system.file("scripts", "reproduce_seaad.R", package = "cepip")
runs both region sets of the PVM_3 arm, the HKG8 control arm and the
same-cell housekeeping control, and compares every value with the
published one. Expected values for PVM_3 NeoC include IPx = 2.4953, IPRS
= 0.791, 8,407 SKCS-core cells, 8,103 OriRef cells, 1,351 Recovered
cells and 643 cells removed by the gate.
The published SEA-AD analysis used ip_k = 10 for the IP
fit and fitted the CMRF spine on the composite column of its data
export, which is stored in single precision (y_spine). The
eight partner genes were chosen from the per-region screens of the
paper.