Call a macro from within a funciton

I am working with DataFrames.jl and DataFramesMeta.jl (which I love).
So consider the following MWE, not directly related to my actual work:

using DataFrames, DataFramesMeta
grps = groupby(dff, :col1)
dff = DataFrame([[1,2,3],[4,5,6]], [:col1,:col2])
dd = @based_on(grps, count=length(:col2))

which produces the correct result. So of course, I wish to put this procedure into a function as follows:

function find(df::DataFrame, group_col::Symbol, selector::Symbol)
    grps = groupby(df, group_col)
    w_count_df = @based_on(grps, count=length(group_col))
end

dff = DataFrame([[1,2,3],[4,5,6]], [:col1,:col2])
dd = find(dff, :col1, :col2)

which produces an error because the macro expansion occurs before the call to the function:

julia> dd = find(dff, :col1, :col2)
ERROR: MethodError: no method matching length(::Symbol)
Closest candidates are:
  length(::Core.SimpleVector) at essentials.jl:596
  length(::Base.MethodList) at reflection.jl:852
  length(::Core.MethodTable) at reflection.jl:938
  ...
Stacktrace:
 [1] (::var"#288#289"{Symbol})(::SubDataFrame{DataFrame,DataFrames.Index,Array{Int64,1}}) at /Users/erlebach/.julia/packages/DataFramesMeta/c67UK/src/DataFramesMeta.jl:80
 [2] _combine(::var"#288#289"{Symbol}, ::GroupedDataFrame{DataFrame}, ::Nothing, ::Bool, ::Bool) at /Users/erlebach/.julia/packages/DataFrames/kwVTY/src/groupeddataframe/splitapplycombine.jl:1215
 [3] combine_helper(::Function, ::GroupedDataFrame{DataFrame}, ::Nothing; keepkeys::Bool, ungroup::Bool, copycols::Bool, keeprows::Bool) at /Users/erlebach/.julia/packages/DataFrames/kwVTY/src/groupeddataframe/splitapplycombine.jl:583
 [4] #combine#375 at /Users/erlebach/.julia/packages/DataFrames/kwVTY/src/groupeddataframe/splitapplycombine.jl:434 [inlined]
 [5] combine at /Users/erlebach/.julia/packages/DataFrames/kwVTY/src/groupeddataframe/splitapplycombine.jl:434 [inlined]
 [6] find(::DataFrame, ::Symbol, ::Symbol) at /Users/erlebach/covid_modeling_julia/julia_code/sir-julia/SIRsims/gordon_julia_code/household_workplaces_leon/drawNetwork.jl:22
 [7] top-level scope at none:0

So how would I make this work, WITHOUT modifying the @based_on macro? I can’t go make changes to existing macros every time I want to call a macro. I have read as much as I could understand. Thank you.

Not an answer to your question, but especially now with combine, select and transform in core DataFrames the answer to problems with DataFramesMeta can often be just don’t use it…

Your actual problem might of course be trickier, but from your MWE it seems that

 combine(groupby(dff, :col1), :col2 => length => :count)

does the trick

1 Like