Hello all.
I am writing some code that adds syntax sugar to subsetting dataframes.
I want to pass :(:SepalLength .> (:SepalWidth .* 2))
and df
into a function and it create a BitVector by evaluating df.SepalLength .> (df.SepalWidth .* 2)
.
I created a function that turns
:(:SepalLength .> (:SepalWidth .* 2))
into
:(df.SepalLength .> (df.SepalWidth .* 2))
.
However, when I try evaluating the new expression with eval()
I run into an error because it evaluates it at the global scope and df
is not defined.
At this time the only way I know how to overcome this issue is by evaluating an expression within a local scope. Is this possible? If not, is there another way to approach this problem to get similar results?
Here is the function. I’m sure there are many issues with it, but the part I am mainly concerned about is evaluating the newly created expression to return a BitVector. Other feedback is welcomed too. Thank you all for your time and aid.
NOTE: I know DataFramesMeta exists. This is for something different.
function subsettingExpressionToBitVector(df::DataFrame, ex::Expr)
newCollec = []
for expression in ex.args
if typeof(expression) <: Expr
expression = subsettingExpressionToBitVector(df, expression)
end
if typeof(expression) <: QuoteNode
if eval(expression) ∈ propertynames(df)
column = propertynames(df)[eval(expression) .== propertynames(df)][1]
expression = Expr(:., Symbol("df"), QuoteNode(column))
end
end
push!(newCollec, expression)
end
newExpr = Expr(:call, newCollec...)
return eval(newExpr) # Using eval() is the issue.
end