🔖

Julia 言語でパイプ演算子をつかう

2022/09/18に公開
3

R言語で、tidyverseパッケージなどを使っていると、%>% というパイプ演算子が非常に便利なんです。特に、関数に関数をかますとコードが見づらくないます。同じようなことは、Julia言語でもデフォルトで搭載されていて、便利なパッケージも何種類かあるみたいです。

base

f(x) = 2*x^2 
x = 1 |> f
# 2

こんな感じで、|>をつかって計算します。2変数以上のときはうまくいかないみたいです(なにか方法を知ってる方々はおしえてください

Pipe.jl

Pipe.jl (ドキュメント) は、よりR言語のパイプ演算子に近づけたものです。2変数関数でも使えます😁

using Pipe: @pipe #後ろの書かないとエラーがでます。
f(x,y) = exp(x) * cos(y)
@pipe  1 |> f(_,π)
# -2.718281828459045

引数を配列にしても使えます。

v = [1,2]
g(x,y) = x^2 + y^2 
@pipe v |> g(_[1],_[2])
# 5

スプラット演算子(splat)を用いるとより描きやすくなります。

v = [1,2]
g(x,y) = x^2 + y^2 
@pipe v |> g(_...)
# 5

Chain.jl

同じようにChain.jl(https://github.com/jkrumbiegel/Chain.jl/blob/master/README.md)で便利に演算することができます。

using Chain: @chain
f(x,y) = x^2 * exp(y)
@chain [2,2] begin
    f(_...)
end

pipeと異なることは、beginとendでくくってあげるところです。 @asideをつかうことで、途中経過の出力もできます

f(x,y) = x^2 * exp(y)
g(x) = sqrt(x)
@chain [2,2] begin
    f(_...)
    @aside @show _
    g(_)
end
# var"##389" = 29.5562243957226
# 5.43656365691809

こういうパッケージは、DataFramesMeta.jlのようなパッケージと組み合わせて使うと非常に便利ですね。

2022 9月21日 追記

コメントありがとうございます。ちゃんと目を通していますので、また情報をアップデートできたらまとめなおします。

Discussion

I_pppI_ppp

baseのやつの2変数のときは

v = [1,2]
g(x,y) = x^2+y^2
v |> a -> g(a[1],a[2])

と無名関数かますかな(Pipe.jlの_をちゃんと書く感じ)

tenfu2teatenfu2tea

2変数関数限定 > Base.Fix1, Base.Fix2

julia> f(x,y)=exp(x)*cos(y)
f (generic function with 1 method)

julia> 1 |> Base.Fix2(f,π)
-2.718281828459045

julia> π |> Base.Fix1(f,1)
-2.718281828459045
tenfu2teatenfu2tea

関数の第2引数以下の値を固定して第1引数だけの関数として振る舞わせるなら、 Lazy パッケージの @> マクロもありますね。Lazyは以前少し紹介しました→ 「Julia でも array.map() do ... end と書ける」@Qiita

julia> using Lazy

julia> f(x,y,z)=exp(x)*cos(y)*cos(z)
f (generic function with 1 method)

julia> @> 1 f(π/4,π/4)
1.3591409142295228

julia> exp(1) / 2
1.3591409142295225