2012-05-20 10 views
17

data.tableという小さなRの問題があります。あなたの助けが大変ありがとうございます。R data.tableでは、変数のパラメータを式に渡すにはどうすればよいですか?

は私が行うことができないので、今、両方 v1v2は文字変数として他のプログラムから渡される

Error in sum(v1, na.rm = TRUE) : invalid 'type' (character) of argument

このv1<- quote(Sepal.Length)がいるようだ:

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) 

私はエラー以下の取得:私はこれを行うにはどうすればよいです作業。コメント欄で

+9

これは適切なトラックに置くことができます: 'dt [、sum(get(v1)、na.rm = TRUE)、by = v2]'または柔軟性がある場合は別のアプローチを提案します。 – flodel

+0

Thx。それはうまくいったのですか?関数はv1という名前のオブジェクトを取得します。代用関数はこの表現に対して何をしましたか?何もしないで、v1を文字値 "Sepal.Length"に置き換えようとしましたか? – user1157129

答えて

20

代替flodelするの答えは可能性があり

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 

EDIT:

そして機能にこれを置くために、マシューから

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 


EDIT : 場合によっては、paste0eval \ quoteの方法がgetより高速になるという微妙な理由もあります。グループ化が高速である理由の1つは、data.tablejを検査して使用する列を確認し、使用された列(FAQ 1.12および3.1)のみをサブセット化することです。これを行うにはbase::all.vars(j)を使用します。使用されているget()jの列を使用する場合all.varsから隠さとdata.tableは念のj式(.SDcolsを解決するために添加したため、多くの.SDシンボルがjで使用される場合のように)、それらを必要とするバックすべての列をサブセット化に落下します。とにかくすべての列が使用されても差はありませんが、DTが1e7x100と言う場合、グループ化されたj=sum(V1)はグループ化されたj=sum(get("V1"))よりもはるかに高速でなければなりません。少なくとも、それは起こるはずのものです。そうでなければ、バグかもしれません。一方、多くのクエリが動的に構築されている場合は、paste0parseまでの時間が繰り返される可能性があります。すべては本当に依存します。 verbose=TRUEを設定すると、どのカラムが検出されたかに関するメッセージがjによって確認されます。

+0

元の質問に戻って、あなたのソリューションgetResultでこれをどうすればいいですか? print(dt [、eval(expr)、by = eval(b)]) } v1 < - "Sepal.Length" v2 < - "種" e user1157129

+0

@ user1157129、で要求された機能の省略をお詫び申し上げます。あなたの質問。提案のための編集をご覧ください。 – BenBarnes

+0

申し訳ありませんが、ベン、それは動作していない、私は何かを試して? getResult < - function(dt、expr、gby){ return(dt [、eval(expr)、by = eval(gby)]) } dt < - data。テーブル(アイリス) v1 < - "Sepal.Length" v2 < - "種" e user1157129

関連する問題