15

ある関数の結果がすぐに次の関数に渡されるパイプライン関数をRで記述する方法はありますか?私はF#から来ており、この機能を本当に高く評価していますが、Rでそれを行う方法を見つけていません。簡単なはずですが、方法がわかりません。F#では、次のようになります。

let complexFunction x =
     x |> square 
     |> add 5 
     |> toString

この場合、入力は2乗され、5が追加されてから、文字列に変換されます。Rでも同じようなことができるようになりたいのですが、方法がわかりません。私はこのようなことをする方法を探しましたが、何も見つかりませんでした。通常、データをインポートしてからフィルタリングする必要があるため、データのインポートにこれが必要です。今、私はこれを複数のステップで実行しており、パイプラインを使用してF#で行うのと同じように何かを実行できるようにしたいと考えています。

4

5 に答える 5

8

を使用した関数型プログラミングのアプローチを次に示しますReduce。それは実際にからの例です?Reduce

square <- function(x) x^2
add_5 <- function(x)  x+5
x <- 1:5
## Iterative function application:
Funcall <- function(f, ...) f(...)

Reduce(Funcall, list(as.character, add_5, square,x), right = TRUE)
## [1] "6"  "9"  "14" "21" "30"

または、さらに単純にfunctionalパッケージを使用して、Compose

あなたのために関数を作成するので、これは素晴らしいです

library(functional)
do_stuff <-   Compose(square,add_5,as.character )
do_stuff(1:5)
##  [1] "6"  "9"  "14" "21" "30"

私は、これらのアプローチのどちらも慣用的には風変わりだとは考えていないことに注意してくださいR(それがフレーズでさえある場合)

于 2012-11-13T01:40:59.613 に答える
7

機能パッケージから使用Composeして、あなたが望むものと同様のことを行う独自の二項演算子を作成できます

# Define our helper functions
square <- function(x){x^2}
add5 <- function(x){x + 5}

# functional contains Compose
library(functional)

# Define our binary operator
"%|>%" <- Compose

# Create our complexFunction by 'piping' our functions
complexFunction <- square %|>% add5 %|>% as.character
complexFunction(1:5)
#[1] "6"  "9"  "14" "21" "30"


# previously had this until flodel pointed out
# that the above was sufficient
#"%|>%" <- function(fun1, fun2){ Compose(fun1, fun2) }

技術的には、機能パッケージを必要とせずにこれを行うことができると思いますがCompose、このタスクに使用するのは非常に適切だと感じています.

"%|>%" <- function(fun1, fun2){
    function(x){fun2(fun1(x))}
}
complexFunction <- square %|>% add5 %|>% as.character
complexFunction(1:5)
#[1] "6"  "9"  "14" "21" "30"
于 2012-11-13T02:52:00.110 に答える
5

必要な手順を実行する関数を書きたいと思うかもしれません。

complexFunction <- function(x) {
    as.character(x^2 + 5)
}

次に、 を呼び出しますcomplexFunction(x)


Rが内部で何をしているのかを編集して表示します(@mnel) -Rを解析して評価する方法は、as.character(x^2 + 5)あなたが望むことを行います

値が互いにどのように渡されているかを確認するcodetoolsために何を調査するために使用できますR

flattenAssignment(quote(as.character(x^2+5)))
[[1]]
[[1]][[1]]
x

[[1]][[2]]
`*tmp*`^2

[[1]][[3]]
`*tmp*` + 5


[[2]]
[[2]][[1]]
`as.character<-`(`*tmp*`, value = `*tmpv*`)

[[2]][[2]]
`+<-`(`*tmp*`, 5, value = `*tmpv*`)

[[2]][[3]]
`^<-`(x, 2, value = `*tmpv*`)

または、Lisp スタイルの表現を取得して、それがどのように解析されるか (および結果が渡されるか) を確認できます。

showTree(quote(as.character(x^2+5)))
(as.character (+ (^ x 2) 5))
于 2012-11-13T00:57:58.567 に答える
3

この質問がされて以来、magrittrパイプは R で非常に人気があります。したがって、あなたの例は次のようになります。

library (magrittr)

fx <- function (x) {
     x %>%
     `^` (2) %>%
     `+` (5)  %>%
     as.character ()
     }

逆引用符の表記は、文字通り R の組み込み関数を使用しているためであり、この方法でそれらを使用するには特別に引用する必要があることに注意してください。より通常の名前の関数 (expまたはヘルパー関数を作成した場合add) は、逆引用符を必要とせず、例のように表示されます。

%>%また、入力値を最初の引数として次の関数に自動的に渡すことにも注意してください。ただし、これは変更できます。また、R 関数は最後に計算された値を返すため、それを返すために計算を割り当てたり割り当てたりする必要がないことにも注意してくださいreturn

これは、他の回答で定義された素敵な特殊演算子によく似ていますが、現在Rで広く使用されている特定の関数を使用しています。

于 2018-01-14T14:57:17.983 に答える
0

これは、F# とほぼ同じように R で機能します。

"%|>%" <- function(x, fun){
    if(is.function(x)) {
      function(...) fun(x(...))
    } else {
      fun(x)
    }
}
于 2014-03-17T15:05:23.767 に答える