# 08. Comparing Cell Composition and Expression Across Conditions

> Separate changes in cell-type abundance from expression changes within a cell type, then aggregate cells by independent person or sample before testing condition effects.

Single-cell condition comparisons contain two different questions: **which cells became more or less abundant**, and **which genes changed within the same cell type**. One result cannot answer both.

A **donor** is the independent person or biological organism that provided the cells. Thousands of cells from one donor still represent one independently observed organism.

> **Question for this lesson**: How can condition effects be tested while donors remain the sample size, even when there are thousands of cells?

## Separate composition from state

An increase in a T-cell signal after treatment can represent at least two scenes.

| question | what changed | required summary |
| --- | --- | --- |
| composition difference (differential abundance) | relative number or captured fraction of T cells | cell counts or fractions by sample and cell type |
| expression or state difference | expression within T cells | gene by sample counts for one cell type |

More T cells can increase tissue-level values of genes characteristic of T cells without any individual T cell expressing those genes more strongly. A gene that is relatively high or low in one cell group and helps identify that group is called a **marker gene**.

## The experimental unit is the donor, not the cell

Suppose three control patients and three treated patients each contribute 5,000 cells. The matrix has 30,000 rows, but only six independently treated experimental units.

Cells from one patient share genetics, collection, and processing conditions. They may also share a **batch**, a processing group defined by factors such as experiment date or instrument. Treating them as independent replicates ignores donor variation and inflates the sample size.

```text
incorrect n: 30,000 cells
n for the condition effect: 6 donors
```

Capturing more cells describes one donor more precisely. It does not add donors.

## Aggregate cell counts by donor

**Pseudobulk** is a table formed by summing cell-level counts by gene within one donor and cell type. For a T-cell comparison, sum raw counts by gene across T cells from each donor.

```python
pseudobulk[donor, gene] = sum(
    raw_count[cell, gene]
    for cell in cells
    if cell.donor == donor and cell.cell_type == "T cell"
)
```

This conceptual pseudocode produces a familiar gene by donor raw-count matrix.

| gene | control_1 | control_2 | control_3 | treated_1 | treated_2 | treated_3 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| IFNG | 142 | 119 | 155 | 380 | 290 | 412 |
| CCL5 | 811 | 760 | 902 | 990 | 870 | 1104 |

One column is the T-cell aggregate from one donor. Methods designed for replicated counts, such as DESeq2, edgeR, or limma, can then model donor variation. The principles in [Differential Expression Across Multiple Samples](/en/lessons/bulk-rna-deg/) apply again within a cell type.

The [GSE251845 differential-expression exercise](/en/practice/colorectal-deg-gse251845/#3-1-check-raw-counts-and-patient-pairs) shows how to match patient IDs with Tumour-Normal columns before running DESeq2 in a bulk paired design. The same sample-level join matters for single-cell pseudobulk.

## Marker discovery and condition testing are different

| analysis | comparison unit | question |
| --- | --- | --- |
| cluster marker | one cluster versus other clusters | Which genes distinguish this cluster? |
| expression comparison after donor-level aggregation | donors in condition A versus B | How does this cell type change by condition? |

Even when coordinates adjusted to align technical processing groups guide clustering, use raw counts with real donor and condition metadata for differential expression. A **Uniform Manifold Approximation and Projection** (UMAP) two-dimensional map and other adjusted coordinates are not expression counts.

## Compare composition per donor

Build a donor-level table before testing abundance.

| donor | condition | T cell | B cell | myeloid | stromal |
| --- | --- | ---: | ---: | ---: | ---: |
| C1 | control | 0.18 | 0.07 | 0.54 | 0.21 |
| C2 | control | 0.23 | 0.05 | 0.49 | 0.23 |
| T1 | treated | 0.61 | 0.08 | 0.21 | 0.10 |
| T2 | treated | 0.55 | 0.06 | 0.25 | 0.14 |

Fractions sum to one and are affected by dissociation and capture. Show donor-level distributions and cell counts rather than only one pooled percentage.

## Separate condition and batch by design

If all controls are processed Monday and all treated samples Tuesday, day and treatment are inseparable. No integration method can recover missing experimental information.

Mix conditions across batches when possible, preserve donor and sample IDs in cell metadata, and report donor counts, cells per donor, pairing, batch, minimum cells per pseudobulk, count layer, and statistical design.

## Summary

Compare composition with donor-level cell-type fractions. Compare expression by aggregating raw counts within cell type and donor. Thousands of cells are not thousands of biological replicates.

The core path is now complete: `cell-level measurement → cell and molecule addresses → count matrix → quality control → similar-cell groups → cell-type naming → sample-level comparison`. Use [Single-Cell Data Structures and File Formats](/en/reference/single-cell-data-structures/) when inspecting an object or handoff file.

---

### Sources

- Biological replicates in single-cell differential expression: [Squair et al., *Nature Communications* (2021)](https://www.nature.com/articles/s41467-021-25960-2)
- Single-cell condition-comparison best practices: [Heumos et al., *Nature Reviews Genetics* (2023)](https://www.nature.com/articles/s41576-023-00586-w)