# Dataframe filtering based on conditions comparing one column to other columns

**URL:** https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802
**Category:** New to Julia
**Tags:** indexing, dataframes
**Created:** [November 2, 2021, 11:46am UTC](https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802 "2021-11-02T11:46:44Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![CompulsoryCoffee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compulsorycoffee/32/30434_2.png) [@CompulsoryCoffee](https://discourse.julialang.org/u/CompulsoryCoffee)
#### Post date: [November 2, 2021, 11:46am UTC](https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802/1 "2021-11-02T11:46:44Z")

</div>

Hi,

I am trying to apply a condition to a selection of columns based on one column and the resulting dataframe.

Here is an example:

```julia
df
10×5 DataFrame
 Row │ x1 x2 x3 x4 x5       
     │ Float64 Float64 Float64 Float64 Float64  
─────┼──────────────────────────────────────────────────────
   1 │ 0.0981372 0.0804932 0.513072 0.450144 0.52068
   2 │ 0.630371 0.968476 0.556494 0.493968 0.347883
   3 │ 0.64709 0.643473 0.670181 0.765159 0.609178
   4 │ 0.394128 0.437874 0.782004 0.15423 0.58172
   5 │ 0.373165 0.783987 0.0135377 0.587961 0.328194
   6 │ 0.0741134 0.889961 0.0378584 0.345939 0.567646
   7 │ 0.311853 0.122679 0.0823076 0.615964 0.271999
   8 │ 0.880035 0.553531 0.491427 0.505312 0.50748
   9 │ 0.285774 0.187106 0.547379 0.193307 0.894698
  10 │ 0.0776693 0.0266613 0.658087 0.0714121 0.667334

```

How can I apply a filter (.\< df.x5) on the first 2 columns and get all the columns as a result?

I tried this but it is giving me a boolean of the first 2 columns.

```julia
df[:, Not(Between(:x3,end))] .> df.x5

10×2 DataFrame
 Row │ x1 x2    
     │ Bool Bool  
─────┼──────────────
   1 │ false false
   2 │ true true
   3 │ true true
   4 │ false false
   5 │ true true
   6 │ false true
   7 │ true false
   8 │ true true
   9 │ false false
  10 │ false false

```

I would like a resulting dataframe containing all the columns from x1 to x5 with the filtered row values

I hope this is clear enough …

Thanks!

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [November 2, 2021, 12:12pm UTC](https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802/2 "2021-11-02T12:12:49Z")

</div>

There are loads of ways of doing this, maybe the simplest one is:

```julia
df[(df.x1 .> df.x5) .& (df.x2 .> df.x5), :]

```

---

<div class="post-metadata">

### Author: ![CompulsoryCoffee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compulsorycoffee/32/30434_2.png) [@CompulsoryCoffee](https://discourse.julialang.org/u/CompulsoryCoffee)
#### Post date: [November 2, 2021, 12:26pm UTC](https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802/3 "2021-11-02T12:26:00Z")

</div>

Thanks,

If I have more columns to do the filtering on, is there a way to set a condition that would exclude a certain number of columns (e.g. Not(:x3,end)) from the filtering while keeping them in the output?

---

<div class="post-metadata">

### Author: ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)
#### Post date: [November 2, 2021, 12:51pm UTC](https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802/4 "2021-11-02T12:51:47Z")

</div>

Here’s one way:

```julia
julia> using DataFrames

julia> df = DataFrame(rand(8,5), :auto)

8×5 DataFrame
 Row │ x1 x2 x3 x4 x5       
     │ Float64 Float64 Float64 Float64 Float64  
─────┼────────────────────────────────────────────────────
   1 │ 0.39997 0.315291 0.564286 0.181416 0.272942
   2 │ 0.406449 0.136713 0.869279 0.856068 0.653893
   3 │ 0.642072 0.371682 0.581247 0.94918 0.106684
   4 │ 0.0550675 0.778223 0.953143 0.0357677 0.562967
   5 │ 0.0294628 0.146155 0.480069 0.237095 0.586552
   6 │ 0.621742 0.456891 0.635841 0.308975 0.630643
   7 │ 0.267329 0.634341 0.269092 0.169279 0.629037
   8 │ 0.864646 0.624525 0.553297 0.32189 0.245451

julia> columns = Cols(:x5, Not(Between(:x3, ncol(df))));

julia> myfilter(x, v...) = all(<(x), v);

julia> filter(columns => myfilter, df) # Or subset(df, columns => ByRow(myfilter))

3×5 DataFrame
 Row │ x1 x2 x3 x4 x5       
     │ Float64 Float64 Float64 Float64 Float64  
─────┼───────────────────────────────────────────────────
   1 │ 0.406449 0.136713 0.869279 0.856068 0.653893
   2 │ 0.0294628 0.146155 0.480069 0.237095 0.586552
   3 │ 0.621742 0.456891 0.635841 0.308975 0.630643
```

---

<div class="post-metadata">

### Author: ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)
#### Post date: [November 2, 2021, 1:06pm UTC](https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802/5 "2021-11-02T13:06:08Z")

</div>

Other solutions:

```julia
filter(df) do row
    all(<(row.x5), row[Not(Between(:x3, end))])
end

```

```julia
columns = names(df, Not(Between(:x3, ncol(df))))
subset(df, (vcat.(columns, "x5") .=> .<)...)

```

---

<div class="post-metadata">

### Author: ![CompulsoryCoffee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/compulsorycoffee/32/30434_2.png) [@CompulsoryCoffee](https://discourse.julialang.org/u/CompulsoryCoffee)
#### Post date: [November 4, 2021, 4:17pm UTC](https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802/6 "2021-11-04T16:17:51Z")

</div>

Thanks! - went for the “filter - row” solution.

Just out of curiosity - could you think of something with DataFramesMeta? using @rsubset maybe?

---

<div class="post-metadata">

### Author: ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)
#### Post date: [November 5, 2021, 10:23am UTC](https://discourse.julialang.org/t/dataframe-filtering-based-on-conditions-comparing-one-column-to-other-columns/70802/7 "2021-11-05T10:23:08Z")

</div>

Note that the filter with do block is the slowest solution I think, but maybe it’s fine for your use case.

I don’t think DataFramesMeta helps in this case (its support for multi-column arguments is a bit rudimentary for now). The best I can come up with is

```julia
columns = Cols(:x5, Not(Between(:x3, ncol(df))))
myfilter(x, v...) = all(<(x), v)
@subset df $(columns => ByRow(myfilter))

```

which you could write in one line at the cost of readability…

Maybe @pdeffebach has a better idea?
