eweiss
August 14, 2023, 6:10pm
1
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:
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
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
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.
2 Likes
Sukera
August 14, 2023, 6:11pm
2
(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.
The ternary operator ?
is not vectorized — the predicate must be a single (scalar) boolean value, not an array thereof.
5 Likes
This gives a result but I don’t think it’s what you’re looking for
df.color .= df.column1 < df.column2 ? "red" : "green"
you could use the ternary operator like this (to justify the title ):
transform(df,1:2=>ByRow((x,y)->x<y ? "red" : "green")=>"color")
or like this if you don’t like mini-lamguage
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)
1 Like
DataFramesMeta.jl is useful here
@rtransform df :color = :column1 < :column2 ? "red" : "green"
4 Likes
eweiss
August 14, 2023, 8:40pm
6
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.
eweiss
August 14, 2023, 8:42pm
8
Sorry, this is a response to rocco_sprmnt21.
bkamins
August 14, 2023, 10:33pm
10
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:
ifelse.(df.column1 .< df.column2, "red", "green")
2 Likes
(Another thread about broadcasting the ternary operator: Is this an expected behavior of rand.()? )
Dan
August 16, 2023, 12:43am
12
Two more options:
df.color .= [c ? "red" : "green" for c in (df.column1 .< df.column2)]
and
df.color .= map(df.column1 .< df.column2) do c
c ? "red" : "green"
end
2 Likes