R data.tableでは、可変パラメータを式にどのように渡すのですか。
-
12-12-2019 - |
質問
data.table
の小さいrの問題で立ち往生しています。あなたの助けが大いに高く評価されています。どうやってこれを行う方法:
getResult <- function(dt, expr, gby) {
e <- substitute(expr)
b <- substitute(gby)
return(dt[,eval(e),by=b])
}
v1 <- "Sepal.Length"
v2 <- "Species"
dt <- data.table(iris)
rDT <- getResult(dt, sum(v1, na.rm=TRUE), v2)
.
次のエラーが発生します:
合計(v1、na.rm= true):無効な 'タイプ'(文字) 議論
今、
v1
とv2
の両方が他のプログラムから文字変数として渡されているため、このv1<- quote(Sepal.Length)
はできません。
解決
コメントにおけるフロデルの答えの代わりになる可能性があります
e <- parse(text = paste0("sum(", v1, ", na.rm = TRUE)"))
b <- parse(text = v2)
rDT2 <- dt[, eval(e), by = eval(b)]
# b V1
# [1,] setosa 250.3
# [2,] versicolor 296.8
# [3,] virginica 329.4
.
編集:
とこれを関数に入れて、
.
getResult <- function(dt, expr, gby){
return(dt[, eval(expr), by = eval(gby)])
}
(dtR <- getResult(dt = dt, expr = e, gby = b))
# gives the same result as above
マシューから編集:
場合によっては、paste0
とeval
\ quote
メソッドがget
よりも速くなる可能性がある理由が微妙な理由があります。グループ化することができる理由の1つは、data.table
がj
を使用して使用する列を検査し、次に使用されている列(FAQ 1.12および3.1)のみをサブセットします。それはそれを実行するためにbase::all.vars(j)
を使用します。 get()
でj
を使用する場合、使用されている列はall.vars
から非表示になり、data.table
Expressionがそれらを必要とする場合にはすべての列に戻ります(j
で.SD
が追加されたときにj
が追加された場合に似ています)。 。とにかくすべての列が違いはありませんが、.SDcols
が1E7x100であると、グループ化されたDT
がその理由のためにグループ化されたj=sum(V1)
よりもはるかに速くなるはずです。少なくとも、それが起こることになっているものであり、それがバグであるかもしれません。一方で多くのクエリが動的に構築されている場合は、j=sum(get("V1"))
とpaste0
への時間が入ってくる可能性があります。すべてが本当に依存しています。 parse
の設定は、verbose=TRUE
によって使用されている列に関するメッセージを印刷する必要があります。これによりチェックできます。