1

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)
Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62
Manuel
  • 11
  • 1
  • This is because you are writing `a = [1:50]`. That makes a vector of vectors. Just write `a = 1:50`, then at least your last example should work. Writing `[x]` always creates a vector with `x` as an element. In your case, it creates a vector with one element that is a range. – DNF Mar 05 '23 at 15:34

2 Answers2

0

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)
DNF
  • 11,584
  • 1
  • 26
  • 40
0

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
Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62