Morpheu5
Morpheu5

Reputation: 2801

Malformed expression in DataFramesMeta.js when @selecting from DataFrame using a Symbol("x") expression

I have a Julia DataFrame which I can work with fine in any normal way. For example, let's say the df is

df = DataFrame(:x => [1,2,3], :y => [4,5,6], :z => [7,8,9]);

I can easily do

julia> df[:, :x]
3-element Vector{Int64}:
 1
 2
 3

julia> df[:, [:x, Symbol("y")]]
3×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

However, if I do the following I get a massive error.

julia> @select(df, Symbol("y"))
ERROR: LoadError: ArgumentError: Malformed expression in DataFramesMeta.jl macro
Stacktrace:
 [1] fun_to_vec(ex::Expr; gensym_names::Bool, outer_flags::NamedTuple{(Symbol("@byrow"), Symbol("@passmissing"), Symbol("@astable")), Tuple{Base.RefValue{Bool}, Base.RefValue{Bool}, Base.RefValue{Bool}}}, no_dest::Bool)
   @ DataFramesMeta ~/.julia/packages/DataFramesMeta/yzaoq/src/parsing.jl:289
 [2] (::DataFramesMeta.var"#47#48"{NamedTuple{(Symbol("@byrow"), Symbol("@passmissing"), Symbol("@astable")), Tuple{Base.RefValue{Bool}, Base.RefValue{Bool}, Base.RefValue{Bool}}}})(ex::Expr)
   @ DataFramesMeta ./none:0
 [3] iterate(::Base.Generator{Vector{Any}, DataFramesMeta.var"#47#48"{NamedTuple{(Symbol("@byrow"), Symbol("@passmissing"), Symbol("@astable")), Tuple{Base.RefValue{Bool}, Base.RefValue{Bool}, Base.RefValue{Bool}}}}})
   @ Base ./generator.jl:47
 [4] select_helper(x::Symbol, args::Expr)
   @ DataFramesMeta ~/.julia/packages/DataFramesMeta/yzaoq/src/macros.jl:1440
 [5] var"@select"(__source__::LineNumberNode, __module__::Module, x::Any, args::Vararg{Any})
   @ DataFramesMeta ~/.julia/packages/DataFramesMeta/yzaoq/src/macros.jl:1543
in expression starting at REPL[35]:1

Any clues?

Upvotes: 2

Views: 223

Answers (1)

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69879

If you want the call to Symbol constructor be parsed verbatim you need to escape it with $:

julia> @select(df, $(Symbol("y")))
3×1 DataFrame
 Row │ y
     │ Int64
─────┼───────
   1 │     4
   2 │     5
   3 │     6

See https://juliadata.github.io/DataFramesMeta.jl/stable/#dollar for more examples.

The reason why this is needed is because DataFramesMeta.jl introduces non standard evaluation, so if you want things to be evaluated in a standard way you need to escape them.

Upvotes: 4

Related Questions