Pass Vector to @subset

Long story short, how do I pass a vector to @subset.

# From this...
@subset(iris, VectorIPassToTheFunction) )
# To this...
@subset(iris, :SepalLength .> 6, :SepalWidth .> 3) )

Long story:
In the DataFramesMeta package you can subset using the @subset macro. I would like to pass in a vector for the macro to read. However, I haven’t found a way to do so. See below:

# Example Data
using RDatasets
rds = RDatasets
iris = rds.dataset("datasets", "iris");

using DataFramesMeta
# Normal Method
julia> @subset(iris, :SepalLength .> 5, :SepalLength .> 4) 
118×5 DataFrame
 Row │ SepalLength  SepalWidth  PetalLength  PetalWidth  Species   
     │ Float64      Float64     Float64      Float64     String    
─────┼─────────────────────────────────────────────────────────────
   1 │         5.1         3.5          1.4         0.2  setosa
   2 │         5.4         3.9          1.7         0.4  setosa
   3 │         5.4         3.7          1.5         0.2  setosa
  ⋮  │      ⋮           ⋮            ⋮           ⋮           ⋮
 117 │         6.2         3.4          5.4         2.3  virginica
 118 │         5.9         3.0          5.1         1.8  virginica
                                                   113 rows omitted

When I try to create a vector of commands to pass in, I am met with the following:

julia> [:SepalLength .> 5, :SepalLength .> 4]
ERROR: MethodError: no method matching isless(::Int64, ::Symbol)
...

To me, this error makes sense because it is trying to evaluate the Symbol and integer comparison first. So, I tried the following:

# Make an Expression
julia> theSubVec = :[:SepalLength .> 5, :SepalLength .> 4]

# Get it's arguments
julia> theSubVec.args
2-element Vector{Any}:
 :(:SepalLength .> 5)
 :(:SepalLength .> 4)

# Try passing them in.
julia> @subset(iris, theSubVec.args)
ERROR: ArgumentError: length 2 of vector returned from function #516 is different from number of rows 150 of the source data frame.

# Try splatting the arguments in.
julia> @subset(iris, theSubVec.args...)
ERROR: syntax: "..." expression outside call around /Users/user/.julia/packages/DataFramesMeta/yzaoq/src/parsing.jl:216
Stacktrace:
 [1] top-level scope
   @ REPL[202]:1

# Try placing them in manually
julia> @subset(iris, theSubVec.args[1], theSubVec.args[2] )
ERROR: ArgumentError: functions passed to `subset` must return an AbstractVector.

# Try having them be evaluated in place.
julia> @subset(iris, eval(theSubVec.args[1]), eval(theSubVec.args[2]) )
ERROR: MethodError: no method matching isless(::Int64, ::Symbol)

Any help is appreciated. Thank you!

You can’t pass arbitrary expressions to macros like that, unfortunately.

DataFramesMeta.jl is not the tool for this. Rather, you should use the underlying DataFrames.jl system that DataFramesMeta.jl builds off of.

To do these kinds of expressions programmatically, make a vector of pairs

julia> df = DataFrame(x = rand(10), y = rand(10));

julia> t = [:x => ByRow(>(.5)), :y => ByRow(>(.6))]
2-element Vector{Pair{Symbol, ByRow{Base.Fix2{typeof(>), Float64}}}}:
 :x => ByRow{Base.Fix2{typeof(>), Float64}}(Base.Fix2{typeof(>), Float64}(>, 0.5))
 :y => ByRow{Base.Fix2{typeof(>), Float64}}(Base.Fix2{typeof(>), Float64}(>, 0.6))

julia> subset(df, t)
3×2 DataFrame
 Row │ x         y        
     │ Float64   Float64  
─────┼────────────────────
   1 │ 0.616501  0.70594
   2 │ 0.716532  0.604494
   3 │ 0.594781  0.930921

If you know what the operation is but not what the column name is, you can work with name programmatically.

julia> x_name = :x; y_name = :y;

julia> @rsubset(df, $x_name > .5, $y_name > .6)
3×2 DataFrame
 Row │ x         y        
     │ Float64   Float64  
─────┼────────────────────
   1 │ 0.616501  0.70594
   2 │ 0.716532  0.604494
   3 │ 0.594781  0.930921

Thank you for confirming this for me.

It is very appreciated.