2017-04-15 6 views
0

Rでは、(n-1)番目の関数の出力がn番目の関数に挿入されるように、関数のリストをオブジェクトに適用するための推奨方法がありますか?オブジェクト上の関数のシーケンス

たとえば、文字列を消去する関数のリストがあります。そして私は、たとえば、同じ汚れた文字列にそれらのすべてを適用したい:

mystring <- "ImPortant info - some extra"; 
cleaning_functions <- 
    list(function(s){tolower(s)}, 
     function(s){substr(s, 1, grep(' -') -1)}) 

そして、最終的な結果は次のようになります。"important info"
これはループで実現できます。私は "プライ"のような魅力的なソリューションを望んでいます。
もしループが効率的であれば、それもそうです。それが最適だったら私は驚くだろう。

私の最終的な解決策は操作の順序が重要であり、提供される関数のリストは動的に作成され、潜在的には名前が付けられないことに注意してください。

答えて

3

これは、function compositionとして知られています。猫には多くの方法があります。

compose = function (f, g) { 
    function (...) f(g(...)) 
} 

そして、あなたの問題に適用します:最も簡単には(例えば、リンクを参照してください)簡単なラッパーを記述するために、または既存のライブラリを使用することです

cleaning_functions = do.call(compose, cleaning_functions) 
# or, directly 
cleaning_functions = compose(tolower, function (s) substr(s, 1, regexpr(' -', s) - 1)) 

し、任意の関数のようにそれを呼び出します。

cleaning_functions(my_string) 
+0

ありがとう、私が探していたもの。クールなトリック – jameselmore

+0

実際には、これが機能することは明らかではありません。 1つのレベルの構成でも無限の再帰エラーが発生します。何かご意見は? – jameselmore

+0

@ jameselmoreあなたが何をしているのか分かりません。ここには無限の再帰はありません。つまり、あなたの関数例にはエラーが含まれていました(しかし、無限再帰につながるわけではありません)。しかし、それが修正されると、私が書いたコードはまさにそのように機能します。 –

1

生成するいくつかのテスト機能:

test1 <- function(x){paste(x,"a",sep="")} 
test2 <- function(x){paste(x,"b",sep="")} 
test3 <- function(x){paste(x,"c",sep="")} 
test4 <- function(x){paste(x,"d",sep="")} 
test5 <- function(x){paste(x,"e",sep="")} 

次に、これらの関数を呼び出す:

string <- "test" 
for (i in c("test1","test2","test3","test4","test5")) { 
    string <- do.call(i, list(string)) 
} 
string 
[1] "testabcde" 

をあなたの具体的な例について、以下に動作するはずです:

mystring <- "ImPortant info - some extra" 
cleaning_functions <- 
    list(function(s){tolower(s)}, 
     function(s){substr(s, 1, regexpr(' -', s) - 1)}) 
for (i in cleaning_functions) { 
    mystring <- do.call(i, list(mystring)) 
} 
mystring 
[1] "important info" 

なお、I 012を変更しなければならなかったそのためには〜regexprが必要です。

+0

私の機能のリストは、動的に作成されます。その他の場所では、名前の指定が保証されません。 – jameselmore

+0

名前が付けられていない場合、動的に作成される関数はどのように格納されますか? – guscht

+0

私が与えた例を試してみましょう。関数はオブジェクトであり、名前を付ける必要はありません:'(cleaning_functions [[1]])( 'ALLCAPS')' は '' allcaps ''を返します – jameselmore

関連する問題