19

パッケージには、引数data.tableとして式を使用する必要がある特別な構文があります。ij

これは、FAQのセクション1.16で非常によく説明されているように、引数を受け入れてデータテーブルに渡す関数を作成する方法にいくつかの影響を及ぼします。

しかし、私はこれをさらに1つのレベルにする方法を理解できません。

これが例です。foo()データの特定の要約を作成するラッパー関数を作成し、次に結果plotfoo()を呼び出しfoo()てプロットする2番目のラッパーを作成するとします。

library(data.table)


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

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

表形式の結果が得られるので、これでうまくいきます。

   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)

しかし、今回はエラーメッセージが表示されます。

Error: evaluation nested too deeply: infinite recursion / options(expressions=)?

OK、それで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を呼び出す関数を呼び出す関数を作成するにはどうすればよいですか?

4

2 に答える 2

14

これは機能します:

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

説明:

問題は、inへの呼び出しが次のいずれかのようfoo()plotfoo()見えることです。

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

fooこれらの呼び出しを処理するときsubstitute2番目の仮引数by)がby'sのとして記号eval(by)またはを取得することを忠実に実行しbyます。ただし、呼び出しのように、byの値をにしたいとします。gearfoo(data, gear)

do.call()次に評価する呼び出しを作成する前に、2番目の引数の要素を評価することにより、この問題を解決します。その結果、渡すと、 (本質的に)次のように見える呼び出しを作成する前にby、その値(シンボル)に評価されます。gear

foo(data, gear)
于 2013-02-12T18:00:15.070 に答える
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
于 2013-02-12T17:44:39.287 に答える