# Ternary Operator \`?:\` on a DataFrame :)

**URL:** <https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798>\
**Category:** New to Julia\
**Tags:** question, dataframes\
**Created:** [August 14, 2023, 6:10pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798 "2023-08-14T18:10:21Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![eweiss](https://avatars.discourse-cdn.com/v4/letter/e/b487fb/32.png) [@eweiss](https://discourse.julialang.org/u/eweiss)\
**Post date:** [August 14, 2023, 6:10pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/1 "2023-08-14T18:10:21Z")

</div>

I’m trying to use the ternary operator and get an error message:

> ERROR: ArgumentError: It is only allowed to pass a vector as a column of a DataFrame."

Here’s my code:

```julia
using DataFrames

# Sample DataFrame with two columns
df = DataFrame(column1 = [10, 5, 8, 3, 12],
               column2 = [7, 4, 9, 2, 15])
df.color = df.column1 < df.column2 ? "red" : "green"

```

I’ve tried

```julia
df.color .= df.column1 .< df.column2 ? "red" : "green"

```

and get this error message:

> ERROR: TypeError: non-boolean (BitVector) used in boolean context

I can get the answers I want with

```julia
df.color = ifelse.(df.column1 .< df.column2, "red", "green")

```

but I’d like to use the ternary ? : operator. Can someone explain the error messages to me?

Thanks.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 14, 2023, 6:11pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/2 "2023-08-14T18:11:56Z")

</div>

(I’ve edited the title of your question to be clearer to others what this topic is about 🙂 )

I suspect the first error occurs on the assignment; you presumably can’t assign a single value like `"red"` to a whole column in a dataframe. There is usually little to no implicit widening to arrays like that in Julia.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 14, 2023, 6:15pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/3 "2023-08-14T18:15:08Z")

</div>

> [@eweiss](#):
>
> `df.color .= df.column1 .< df.column2 ? "red" : "green"`

The ternary operator `?` is not vectorized — the predicate must be a single (scalar) boolean value, not an array thereof.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [August 14, 2023, 8:17pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/4 "2023-08-14T20:17:23Z")

</div>

This gives a result but I don’t think it’s what you’re looking for

```julia
df.color .= df.column1 < df.column2 ? "red" : "green"

```

you could use the ternary operator like this (to justify the title 😄):

```julia
 transform(df,1:2=>ByRow((x,y)->x<y ? "red" : "green")=>"color")

```

or like this if you don’t like mini-lamguage

```julia
 df.color = [c1 < c2 ? "red" : "green" for (c1,c2) in zip(df.column1 , df.column2)]
 df.color = [whichcol ? "red" : "green" for whichcol in (df.column1 .< df.column2)]

(df.column1 .< df.column2) .|> rog->rog ? "red" : "gren"

df.color=(c->c ? "red" : "gren").(df.column1 .< df.column2)

```

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [August 14, 2023, 8:37pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/5 "2023-08-14T20:37:17Z")

</div>

DataFramesMeta.jl is useful here

```julia
@rtransform df :color = :column1 < :column2 ? "red" : "green"

```

---

<div class="post-metadata">

**Author:** ![eweiss](https://avatars.discourse-cdn.com/v4/letter/e/b487fb/32.png) [@eweiss](https://discourse.julialang.org/u/eweiss)\
**Post date:** [August 14, 2023, 8:40pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/6 "2023-08-14T20:40:38Z")

</div>

Thanks. I tried the first bit of code and as you guessed, setting each row to the value of “green” isn’t what I’m looking for. I’ve learned something about Julia from your other suggestions.

---

<div class="post-metadata">

**Author:** ![eweiss](https://avatars.discourse-cdn.com/v4/letter/e/b487fb/32.png) [@eweiss](https://discourse.julialang.org/u/eweiss)\
**Post date:** [August 14, 2023, 8:41pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/7 "2023-08-14T20:41:35Z")

</div>

> [@pdeffebach](#):
>
> `@rtransform df :color = :column1 < :column2 ? "red" : "green"`

Neat.

---

<div class="post-metadata">

**Author:** ![eweiss](https://avatars.discourse-cdn.com/v4/letter/e/b487fb/32.png) [@eweiss](https://discourse.julialang.org/u/eweiss)\
**Post date:** [August 14, 2023, 8:42pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/8 "2023-08-14T20:42:12Z")

</div>

Sorry, this is a response to rocco\_sprmnt21.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 14, 2023, 9:32pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/9 "2023-08-14T21:32:58Z")

</div>

> [@rocco\_sprmnt21](#):
>
> `(df.column1 .< df.column2) .|> x->x ? "red" : "gren"`

Pretty nice.

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [August 14, 2023, 10:33pm UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/10 "2023-08-14T22:33:41Z")

</div>

This is an issue in Base Julia not DataFrames.jl. In my opinion a standard translation, if we want to stay with Base Julia, that can be vectorized is the `ifelse` function:

```julia
ifelse.(df.column1 .< df.column2, "red", "green")

```

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [August 16, 2023, 12:04am UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/11 "2023-08-16T00:04:40Z")

</div>

(Another thread about broadcasting the ternary operator: [Is this an expected behavior of rand.()?](https://discourse.julialang.org/t/is-this-an-expected-behavior-of-rand/97735))

---

<div class="post-metadata">

**Author:** ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)\
**Post date:** [August 16, 2023, 12:43am UTC](https://discourse.julialang.org/t/ternary-operator-on-a-dataframe/102798/12 "2023-08-16T00:43:38Z")

</div>

Two more options:

```julia
df.color .= [c ? "red" : "green" for c in (df.column1 .< df.column2)]

```

and

```julia
df.color .= map(df.column1 .< df.column2) do c
    c ? "red" : "green"
end

```
