Rの高レベル関数 - 公式のコンポースオペレーターまたはカレー関数はありますか?

StackOverflow https://stackoverflow.com/questions/2228544

質問

RでCompose演算子を作成できます。

 `%c%` = function(x,y)function(...)x(y(...)) 

このように使用する:

 > numericNull = is.null %c% numeric
 > numericNull(myVec)
 [2] TRUE FALSE

しかし、この種のことを行うための公式の機能セットがあるかどうか、およびRでカリーするなどの他の操作があるかどうかを知りたいと思います。

私のカレー機能:

> curry=function(...){
    z1=z0=substitute(...);z1[1]=call("list");
    function(...){do.call(as.character(z0[[1]]),
                          as.list(c(eval(z1),list(...))))}}
> p = curry(paste(collapse=""))
> p(letters[1:10])
[1] "abcdefghij"

これは、EG Aggregateに特に最適です。

> df = data.frame(l=sample(1:3,10,rep=TRUE), t=letters[1:10])
> aggregate(df$t,df["l"],curry(paste(collapse="")) %c% toupper)
  l    x
1 1  ADG
2 2  BCH
3 3 EFIJ

私は以下よりもはるかにエレガントで編集可能だと思います:

> aggregate(df$t, df["l"], function(x)paste(collapse="",toupper(x)))
  l    x
1 1  ADG
2 2  BCH
3 3 EFIJ

基本的に知りたい - これはすでにRのために行われていますか?

役に立ちましたか?

解決

Rの機能プログラミングの標準的な場所は、今では functional 図書館。

図書館から:

機能:カレー、作曲、およびその他の高次関数

例:

   library(functional)
   newfunc <- Curry(oldfunc,x=5)

クラン:https://cran.r-project.org/web/packages/function/index.html

PS:このライブラリは置き換えます ROxigen 図書館。

他のヒント

これらの関数は両方ともに存在します roxygen パッケージ (こちらのソースコードを参照してください)Peter Danenbergから(もともと基づいていた R-HELPでのバイロンエリスのソリューション):

Curry <- function(FUN,...) {
  .orig = list(...);
  function(...) do.call(FUN,c(.orig,list(...)))
}

Compose <- function(...) {
  fs <- list(...)
  function(...) Reduce(function(x, f) f(x),
                       fs,
                       ...)
}

の使用に注意してください Reduce R.で機能的なプログラミングを実行しようとするときに非常に役立つ機能。 MapFilter).

カレーの例(この使用法がわずかに異なる):

> library(roxygen)
> p <- Curry(paste, collapse="")
> p(letters[1:10])
[1] "abcdefghij"

ユーティリティを示す例を次に示します Compose (3つの異なる関数を文字に適用します):

> Compose(function(x) x[length(x):1], Curry(paste, collapse=""), toupper)(letters)
[1] "ZYXWVUTSRQPONMLKJIHGFEDCBA"

そして、あなたの最後の例は次のように機能します:

> aggregate(df[,"t"], df["l"], Compose(Curry(paste, collapse=""), toupper))
  l    x
1 1  ABG
2 2 DEFH
3 3  CIJ

最後に、同じことをする方法があります plyr (簡単に実行することもできます by また aggregate すでに示されているように):

> library(plyr)
> ddply(df, .(l), function(df) paste(toupper(df[,"t"]), collapse=""))
  l   V1
1 1  ABG
2 2 DEFH
3 3  CIJ

にカレーと呼ばれる関数があります roxygen パッケージ。
経由で見つかりました この会話 Rメールアーカイブ。

変数の「名前」を正確に通過させる場合、より複雑なアプローチが必要です。

たとえば、そうする場合 plot(rnorm(1000),rnorm(1000)) その後、x軸とy軸に素敵なラベルが得られます。この別の例はです data.frame

> data.frame( rnorm(5), rnorm(5), first=rpois(5,1), second=rbinom(5,1,0.5) )
    rnorm.5. rnorm.5..1 first second
1  0.1964190 -0.2949770     0      0
2  0.4750665  0.8849750     1      0
3 -0.7829424  0.4174636     2      0
4  1.6551403  1.3547863     0      1
5  1.4044107 -0.4216046     0      0

data.frameが有用な名前を列に割り当てたわけではありません。

カレーのいくつかの実装はこれを適切に行わず、読み取れない列名とプロットラベルにつながる場合があります。代わりに、私は今、このようなものを使用しています:

Curry <- function(FUN, ...) {
    .orig = match.call()
    .orig[[1]] <- NULL # Remove first item, which matches Curry
    .orig[[1]] <- NULL # Remove another item, which matches FUN
    function(...) {
        .inner = match.call()
        .inner[[1]] <- NULL # Remove first item, which matches Curry
        do.call(FUN, c(.orig, .inner), envir=parent.frame())
    }
}

これは非常に複雑ですが、正しいと思います。 match.call すべてのARGSをキャッチし、どのような表現がARGSを定義したかを完全に覚えています(これは素敵なラベルに必要です)。問題は、それがあまりにも多くのargを捕まえることです - ただ ... しかし、 FUN. 。また、呼ばれている関数の名前を覚えています(Curry).

したがって、これらの最初の2つのエントリをで削除する必要があります .orig となることによって .orig 本当にに対応しています ... 議論。それが私たちがする理由です .orig[[1]]<-NULL 2回 - 毎回エントリを削除し、他のすべてを左にシフトします。

これにより定義が完了し、次のことを行うことができます まさに 上記と同じです

Curry(data.frame, rnorm(5), rnorm(5) )( first=rpois(5,1) , second=rbinom(5,1,0.5) )

に関する最後のメモ envir=parent.frame(). 。これを使用して、「.inner」または「.orig」と呼ばれる外部変数がある場合、問題が発生しないようにしました。これで、すべての変数がカレーが呼ばれる場所で評価されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top