2013-02-12 36 views
18

パッケージdata.tableには、式をij引数として使用するための特別な構文があります。data.tableを呼び出す関数を呼び出す関数の記述方法?

これは、実際にはsection 1.16 of the FAQsで説明されているように、データテーブルに引数を受け入れて渡す書き込み関数がどのように機能するかにいくつかの意味があります。

しかし、私はこの1つの追加レベルを取る方法を理解できません。

ここは例です。私は私の集計結果を得るために、この作品、

library(data.table) 


foo <- function(data, by){ 
    by <- substitute(by) 
    data[, .N, by=list(eval(by))] 
} 

DT <- data.table(mtcars) 
foo(DT, gear) 

OK:私は私のデータの特定のサマリーを作るラッパー関数foo()を書き、その後foo()を呼び出し、結果をプロット秒ラッパーplotfoo()したいと言います:

by N 
1: 4 12 
2: 3 15 
3: 5 5 

plotfoo()を書くときに今、私はちょうど同じにしようと、私は無残に失敗:

plotfoo <- function(data, by){ 
    by <- substitute(by) 
    foo(data, eval(by)) 
} 
plotfoo(DT, gear) 

は、しかし、私はエラーメッセージが表示されます。この時間は:


OK

Error: evaluation nested too deeply: infinite recursion/options(expressions=)? 
、そう eval()は、問題を引き起こしています。のは、それを削除してみましょう:

plotfoo <- function(data, by){ 
    by <- substitute(by) 
    foo(data, by) 
} 
plotfoo(DT, gear) 

ああ、私は新しいエラーメッセージが表示されます:私は立ち往生したままどこ

Error in `[.data.table`(data, , .N, by = list(eval(by))) : 
    column or expression 1 of 'by' or 'keyby' is type symbol. Do not quote column names. Useage: DT[,sum(colC),by=list(colA,month(colB))] 

そしてここです。

質問:data.tableを呼び出す関数を呼び出す関数を作成するにはどうすればよいですか?

+0

ないソリューションが、あなたは、 '代替を(削除した場合by)と 'eval'を呼び出し、' foo(DT、 "gear") 'のような文字変数として' gear'を渡します。 – Arun

答えて

13

これは動作します:

plotfoo <- function(data, by) { 
    by <- substitute(by) 
    do.call(foo, list(quote(data), by)) 
} 

plotfoo(DT, gear) 
# by N 
# 1: 4 12 
# 2: 3 15 
# 3: 5 5 

説明:

問題は、あなたのことですのfoo()に電話するfooプロセスが二仮引数by)のためにこれらの呼び出し、その律儀substitute sがシンボルeval(by)またはbybyとして取得する場合

foo(data, eval(by)) 
foo(data, by) 

:は、次のいずれかのように見えます。しかしbyの値はのようにgearになります。

do.call()は、呼び出し元を評価する呼び出しを構成する前に、2番目の引数の要素を評価することでこの問題を解決します。あなたはそれbyを渡すときその結果、それはこのように(基本的に)見えますコールを構築する前に、その値(シンボルgear)にそれを評価:

foo(data, gear) 
+0

非常に良い説明!ありがとうございました。 – Arun

+0

+1これは非常にうまくいきます。「i」と「j」の引数を渡すための暗黙の要求ですが、ありがとうございます。 – Andrie

5

あなたは結婚しているかもしれないと思います。

library(data.table) 
foo <- function(data, by){ 
    by <- by 
    data[, .N, by=by] 
} 

DT <- data.table(mtcars) 
foo(DT, 'gear') 

plotfoo <- function(data, by){ 
    foo(data, by) 
} 
plotfoo(DT, 'gear') 

そして、その方法は、文字値を渡すサポートしています:これは動作します

> gg <- 'gear' 
> plotfoo <- function(data, by){ 
+ foo(data, by) 
+ } 
> plotfoo(DT, gg) 
    gear N 
1: 4 12 
2: 3 15 
3: 5 5 
+1

あなたを迷惑して申し訳ありませんが、fooの中で 'by by 'の意味は何ですか? – vodka

+0

ああ、はい、あなたは大丈夫です。私の事例を単純化しようと試みて、「i」または「j」に引数を渡すという元の問題を取り除いたことをお詫びします。申し訳ありません - 私は私の質問を編集します。 – Andrie

+0

@vodka:特に意味はありません。オリジナルを編集することからちょっと残しました。 –

関連する問題