# How to filter concatenated anndata object?

**URL:** https://discourse.scverse.org/t/how-to-filter-concatenated-anndata-object/2159
**Category:** Help
**Created:** [March 14, 2024, 6:15pm UTC](https://discourse.scverse.org/t/how-to-filter-concatenated-anndata-object/2159 "2024-03-14T18:15:12Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![st4302](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/st4302/32/986_2.png) [@st4302](https://discourse.scverse.org/u/st4302)
#### Post date: [March 14, 2024, 6:15pm UTC](https://discourse.scverse.org/t/how-to-filter-concatenated-anndata-object/2159/1 "2024-03-14T18:15:12Z")

</div>

Hello,

I concatenated several samples in one anndata object as shown here:  
S1.obs[‘sample’]=“S1”

S2.obs[‘sample’]=“S2”

S3.obs[‘sample’]=“S3”

# merge into one object.

adata = S1.concatenate(S2, S3,)

Then I did the QC steps and the violin plots in order to decide how to filter the object. Since I have 3 samples I am using different parameters for each. Does the below look correct?

keep\_S1 = (adata.obs[‘n\_genes\_by\_counts’] \< 5000) & (adata.obs[‘sample’] == ‘S1’)  
keep\_S2 = (adata.obs[‘n\_genes\_by\_counts’] \< 6000) & (adata.obs[‘sample’] == ‘S2’)  
keep\_S3 = (adata.obs[‘n\_genes\_by\_counts’] \< 4000) & (adata.obs[‘sample’] == ‘S3’)

# keep both sets of cells

keep = (keep\_S1 ) | (keep\_S2 ) | (keep\_S3 )  
adata = adata[keep, :]

print(“Remaining cells %d”%adata.n\_obs)

Does that seem correct?

Thank you

---

<div class="post-metadata">

### Author: ![ivirshup](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/ivirshup/32/160_2.png) [@ivirshup](https://discourse.scverse.org/u/ivirshup)
#### Post date: [March 15, 2024, 1:20pm UTC](https://discourse.scverse.org/t/how-to-filter-concatenated-anndata-object/2159/2 "2024-03-15T13:20:21Z")

</div>

I think it’s a little strange to combine the data, then filter them separately, but otherwise I think this is doing what you want.

I would also suggest doing:

```python
adata = sc.concat([S1, S2, S3], keys=["S1", "S2", "S3"], label = "sample")

```

Instead of `S{n}.obs["sample"] = "S{n}"` and `S1.concatenate`.

Is there a reason you think this code may be incorrect?

---

<div class="post-metadata">

### Author: ![st4302](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/st4302/32/986_2.png) [@st4302](https://discourse.scverse.org/u/st4302)
#### Post date: [March 15, 2024, 1:44pm UTC](https://discourse.scverse.org/t/how-to-filter-concatenated-anndata-object/2159/3 "2024-03-15T13:44:10Z")

</div>

Thank you for replying. I am just relatively new to scanpy and I am still trying to understand how to handle the anndata object.  
I tried to combine them first because when doing the QC and violin plots I could do it only on one object. Is it strange because you think I should use the same filtering criteria for all the samples?  
Is the code that you included for concatenating the data just faster than what I did or does it produce different results?

---

<div class="post-metadata">

### Author: ![ivirshup](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/ivirshup/32/160_2.png) [@ivirshup](https://discourse.scverse.org/u/ivirshup)
#### Post date: [March 15, 2024, 2:06pm UTC](https://discourse.scverse.org/t/how-to-filter-concatenated-anndata-object/2159/4 "2024-03-15T14:06:13Z")

</div>

> [@st4302](#):
>
> I tried to combine them first because when doing the QC and violin plots I could do it only on one object. Is it strange because you think I should use the same filtering criteria for all the samples?

I don’t think there’s anything wrong with what you did, and I see how it would make some plotting easier. I think it’s mostly that the plots I typically make for qc don’t facet by sample well.

> Is the code that you included for concatenating the data just faster than what I did or does it produce different results?

It’s a little faster, but more importantly `AnnData.concatenate` will be deprecated in favor of the `concat` function.

There are slight differences, IIRC mostly when you use `join="outer"`.

---

<div class="post-metadata">

### Author: ![st4302](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/st4302/32/986_2.png) [@st4302](https://discourse.scverse.org/u/st4302)
#### Post date: [March 15, 2024, 6:00pm UTC](https://discourse.scverse.org/t/how-to-filter-concatenated-anndata-object/2159/5 "2024-03-15T18:00:01Z")

</div>

When I did it like this:

> adata = sc.concat([S1, S2, S3], keys=[“S1”, “S2”, “S3”], label = “sample”)

I actually lost all the .var information.

---

<div class="post-metadata">

### Author: ![ivirshup](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/ivirshup/32/160_2.png) [@ivirshup](https://discourse.scverse.org/u/ivirshup)
#### Post date: [March 18, 2024, 1:25pm UTC](https://discourse.scverse.org/t/how-to-filter-concatenated-anndata-object/2159/6 "2024-03-18T13:25:56Z")

</div>

Ah that’s right, to determine which `var` things to keep you’ll need to specify the `merge` argument. Probably `merge="same"` or `merge="unique"` here.

See also:

> **[Concatenation](https://anndata.readthedocs.io/en/latest/concatenation.html#merging)**
>
> With concat(), AnnData objects can be combined via a composition of two operations: concatenation and merging. Concatenation is when we keep all sub elements of each object, and stack these element...
