sob*_*sob 7 metaprogramming dataframe julia
我能够很好地运行以下代码,并且它提供了预期的结果:
\njulia> using DataFrames, DataFramesMeta\n\njulia> expr = "2*:a+:b"\n"2*:a+:b"\n\njulia> df = DataFrame(a=[1,2],b=[3,4])\n2\xc3\x972 DataFrame\n Row \xe2\x94\x82 a b \n \xe2\x94\x82 Int64 Int64 \n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n 1 \xe2\x94\x82 1 3\n 2 \xe2\x94\x82 2 4\n\njulia> eval(Meta.parse("@transform(df, " * join(collect(":res" => expr), " = ") * ")"))\n2\xc3\x973 DataFrame\n Row \xe2\x94\x82 a b res \n \xe2\x94\x82 Int64 Int64 Int64 \n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n 1 \xe2\x94\x82 1 3 5\n 2 \xe2\x94\x82 2 4 8\n\nRun Code Online (Sandbox Code Playgroud)\n然而,当在模块内完成时,这会失败。
\njulia> module foo\n using DataFrames, DataFramesMeta\n function bar()\n expr = "2*:a+:b"\n df = DataFrame(a=[1,2],b=[3,4])\n eval(Meta.parse("@transform(df, " * join(collect(":res" => expr), " = ") * ")"))\n end\n end\nMain.foo\n\njulia> foo.bar()\nERROR: UndefVarError: df not defined\nStacktrace:\n [1] top-level scope\n @ ~/.julia/packages/DataFramesMeta/BkRtJ/src/macros.jl:1363\n [2] eval\n @ ./boot.jl:368 [inlined]\n [3] eval\n @ ./REPL[9]:1 [inlined]\n [4] bar()\n @ Main.foo ./REPL[9]:6\n [5] top-level scope\n @ REPL[10]:1\nRun Code Online (Sandbox Code Playgroud)\n我想这可能是范围问题,并试图通过使用foo.df而不是明确地df在函数调用中明确显示,但没有成功。
有谁知道如何预防df这里被识别为已定义变量吗?
就像 Bogumil 所说的那样,eval完全看起来不像是编写代码的推荐方式。
但是,如果您的目标是学习宏,那么这是正确的代码:
\nmodule Foo2\n using DataFrames, DataFramesMeta\n function bar()\n expr = "2*:a+:b"\n df = DataFrame(a=[1,2],b=[3,4])\n code = quote\n @transform($df, :res = $(Meta.parse(expr)))\n end\n eval(code)\n end\nend\nRun Code Online (Sandbox Code Playgroud)\n现在你可以运行:
\njulia> Foo2.bar()\n2\xc3\x973 DataFrame\n Row \xe2\x94\x82 a b res\n \xe2\x94\x82 Int64 Int64 Int64\n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n 1 \xe2\x94\x82 1 3 5\n 2 \xe2\x94\x82 2 4 8\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
196 次 |
| 最近记录: |