まず第一に、@MattDowle に感謝します。data.table
を使い始めて以来、私に起こった最高のことの 1 つR
です。
2 番目: の変数列名のさまざまな使用例について、次のような多くの回避策があることを認識していますdata.table
。
- 文字ベクトルに名前が格納されている data.table 変数を選択 / 割り当て
- Rの変数を使用してdata.tableに列名を渡す
- 変数に保存された名前で data.table 列を参照する
- プログラムで列名を data.table に渡す
- Data.table メタプログラミング
- data.table を呼び出す関数を呼び出す関数の書き方
- `data.table` での動的列名の使用
- data.table、R の動的列名
- グループごとに、data.table で := を使用して複数の列を割り当てる
- data.table を使用した「group by」操作で列名を設定する
- R data.table を使用して複数の列を要約する
おそらく、私が参照していないより多くのことです。
しかし、上記のすべてのトリックを習得して、それらの使用方法を思い出すためにそれらを調べる必要がなくなったとしても、関数にパラメーターとして渡される列名を操作することは非常に困難であることがわかります。面倒な作業。
私が探しているのは、次の回避策/ワークフローに代わる「ベストプラクティスが承認された」代替手段です。同様のデータの列がたくさんあり、これらの列またはそれらのセットに対して一連の同様の操作を実行したいと考えています。操作は任意に複雑であり、指定された各操作に渡される列名のグループ変数で。
この問題は不自然に聞こえると思いますが、驚くほど頻繁に遭遇します。通常、例は非常に乱雑であるため、この質問に関連する機能を分離するのは困難ですが、最近、ここで MWE として使用するために単純化するのがかなり簡単な例に出くわしました。
library(data.table)
library(lubridate)
library(zoo)
the.table <- data.table(year=1991:1996,var1=floor(runif(6,400,1400)))
the.table[,`:=`(var2=var1/floor(runif(6,2,5)),
var3=var1/floor(runif(6,2,5)))]
# Replicate data across months
new.table <- the.table[, list(asofdate=seq(from=ymd((year)*10^4+101),
length.out=12,
by="1 month")),by=year]
# Do a complicated procedure to each variable in some group.
var.names <- c("var1","var2","var3")
for(varname in var.names) {
#As suggested in an answer to Link 3 above
#Convert the column name to a 'quote' object
quote.convert <- function(x) eval(parse(text=paste0('quote(',x,')')))
#Do this for every column name I'll need
varname <- quote.convert(varname)
anntot <- quote.convert(paste0(varname,".annual.total"))
monthly <- quote.convert(paste0(varname,".monthly"))
rolling <- quote.convert(paste0(varname,".rolling"))
scaled <- quote.convert(paste0(varname,".scaled"))
#Perform the relevant tasks, using eval()
#around every variable columnname I may want
new.table[,eval(anntot):=
the.table[,rep(eval(varname),each=12)]]
new.table[,eval(monthly):=
the.table[,rep(eval(varname)/12,each=12)]]
new.table[,eval(rolling):=
rollapply(eval(monthly),mean,width=12,
fill=c(head(eval(monthly),1),
tail(eval(monthly),1)))]
new.table[,eval(scaled):=
eval(anntot)/sum(eval(rolling))*eval(rolling),
by=year]
}
もちろん、ここでのデータと変数に対する特定の影響は無関係です。そのため、この特定のケースで達成されることを達成するために、それに焦点を合わせたり、改善を提案したりしないでください。むしろ、私が探しているのはdata.table
、変数で指定された、または関数に引数として渡された列のリストまたは列のリストのリストに、アクションの任意の複雑な手順を繰り返し適用するワークフローの一般的な戦略です、プロシージャは、変数/引数で指定された列をプログラムで参照する必要があり、更新、結合、グループ化、data.table
特別なオブジェクト.I
への呼び出し.SD
などを含む可能性があります。しかし、上記のものや頻繁に必要とする他のものよりも、よりシンプルで、よりエレガントで、より短く、または設計、実装、または理解が容易なものquote
-ingとeval
-ing。
特に、手順がかなり複雑になる可能性がありdata.table
、更新された列を繰り返し更新してから参照する必要があるため、lapply(.SD,...), ... .SDcols = ...
通常、標準的な方法は実行可能な代替手段ではないことに注意してください。また、各呼び出しを で置き換えるeval(a.column.name)
ことは、私が知る限りDT[[a.column.name]]
、他の操作とはうまくいかないため、あまり単純化されず、一般的に完全に機能しません。data.table