ERROR: MethodError: no method matching isless(::Vector{UnitRange{Int64}}, ::Int64)

463 views Asked by At

I am new to Julia and I am struggling to compare the values stored in a vector with a integer (which is a threshold I want to use to determine if a certain condition is true or false). The actual values are stored as columns in a dataframe but the example below reproduces the same error.

using DataFrames
a= [1:50]
b= ByRow(a<25 ? "True" : "False")

I think the problem is that I am comparing an array with an integer. I thought applying the comparison row by row would give another vector with "True" or "False" values but it does not. If I broadcast the comparison I get the same error:

a= [1:50]
b= a.<25 ? "True" : "False")
ERROR: MethodError: no method matching isless(::UnitRange{Int64}, ::Int64)
2

There are 2 answers

1
DNF On

I'm not familiar with DataFrames, but you can fix your second example with a couple of corrections.

There is a trailing parenthesis in your expression, a= [1:50] b= a.<25 ? "True" : "False"). I'll assume that's not supposed to be there.

Here's a working solution:

a = 1:50
b = all(a.<25) ? "True" : "False"

Remove the brackets around 1:50, with the brackets you get a Vector{UnitRange}, but you just need a UnitRange.

After removing the brackets, a.<25 works, but it returns a vector, so you cannot use it as a condition. You need to add all or any to reduce it to just one Boolean value. Otherwise, what would a.<25 mean, if some are greater and some are less?

Now, a.<25 creates a temporary array. You may want to avoid that in some cases, then you can use an alternative formulation: all(<(25), a):

a = 1:50
b = all(<(25), a) ? "True" : "False"  # or any, if applicable

Edit: I see you actually want a vector of strings as output. In that case, either of these will work:

b = [(val<25 ? "True" : "False") for val in a]
b = ifelse.(a.<25, "True", "False")
b = (x->(x<25 ? "True" : "False")).(a)
b = map(x->(x<25 ? "True" : "False"), a)
0
Przemyslaw Szufel On

It has been already mentioned that [1:50] creates a one element Vector of UnitRanges. My best bet is that what you want is:

df = DataFrame(a=1:5)
df.b .= df.a .<= 3

And now yo have

julia> df
5×2 DataFrame
 Row │ a      b
     │ Int64  Bool
─────┼──────────────
   1 │     1   true
   2 │     2   true
   3 │     3   true
   4 │     4  false
   5 │     5  false