Julia-dataframe-在具有by()的多输入函数中的同一列

Julia-dataframe-在具有by()的多输入函数中的同一列,dataframe,julia,Dataframe,Julia,我试图探索DataFrames.jl模块的功能。 我在尝试将同一列传递给by()函数中的多输入变量时遇到了以下问题 我的基本例子是: df = DataFrame(grp = rand(["a","b"], 100), x= rand(100), y = rand(100), z=rand(100)) by(df, :grp,result= (:x, :z) => ((x, y),) -> cov(x, y)) 给出以下数据帧 2×2 DataFrame │ Row │ grp

我试图探索DataFrames.jl模块的功能。 我在尝试将同一列传递给by()函数中的多输入变量时遇到了以下问题

我的基本例子是:

df = DataFrame(grp = rand(["a","b"], 100), x= rand(100), y = rand(100), z=rand(100))
by(df, :grp,result= (:x, :z) => ((x, y),) -> cov(x, y))
给出以下数据帧

2×2 DataFrame
│ Row │ grp    │ result     │
│     │ String │ Float64    │
├─────┼────────┼────────────┤
│ 1   │ a      │ -0.0111914 │
│ 2   │ b      │ -0.0184773 │
现在让我们假设我不一定使用cov(),我希望传递与该函数的x和y输入相同的列x。在cov()的例子中,这是一个微不足道的问题,但要尽可能做到通用。

我尝试了以下两种可能性

by(df, :grp,result= (:x) => ((x, y),) -> cov(x, y))
这将给出以下错误消息:

ERROR: MethodError: no method matching cov(::Float64, ::Float64)
本例中的错误是预期的,我认为该方法引用了提供给函数对象的数据

我还尝试了以下方法

by(df, :grp,result= (:x,:x) => ((x, y),) -> cov(x, y))
这将给出以下错误消息

ERROR: ArgumentError: Elements of Symbol[:x, :x] must be unique
这次我理解了错误消息,但我不明白为什么符号必须是唯一的。我已检查了
?Symbol
,但找不到有关为什么或如何绕过此问题(限制?)的更多详细信息。 这有效地防止了我通过编程为两个输入传递相同的列

那么,解决这个问题的方法是什么?对于一个具有f(x,y)的函数,可以将同一列传递两次吗?

附:在本例(x)中的问题或评论之前-->cov(x,x)将起作用。我知道会的。但是假设我有一个函数,它将计算数据帧中(选定)列的cov()或其他函数,我不希望处理对角线项的特殊情况。

带有

by(df, :grp,result= (:x) => ((x, y),) -> cov(x, y))
是由于以下方式导致的Julia processess参数:

julia> f((x,y),) = @show (x,y)
f (generic function with 1 method)

julia> f([1,2,3,4,5])
(x, y) = (1, 2)
(1, 2)
因此,x获取存储在列
:x
中的传递向量的第一个元素,
:y
获取第二个值

请注意,如果您的
df
小于2行,您甚至会得到一个错误:

julia> by(first(df,2), :grp,result= (:x) => ((x, y),) -> println((x,y)))
ERROR: BoundsError: attempt to access 1-element view(::Array{Float64,1}, [1]) with eltype Float64 at index [2]

现在转到重复专栏问题。问题在于,
by
向函数传递了一个名为tuple的函数,您可以通过运行以下代码来检查该函数:

julia> df = DataFrame(x=[:a,:b,:a,:b], y=1:4)
4×2 DataFrame
│ Row │ x      │ y     │
│     │ Symbol │ Int64 │
├─────┼────────┼───────┤
│ 1   │ a      │ 1     │
│ 2   │ b      │ 2     │
│ 3   │ a      │ 3     │
│ 4   │ b      │ 4     │

julia> by(df, :x, (:x, :y) => x -> @show typeof(x));
typeof(x) = NamedTuple{(:x, :y),Tuple{SubArray{Symbol,1,Array{Symbol,1},Tuple{Array{Int64,1}},false},SubArray{Int64,1,Array{Int64,1},Tuple{Array{Int64,1}},false}}}
typeof(x) = NamedTuple{(:x, :y),Tuple{SubArray{Symbol,1,Array{Symbol,1},Tuple{Array{Int64,1}},false},SubArray{Int64,1,Array{Int64,1},Tuple{Array{Int64,1}},false}}}
并且
NamedTuple
不允许重复列:

julia> (a=1,a=2)
ERROR: syntax: field name "a" repeated in named tuple

实际上,我们正在DataFrames.jl中讨论从传递
NamedTuple
转换为自动飞溅,请参见以下内容。

再次感谢您的快速回复和见解。我应该从你在我上一篇文章中的回答中猜到,名字对是根本原因。谢谢你的耐心。我绝对同意你在这个问题上的观点。如果我能帮忙,请告诉我。