Statistics 如何从该函数中获得一致的返回类型?

Statistics 如何从该函数中获得一致的返回类型?,statistics,julia,regression,glm,Statistics,Julia,Regression,Glm,有没有办法让下面的函数返回一致的类型?我正在做一些工作(喜欢它)。我编写了一个函数,为数据集创建所有可能的回归组合。但是,我当前创建的方法会为每个不同长度的rhs返回不同的类型 using GLM function compose(lhs::Symbol, rhs::AbstractVector{Symbol}) ts = term.((1, rhs...)) term(lhs) ~ sum(ts) end 对于一个简单的示例,使用@code\u warntype返回以下内容

有没有办法让下面的函数返回一致的类型?我正在做一些工作(喜欢它)。我编写了一个函数,为数据集创建所有可能的回归组合。但是,我当前创建的方法会为每个不同长度的
rhs
返回不同的类型

using GLM

function compose(lhs::Symbol, rhs::AbstractVector{Symbol})
    ts = term.((1, rhs...))
    term(lhs) ~ sum(ts)
end
对于一个简单的示例,使用
@code\u warntype
返回以下内容

julia> @code_warntype compose(:y, [:x])
Variables
  #self#::Core.Compiler.Const(compose, false)
  lhs::Symbol
  rhs::Array{Symbol,1}
  ts::Any

Body::FormulaTerm{Term,_A} where _A
1 ─ %1 = Core.tuple(1)::Core.Compiler.Const((1,), false)
│   %2 = Core._apply(Core.tuple, %1, rhs)::Core.Compiler.PartialStruct(Tuple{Int64,Vararg{Symbol,N} where N}, Any[Core.Compiler.Const(1, false), Vararg{Symbol,N} where N])
│   %3 = Base.broadcasted(Main.term, %2)::Base.Broadcast.Broadcasted{Base.Broadcast.Style{Tuple},Nothing,typeof(term),_A} where _A<:Tuple
│        (ts = Base.materialize(%3))
│   %5 = Main.term(lhs)::Term
│   %6 = Main.sum(ts)::Any
│   %7 = (%5 ~ %6)::FormulaTerm{Term,_A} where _A
└──      return %7
我们看到,随着
rhs
长度的变化,返回类型也会发生变化


我是否可以更改我的
compose
函数,使其始终返回相同的类型?这不是什么大问题。为每一个新的回归器编译只需约70毫秒。这实际上更多的是一个“如何提高我的Julia技能?”

我认为你不能避免这里的类型不稳定,因为
期望RHS是
术语
术语
元组

但是,您所支付的编译成本最大的是
术语。((1,rhs…)
,因为您调用的是编译成本较高的广播。以下是您如何以更便宜的方式完成此任务:

function compose(lhs::Symbol, rhs::AbstractVector{Symbol})
    term(lhs) ~ ntuple(i -> i <= length(rhs) ? term(rhs[i]) : term(1) , length(rhs)+1)
end
最后-如果您正在进行此类计算,也许您可以使用公式界面放弃,但将
lm
glm
作为RHS直接馈送到矩阵,在这种情况下,应该能够避免额外的编译成本,例如:

julia> y = rand(10);

julia> x = rand(10, 2);

julia> @time lm(x,y);
  0.000048 seconds (18 allocations: 1.688 KiB)

julia> x = rand(10, 3);

julia> @time lm(x,y);
  0.000038 seconds (18 allocations: 2.016 KiB)

julia> y = rand(100);

julia> x = rand(100, 50);

julia> @time lm(x,y);
  0.000263 seconds (22 allocations: 121.172 KiB)
function compose(lhs::Symbol, rhs::AbstractVector{Symbol})
    term(lhs) ~ map(term, (1, rhs...))
end
julia> y = rand(10);

julia> x = rand(10, 2);

julia> @time lm(x,y);
  0.000048 seconds (18 allocations: 1.688 KiB)

julia> x = rand(10, 3);

julia> @time lm(x,y);
  0.000038 seconds (18 allocations: 2.016 KiB)

julia> y = rand(100);

julia> x = rand(100, 50);

julia> @time lm(x,y);
  0.000263 seconds (22 allocations: 121.172 KiB)