Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Replication

Meta-analysis combined the studies’ estimates into one per gene. Whether a change replicates is another question: that the gene changes in study after study, not that the studies together find it. sumrank asks it by default: each study ranks the genes, and every gene’s ranks are summed across the studies Nakatsuka et al., 2025. Replication across studies runs it on six simulated cohorts, with the other methods of this chapter.

SumRank

A meta-analysis weighs each study by its precision, so that one or two precise studies can carry a gene; the random-effects model widens the interval when the studies disagree (Defaults and choices). SumRank asks instead that a gene rank high in every study, or, with fewer ranks summed, in most, so that one study alone cannot carry a gene, however small its p-value there. In the paper that introduced it, its genes predicted case status in studies left out better than those of a random-effects meta-analysis Nakatsuka et al., 2025. sumrank computes it for one cell type and contrast of the studies’ results, a StudyResults, and returns a SumRankResult, whose table (SumRankResult.features) gives each gene’s statistics and p-values, up and down; fit_sumrank computes it from arrays of the studies’ signed statistics, into a SumRankFit.

Within each study, the genes that every study tested are ranked by their signed −log⁡10-\log_{10} p-value, the gene most up first, r=1r = 1, and the gene most down last, r=Gr = G; tied genes share their average rank. The normalized ranks u=(r−1)/(G−1)u = (r - 1) / (G - 1) run from 0 to 1. A gene’s statistic adds up its best mm of its kk normalized ranks, one from each of the mm studies that rank it highest, and is capped at their mean under the null:

Sg=min⁡(∑j=1mug(j), m2),m=⌊p k⌋,S_g = \min\Big(\sum_{j=1}^{m} u_{g(j)},\ \frac{m}{2}\Big), \qquad m = \lfloor p\,k \rfloor,

with ug(1)≤⋯≤ug(k)u_{g(1)} \le \dots \le u_{g(k)} and the proportion pp of the studies (proportion_of_studies), or mm given itself (n_studies_summed). By default every study is summed, m=km = k. The paper summed every study when there were few, 3 to 6, and chose pp by cross-validation when there were many: 0.65 of 17 studies of Alzheimer’s disease and 0.55 of 16 of COVID-19. Genes down have the statistic of the ranks 1−u1 - u. A gene missing from some study’s results, because the study did not measure it or its expression filter left it out, is not ranked, as in the paper, which ranked the genes that every study measured: a rank says where a gene stands among the genes ranked with it.

If each study ranked the genes at random, the normalized ranks would be independent uniform variables, and SgS_g below the cap would follow the Irwin-Hall distribution of a sum of mm of them Irwin, 1927Hall, 1927, whose distribution function gives the Irwin-Hall p-value. With every study summed this distribution holds, but for the discreteness of the ranks, which is small among many genes. The sum of the best mm of kk ranks is smaller than a sum of mm ranks, so with m<km < k these p-values are much too small, and sumrank warns when it gives them: in six simulated studies without changes, 4.8% of the p-values fell at or below 0.05 with every study summed, and 37% with the best three of six (Validation).

The paper takes its p-values from permutations instead. With n_permutations, sumrank permutes the variable whose levels the contrast compares (or permute) in each study’s design, among the samples of its fit of the cell type, from a seeded numpy.random.Generator, and runs the study’s limma_voom or limma_trend again, with the design and the settings that its result records. Pooled over the genes and the permutations, the permuted statistics make one null distribution of NN values, against which a gene of statistic ss has the p-value

p=1+#{null statistics≤s}1+N,p = \frac{1 + \#\{\text{null statistics} \le s\}}{1 + N},

never zero Phipson & Smyth, 2010. This pooling gives small p-values from few permutations: 100 permutations of 10,000 genes reach 10-6. Each permutation runs every study’s analysis once, for one cell type (Timings gives the cost). plot_sumrank draws the p-values as a Manhattan plot, a point per gene in alphabetical order, as SumRank’s authors draw them.

Prediction in held-out studies

Genes that replicate should tell cases from controls in a study that had no part in choosing them. held_out_prediction leaves each study of a StudyResults out in turn and chooses, in each cell type, n_features genes up and as many down from the other studies’ results (50 by default), by SumRank and by the random-effects meta-analysis with REML and the Knapp-Hartung adjustment, the paper’s comparison. It scores each of the held-out study’s cases and controls, the two levels that the contrast compares, and reports the area under the ROC curve of cases against controls Hanley & McNeil, 1982, by study and method, in a HeldOutPrediction (HeldOutPrediction.auc).

A sample’s score builds on UCell’s rank score Andreatta & Carmona, 2021: in each cell type, how high the sample’s profile ranks the chosen genes among all its genes, rescaled to [0, 1] across the study’s samples, with the genes up adding to the score and the genes down taking from it; the cell types’ scores are summed, as the authors’ code sums them. A sample without a profile in a cell type takes the mean of the others’ scaled scores there. The genes chosen and the scores are in HeldOutPrediction.features and HeldOutPrediction.scores, and plot_held_out_auc draws the AUC of every study by method. An AUC of 0.5 says that the score does not separate cases from controls, and below 0.5 that the genes predict the wrong direction.

Combined p-values

Where the studies give p-values rather than comparable effects, they can be combined. For every gene that kk studies tested, with p-values p1,…,pkp_1, \dots, p_k, combine_p_values tests the hypothesis that none of these studies has an effect, by the methods of scipy’s combine_pvalues and the R package metap, and returns a CombinedPValues. With p(1)≤⋯≤p(k)p_{(1)} \le \dots \le p_{(k)} in order:

MethodStatisticIts distribution without effects
"fisher" Fisher, 1932X=−2∑log⁡piX = -2 \sum \log p_iχ2k2\chi^2_{2k}, upper tail
"stouffer" Stouffer et al., 1949Lipták, 1958Z=∑wizi/∑wi2Z = \sum w_i z_i / \sqrt{\sum w_i^2}, zi=Φ−1(1−pi)z_i = \Phi^{-1}(1 - p_i)standard normal, upper tail
"tippett" Tippett, 1931p(1)p_{(1)}1−(1−p(1))k1 - (1 - p_{(1)})^k
"wilkinson" Wilkinson, 1951p(r)p_{(r)}beta with parameters rr and k−r+1k - r + 1
"pearson" Pearson, 1933X=−2∑log⁡(1−pi)X = -2 \sum \log (1 - p_i)χ2k2\chi^2_{2k}, lower tail
"mudholkar_george" George & Mudholkar, 1983∑log⁡((1−pi)/pi)\sum \log((1 - p_i)/p_i), scaledStudent’s t on 5k+45k + 4 degrees of freedom
"simes" Simes, 1986min⁡jk p(j)/j\min_j k\, p_{(j)} / jthe p-value itself

Fisher’s and Tippett’s methods respond to the strongest study; Stouffer’s, the logit and Pearson’s to evidence that the studies share. Stouffer’s method weighs the studies equally unless given weights, usually the square roots of their sample sizes Zaykin, 2011. A small p-value of Wilkinson’s maximum (r=kr = k) says that every study has some evidence, not that every study has an effect, which the partial conjunction below tests. A gene that some studies did not test is combined over the others, and n_studies says how many; one study gives its own p-value, except with the logit, which approximates its statistic’s distribution even then. p-values of exactly 0 or 1 are taken as the limits that the methods reach.

Each method expects one-sided p-values of one direction of effect, so that an effect the other way gives a p-value near 1. Two-sided p-values can be combined as they are, but they then ask whether some study has an effect either way, and opposite effects do not cancel. Given the signs of the studies’ effects in directions, such as their log2 fold changes, combine_p_values makes each two-sided p-value one-sided for each direction, p/2p/2 where the effect points that way and 1−p/21 - p/2 where it points the other, as metap’s two2one does; it combines each direction and doubles the smaller result, up to 1 Owen, 2009; for Stouffer’s method, that is the two-sided p-value of ZZ. Each method uses p/2p/2 as it is, never as 1−(1−p/2)1 - (1 - p/2), so that p-values near 1e-300 keep their digits.

An effect in at least u studies

One study’s effect makes the hypothesis of no effect in any study false, so a small combined p-value does not say that an effect replicates. partial_conjunction tests the hypothesis that fewer than uu of the nn studies that tested a gene have an effect Benjamini & Heller, 2008. Up to u−1u - 1 studies with effects could explain the u−1u - 1 smallest p-values, so the test sets them aside and combines the others, p(u),…,p(n)p_{(u)}, \dots, p_{(n)}: by Simes’s method, min⁡i≥u(n−u+1) p(i)/(i−u+1)\min_{i \ge u} (n - u + 1)\, p_{(i)} / (i - u + 1), the default, or by Fisher’s or Stouffer’s (unweighted). With u=1u = 1 this is the test of no effect in any study; with u=nu = n every method returns the largest p-value, p(n)p_{(n)}. With directions, the uu effects must point the same way. Benjamini and Hochberg’s adjustment of these p-values over the genes controls the false discovery rate of the claims that a gene has an effect in at least uu studies Benjamini & Heller, 2008. It gains this at a cost in power: the change must be clear in uu studies, each on its own.

How well one study replicates another

A gene that one study finds and another does not may still change in the other, by too little for it to find. Take the genes that the discovery study finds, and their p-values in the replication study: one minus Storey’s estimate of the proportion of these p-values without an effect, π1=1−π0\pi_1 = 1 - \pi_0 (The proportion of true nulls), estimates the share of the genes that change in the replication study, whether it finds them or not Storey & Tibshirani, 2003. It is not symmetric: it reads the genes of one study in the p-values of the other. The sign agreement, the share of those genes whose log2 fold changes point the same way in both studies, says whether the changes agree in direction.

By default π0\pi_0 is estimated at λ=0.5\lambda = 0.5, which suits the few dozen p-values of one study’s findings better than qvalue’s smoother (Defaults and choices); null_proportion={} asks for the smoother.

The replication tables

replication reads the studies’ results, a StudyResults, for one cell type and contrast, and returns a ReplicationResult with four tables, each of which answers one question:

plot_study_agreement shows π1\pi_1 or the sign agreement for every pair of studies as a heatmap, and plot_replicated_genes the number of genes found by each number of studies.

Defaults and choices

Limits and differences

Checks and further reading

Further reading:

This is the last chapter. Choosing a method maps every question to its method, and the Validation page gives how closely each agrees with the tool that defined it.

References
  1. Nakatsuka, N., Adler, D., Jiang, L., Hartman, A., Cheng, E., Klann, E., & Satija, R. (2025). Improving reproducibility of differentially expressed genes in single-cell transcriptomic studies of neurodegenerative diseases through meta-analysis. Nature Communications, 16(1), 7436. 10.1038/s41467-025-62579-z
  2. Irwin, J. O. (1927). On the frequency distribution of the means of samples from a population having any law of frequency with finite moments, with special reference to Pearson’s Type II. Biometrika, 19(3–4), 225–239. 10.1093/biomet/19.3-4.225
  3. Hall, P. (1927). The distribution of means for samples of size N drawn from a population in which the variate takes values between 0 and 1, all such values being equally probable. Biometrika, 19(3–4), 240–244. 10.1093/biomet/19.3-4.240
  4. Phipson, B., & Smyth, G. K. (2010). Permutation p-values should never be zero: calculating exact p-values when permutations are randomly drawn. Statistical Applications in Genetics and Molecular Biology, 9(1), Article 39. 10.2202/1544-6115.1585
  5. Hanley, J. A., & McNeil, B. J. (1982). The meaning and use of the area under a receiver operating characteristic (ROC) curve. Radiology, 143(1), 29–36. 10.1148/radiology.143.1.7063747
  6. Andreatta, M., & Carmona, S. J. (2021). UCell: robust and scalable single-cell gene signature scoring. Computational and Structural Biotechnology Journal, 19, 3796–3798. 10.1016/j.csbj.2021.06.043
  7. Fisher, R. A. (1932). Statistical Methods for Research Workers (4th ed.). Oliver.
  8. Stouffer, S. A., Suchman, E. A., DeVinney, L. C., Star, S. A., & Williams, R. M. (1949). The American Soldier, Volume 1: Adjustment during Army Life. Princeton University Press.
  9. Lipták, T. (1958). On the combination of independent tests. Magyar Tudományos Akadémia Matematikai Kutató Intézetének Közleményei, 3, 171–197.
  10. Tippett, L. H. C. (1931). The Methods of Statistics. Williams.
  11. Wilkinson, B. (1951). A statistical consideration in psychological research. Psychological Bulletin, 48(2), 156–158. 10.1037/h0059111
  12. Pearson, K. (1933). On a method of determining whether a sample of size n supposed to have been drawn from a parent population having a known probability integral has probably been drawn at random. Biometrika, 25(3–4), 379–410. 10.1093/biomet/25.3-4.379
  13. George, E. O., & Mudholkar, G. S. (1983). On the convolution of logistic random variables. Metrika, 30(1), 1–13. 10.1007/BF02056895
  14. Simes, R. J. (1986). An improved Bonferroni procedure for multiple tests of significance. Biometrika, 73(3), 751–754. 10.1093/biomet/73.3.751
  15. Zaykin, D. V. (2011). Optimally weighted Z-test is a powerful method for combining probabilities in meta-analysis. Journal of Evolutionary Biology, 24(8), 1836–1841. 10.1111/j.1420-9101.2011.02297.x