# DataFramesMeta custom filter: by groups of A, apply filter on B

**URL:** https://discourse.julialang.org/t/dataframesmeta-custom-filter-by-groups-of-a-apply-filter-on-b/24557
**Category:** Data
**Created:** [May 24, 2019, 8:13am UTC](https://discourse.julialang.org/t/dataframesmeta-custom-filter-by-groups-of-a-apply-filter-on-b/24557 "2019-05-24T08:13:19Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![floswald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/floswald/32/195_2.png) [@floswald](https://discourse.julialang.org/u/floswald)
#### Post date: [May 24, 2019, 8:13am UTC](https://discourse.julialang.org/t/dataframesmeta-custom-filter-by-groups-of-a-apply-filter-on-b/24557/1 "2019-05-24T08:13:19Z")

</div>

I need to subset a dataframe by groups. that is, in each group there is a different filtering condition to apply. here is a MWE

```julia
using DataFrames, DataFramesMeta

julia> df = DataFrame(A = repeat(1:3,3), B = rand(1:9,9),C = rand(9))
9×3 DataFrame
│ Row │ A │ B │ C │
│ │ Int64 │ Int64 │ Float64 │
├─────┼───────┼───────┼──────────┤
│ 1 │ 1 │ 1 │ 0.676259 │
│ 2 │ 2 │ 5 │ 0.675797 │
│ 3 │ 3 │ 9 │ 0.597738 │
│ 4 │ 1 │ 6 │ 0.593364 │
│ 5 │ 2 │ 2 │ 0.156473 │
│ 6 │ 3 │ 7 │ 0.859696 │
│ 7 │ 1 │ 9 │ 0.951905 │
│ 8 │ 2 │ 6 │ 0.196368 │
│ 9 │ 3 │ 1 │ 0.292369 │

```

Suppose for each group of A I want to discard the row where `B` is largest within that group:

```julia

julia> @linq df |>
           groupby(:A) |>
               where( :B != maximum(:B) )
GroupedDataFrame with 3 groups based on key: A
First Group (3 rows): A = 1
│ Row │ A │ B │ C │
│ │ Int64 │ Int64 │ Float64 │
├─────┼───────┼───────┼──────────┤
│ 1 │ 1 │ 1 │ 0.676259 │
│ 2 │ 1 │ 6 │ 0.593364 │
│ 3 │ 1 │ 9 │ 0.951905 │
⋮
Last Group (3 rows): A = 3
│ Row │ A │ B │ C │
│ │ Int64 │ Int64 │ Float64 │
├─────┼───────┼───────┼──────────┤
│ 1 │ 3 │ 9 │ 0.597738 │
│ 2 │ 3 │ 7 │ 0.859696 │
│ 3 │ 3 │ 1 │ 0.292369 │

```

that’s not it. let me try creating a grouped dataframe and work on that:

```julia

julia> g = @linq df |>
           groupby(:A)

julia> filter(x -> (x[:B] < 9),g[1])
2×3 DataFrame
│ Row │ A │ B │ C │
│ │ Int64 │ Int64 │ Float64 │
├─────┼───────┼───────┼──────────┤
│ 1 │ 1 │ 1 │ 0.676259 │
│ 2 │ 1 │ 6 │ 0.593364 │

```

that works! of course I cannot hardcode `9`, so i must find out what the largest value is:

```julia

julia> filter(x -> (x[:B] < maximum(x[:B])),g[1])
0×3 DataFrame

julia> filter(x -> (x[:B] .< maximum(x[:B])),g[1])
0×3 DataFrame

```

what’s the mistake I’m making? thanks

---

<div class="post-metadata">

### Author: ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)
#### Post date: [May 25, 2019, 3:02pm UTC](https://discourse.julialang.org/t/dataframesmeta-custom-filter-by-groups-of-a-apply-filter-on-b/24557/2 "2019-05-25T15:02:04Z")

</div>

`where` filters groups, not rows. So it can’t used for what you’re trying to do. That should probably change, please file an issue in DataFramesMeta.

For now you can do this:

```julia
map(gd) do d
    d[d.B .< maximum(d.B), :]
end

```

(`filter` inside the `do` will also work, but you need to store `maximum(d.B)` to avoid recomputing it for each row.)

---

<div class="post-metadata">

### Author: ![floswald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/floswald/32/195_2.png) [@floswald](https://discourse.julialang.org/u/floswald)
#### Post date: [May 27, 2019, 5:48pm UTC](https://discourse.julialang.org/t/dataframesmeta-custom-filter-by-groups-of-a-apply-filter-on-b/24557/3 "2019-05-27T17:48:58Z")

</div>

> [@nalimilan](#):
>
> map(gd) do d d[d.B .\< maximum(d.B), :] end

thanks! thats pretty cool with the map actually (and makes a lot of sense, now that i think about it).

---

<div class="post-metadata">

### Author: ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)
#### Post date: [May 27, 2019, 6:26pm UTC](https://discourse.julialang.org/t/dataframesmeta-custom-filter-by-groups-of-a-apply-filter-on-b/24557/4 "2019-05-27T18:26:11Z")

</div>

Does `maximum(d.B` inside the map run the function multiple times? Is the compiler smart enough to figure out not to re-run the function over and over again? At a deeper level, will this get cached in the CPU so that multiple calls are negligible?

---

<div class="post-metadata">

### Author: ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)
#### Post date: [May 27, 2019, 6:44pm UTC](https://discourse.julialang.org/t/dataframesmeta-custom-filter-by-groups-of-a-apply-filter-on-b/24557/5 "2019-05-27T18:44:08Z")

</div>

`maximum` is called once for each group, so that should be reasonably efficient. It could be made a bit faster by returning a view (using `view`) instead of a new data frame.
