这有效:
StatsPlots.@df SYN_MM_BM_df plot(
:t,
[:SYN_MM_BM_5, :SYN_MM_BM_10, :SYN_MM_BM_15, :SYN_MM_BM_30]
)
但这不是:
StatsPlots.@df SYN_MM_BM_df plot(
:t,
[Symbol(name) for name in names(SYN_MM_BM_df[2:5])]
)
Error: Cannot convert Symbol to series data for plotting
尽管:
[Symbol(name) for name in names(SYN_MM_BM_df)[2:5]] ==
[:SYN_MM_BM_5, :SYN_MM_BM_10, :SYN_MM_BM_15, :SYN_MM_BM_30
是真的。
谁能解释为什么?我真的不希望单独键入所有符号...
答案 0 :(得分:4)
要解决@Nils Gudat突出显示的限制,请使用cols
(它将其内容视为变量,并将其扩展为列)以获取所需的内容(并在数据帧上使用propertynames
直接将其列名称用作符号):
julia> df = DataFrame(x=1:10, y=rand(10), z=rand(10));
julia> @df df plot(:x, cols(propertynames(df)[2:end]))
这就是我想要的。
答案 1 :(得分:3)
这样做的原因是@df
是一个宏,而不是一个函数,这意味着它会在实际运行任何代码之前 将您编写的代码转换为其他代码。也就是说,它会在表达式[Symbol(name) for name in names(df)[2:5]]
实际被求值之前运算(从而变成[:SYN_MM_BM_5 ...]
。
为说明区别,您可以使用@macroexpand
(此处与prettify
中的MacroTools
结合使用,使输出更具可读性:
julia> using DataFrames, StatsPlots, MacroTools
julia> df = DataFrame(a = 1:10, b = 10 .* rand(10), c = 10 .* rand(10));
# Calling macro with symbols written out
julia> prettify(@macroexpand(@df df plot(:a, [:b, :c], colour = [:red :blue])))
:(((crane->begin
((rat, zebra, coyote, butterfly, starling), curlew) = (StatsPlots).extract_columns_and_names(crane, :a, :b, :c, :red, :blue)
(StatsPlots).add_label(["a", "[b, c]"], plot, rat, [zebra, coyote], colour = [butterfly starling])
end))(df))
# Calling macro with comprehension
julia> prettify(@macroexpand(@df df plot(:a, [x for x ∈ names(df)[2:3]], colour = [:red :blue])))
:(((crane->begin
((rat, zebra, coyote), butterfly) = (StatsPlots).extract_columns_and_names(crane, :a, :red, :blue)
(StatsPlots).add_label(["a", "[x for x = (names(df))[23]]"], plot, rat, [x for x = (names(df))[2:3]], colour = [zebra coyote])
end))(df))
如您所见,该理解并没有被宏接受,因此您最终调用了StatsPlots.extract_columns_and_names(df, :a, :red, :blue)
而不是StatsPlots.extract_columns_and_names(df, :a, :b, :c, :red, :blue)
。
我看到Bogumil在输入时已经提供了解决方案,看来我的StatsPlots
太慢了,无法预编译:)