質問

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):無効な 'タイプ'(文字) 議論

今、v1v2の両方が他のプログラムから文字変数として渡されているため、この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
.


マシューから編集: 場合によっては、paste0eval \ quoteメソッドがgetよりも速くなる可能性がある理由が微妙な理由があります。グループ化することができる理由の1つは、data.tablejを使用して使用する列を検査し、次に使用されている列(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によって使用されている列に関するメッセージを印刷する必要があります。これによりチェックできます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top