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:
# 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"
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?
(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.
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)
DataFramesMeta.jl is useful here
@rtransform df :color = :column1 < :column2 ? "red" : "green"
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.
Sorry, this is a response to rocco_sprmnt21.
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.(df.column1 .< df.column2, "red", "green")
(Another thread about broadcasting the ternary operator: Is this an expected behavior of rand.()?)
Two more options:
df.color .= [c ? "red" : "green" for c in (df.column1 .< df.column2)]
df.color .= map(df.column1 .< df.column2) do c
c ? "red" : "green"