Nested measurements · Choose a method

Patch-clamp statistics: cells, animals, pooled events and paired drug applications

Compare genotypes with the animal as n, not cells or pooled events: a Kolmogorov–Smirnov test on pooled mEPSCs finds differences that do not exist. Analyse drug applications in the same cell as paired. Python and R code.

By Licklider · Published · Last reviewed · How this page was made · Markdown

On this page
  1. Which analysis for your question
  2. Worked example: mEPSC amplitudes in WT and KO mice with no real difference
  3. Before you analyse
  4. Check what an AI assistant ran
  5. Report it
  6. References

Quick answer. Cells recorded from one animal, and events recorded from one cell, are not independent. To compare genotypes or treatments given to whole animals, summarise each cell (for example its median mEPSC amplitude), average cells within each animal, and test animals as n (or, with more than 3 animals per group, fit a mixed model with an animal random effect and t-based tests; Python’s statsmodels MixedLM reports z-tests, which are too liberal with few animals, so in Python use the per-animal means). Pooling all events into one cumulative distribution and running a Kolmogorov–Smirnov test, which assumes independent values, found a “significant” difference in 78.2% of our simulated studies (5 mice per group, 4 neurons each) where none existed; with cells as n, 15.9%; with animals as n, 4.6%. When a drug is applied to the same cell, compare before and after within each cell (paired), against a time-matched vehicle control for rundown, then summarise per animal. Report the number of cells and the number of animals.

Terms used below. Patch clamp (whole-cell recording): recording the currents of one neuron through a glass electrode. mEPSC: miniature excitatory postsynaptic current, a small spontaneous event; amplitude in pA, frequency in Hz. Event: one detected mEPSC. Cumulative distribution plot: the share of events below each amplitude. Kolmogorov–Smirnov (KS) test: compares two distributions; valid only for independent values. Median per cell: the typical event amplitude of one neuron. Log scale: natural logarithm here; exp() of a difference gives a ratio. Mixed model: a regression with random effects for animal and cell (and slice), so that values from one animal are not treated as independent; t-based tests (Satterthwaite) suit few animals. Paired test: compares two measurements from the same cell. Access resistance: the electrical resistance of the electrode–cell connection; high values distort recordings. Welch’s t-test: compares two groups without assuming equal spreads. 95% confidence interval (CI): the range of values compatible with the data. Power: the chance of detecting an effect that is really there. False positive: a “significant” result when there is no real effect.

Which analysis for your question

Question Analysis Report
Do mEPSC amplitudes differ between genotypes? Median per cell, average per animal, Welch’s t-test on log values with animals as n; or, with more than 3 animals per group, a mixed model with an animal random effect and t-based tests Ratio with 95% CI, n animals and n cells
Do mEPSC frequencies differ? Events per cell over a fixed time, averaged per animal (log only if no cell has zero events), Welch’s t-test with animals as n; a count mixed model’s z-tests are too liberal with a handful of animals Ratio or difference with 95% CI
Does a drug change currents in the same cell? Change per cell (the log ratio of the current magnitudes, after
Does the shape of the amplitude distribution differ? Per-cell summaries (one quantile chosen in advance, or several with a correction) compared with animals as n; show the cumulative plot as a description As above, per quantile
Cells from several slices per animal Average per slice, then per animal, or a mixed model with animal and slice As above
Excluding unstable recordings Criteria set in advance (access resistance, holding current, stability), applied blind to group Number excluded per group

Aarts and colleagues found that 53% of 314 neuroscience papers had designs “in which multiple observations are collected from a single research object (for example, multiple neurons from one animal)” (Aarts et al. 2014). Galbraith and colleagues describe the pooled approach, in which “the data obtained from individual synapses are pooled to create a single large dataset”, and warn that assuming each measurement is independent “is not valid” (Galbraith et al. 2010). Yu and colleagues show how mixed-effects models with animal-specific random effects handle this clustering (Yu et al. 2022). For repeated measurements on the same unit, Lazic notes that data are “typically analysed with a paired-samples t-test if there are only two conditions” (Lazic 2010). eNeuro asks authors for the “number of individual measurements, number of animals, number of slices” (eNeuro), and ARRIVE 2.0 asks authors to “specify if these criteria were established a priori” for exclusions (Percie du Sert et al. 2020).

Worked example: mEPSC amplitudes in WT and KO mice with no real difference

Constructed data: mEPSC amplitudes from 4 neurons in each of 5 wild-type (WT) and 5 knockout (KO) mice, 200 events per neuron (8,000 events). By design, both genotypes have the same typical amplitude, 15 pA. Mice differ a little (a standard deviation of 0.10 on the log scale), neurons within a mouse more (0.15), and events within a neuron are right-skewed (0.45). The random seed was the first one tried and was not chosen for its result. Stored code and data: mepsc.csv, model.py, make_data.py, analysis.py, analysis.R and the analysis output; analysis.py and analysis.R print the same output.

Analysis Result
All events pooled (4,000 vs 4,000), KS test D = 0.0585, p = 2.3 × 10⁻⁶ (a misleading “KO amplitudes differ”)
Neurons as n (20 vs 20), median per neuron, Welch’s t-test KO ÷ WT 1.06, p = 0.27
Mice as n (5 vs 5) KO ÷ WT 1.06 (95% CI 0.92 to 1.23), p = 0.34
Median amplitude, all events WT 15.2 pA, KO 15.9 pA

The cumulative distributions of pooled events look slightly shifted, and with 8,000 events the KS test calls that certain; but the shift comes from which neurons and mice happened to be recorded. With mice as n, the difference is small and the interval includes no change. In 10,000 simulated studies of this design (simulation.py, the simulation output):

Scenario Mice per group All events pooled (KS) Neurons as n Mice as n
No genotype difference 5 78.2% 15.9% 4.6% (false positives)
No genotype difference 8 78.5% 16.2% 5.4% (false positives)
KO amplitude 15% smaller 5 97.1% 72.2% 40.5% (power)
KO amplitude 15% smaller 8 99.2% 87.3% 65.8% (power)

Pooled events give false positives in nearly 4 of 5 studies with no difference, and more mice do not help; neurons as n give about three times the intended rate. Mice as n keep false positives at 5%; with 8 mice per group a 15% change was still detected only 65.8% of the time, so plan more animals for effects that small.

The code expects one row per event with columns genotype (WT or KO), mouse, cell and amplitude_pA (exported from your event detection software); rename your columns and labels to match, and run the code in the folder that holds the CSV file. Python needs NumPy, pandas and SciPy; the R code uses base R only.

# Condensed: analysis.py also gives the pooled KS test and the neurons-as-n comparison
import numpy as np, pandas as pd
from scipy import stats

d = pd.read_csv("mepsc.csv")
cell = d.groupby(["genotype", "mouse", "cell"]).amplitude_pA.median().reset_index()   # one median per neuron
mouse = cell.assign(l=np.log(cell.amplitude_pA)).groupby(["genotype", "mouse"]).l.mean().reset_index()   # one value per mouse
k = mouse.genotype == "KO"
t = stats.ttest_ind(mouse.l[k], mouse.l[~k], equal_var=False)
print(np.exp(mouse.l[k].mean() - mouse.l[~k].mean()), np.exp(t.confidence_interval()), t.pvalue)   # 1.06, 0.92 to 1.23, p = 0.34
d <- read.csv("mepsc.csv")
cell <- aggregate(amplitude_pA ~ genotype + mouse + cell, data = d, FUN = median)       # one median per neuron
mouse <- aggregate(log(amplitude_pA) ~ genotype + mouse, data = cell, FUN = mean)      # one value per mouse
names(mouse)[3] <- "l"; k <- mouse$genotype == "KO"; tt <- t.test(mouse$l[k], mouse$l[!k])
exp(c(ratio = mean(mouse$l[k]) - mean(mouse$l[!k]), tt$conf.int)); tt$p.value            # 1.06, 0.92 to 1.23, p = 0.34
# with lme4 and lmerTest (not base R), on the per-neuron medians: lmer(log(amplitude_pA) ~ genotype + (1 | mouse), data = cell)

Before you analyse

  1. Set inclusion criteria in advance (for example access resistance, holding current, stability over the recording) and apply them blind to group; report how many cells each criterion removed.
  2. Plan the number of animals, not cells; record several cells per animal for precision, and report both numbers (what counts as n).
  3. Summarise events within each cell first (median amplitude, frequency over a fixed time), using the same detection threshold and recording length for every cell.
  4. Use cumulative distribution plots as descriptions, with one curve per cell or per animal; compare groups on per-cell or per-animal summaries.
  5. For drug applications, keep the pairing (paired vs unpaired): the same cell before and after, with a time-matched vehicle control for drift.

Check what an AI assistant ran

  1. The assistant ran a KS test on pooled events from all cells. Ask for per-cell summaries compared with animals as n.
  2. The assistant used cells as n for a genotype comparison. Ask for one value per animal, or, with more than 3 animals per group, a mixed model with an animal random effect and t-based tests.
  3. The assistant compared drug and baseline as two independent groups. Ask for a paired comparison within each cell.
  4. The assistant reported only the number of cells. Ask for the number of animals too.

Report it

mEPSCs were detected with a threshold of [5] pA over [5] min per neuron; neurons with access resistance above [25] MΩ were excluded, as set in advance ([2] WT and [1] KO neurons). The median amplitude of each neuron was log-transformed and averaged per mouse, and genotypes were compared with Welch’s t-test (mouse as the unit; [18] WT and [19] KO neurons analysed after exclusions, from [5] mice per genotype; R [4.3.3]).

For a drug applied in the same neurons: the change in each neuron (log of |after| ÷ |before|, or after − before if the current changed sign) was averaged per mouse, and drug-treated neurons were compared with time-matched vehicle-treated neurons with Welch’s t-test across mice ([n] mice per group).

mEPSC amplitude did not differ clearly between genotypes (KO ÷ WT [1.06], 95% CI [0.92] to [1.23]; p = [0.34]).

Replace the bracketed values with your own.

References

  • Aarts E, Verhage M, Veenvliet JV, Dolan CV, van der Sluis S (2014). A solution to dependency: using multilevel analysis to accommodate nested data. Nature Neuroscience 17:491–496. doi:10.1038/nn.3648
  • Galbraith S, Daniel JA, Vissel B (2010). A study of clustered data and approaches to its analysis. Journal of Neuroscience 30:10601–10608. doi:10.1523/JNEUROSCI.0362-10.2010
  • Yu Z, Guindani M, Grieco SF, Chen L, Holmes TC, Xu X (2022). Beyond t test and ANOVA: applications of mixed-effects models for more rigorous statistical analysis in neuroscience research. Neuron 110:21–35. doi:10.1016/j.neuron.2021.10.030
  • Lazic SE (2010). The problem of pseudoreplication in neuroscientific studies: is it affecting your analysis? BMC Neuroscience 11:5. doi:10.1186/1471-2202-11-5
  • Society for Neuroscience. eNeuro information for authors (checked 12 November 2026). eneuro.org
  • Percie du Sert N, Hurst V, Ahluwalia A, et al. (2020). The ARRIVE guidelines 2.0: updated guidelines for reporting animal research. PLOS Biology 18:e3000410. doi:10.1371/journal.pbio.3000410

How this page was made

  • Written and published by Licklider. Recommendations cite peer-reviewed methods papers, journal guidance and the ARRIVE 2.0 guidelines listed under References; cited passages were checked against the source text.
  • The worked example uses constructed data. Its numbers were produced by stored code (Python 3.13 with SciPy 1.18.1; R 4.3.3, base R), and the two languages print identical output; the simulation was run in Python.
  • Separate review passes checked the statistics, the citations and readability before publication.