web-dev-qa-db-ja.com

変数に保存された名前でdata.table列を参照する

_data.table_は素晴らしいRパッケージであり、開発中のライブラリで使用しています。これまでのところ、1つの合併症を除いて、すべてが順調に進んでいます。変数に保存された名前を使用して_data.table_列を参照することは(従来のデータフレームに比べて)はるかに難しいようです(データフレームの場合、たとえば_colname="col"; df[df[,colname]<5,colname]=0_)。

おそらく、物事を最も複雑にしているのは、_data.table_の構文の一貫性が明らかに欠如していることです。場合によっては、eval(colname)get(colname)、またはc(colname)でも機能するようです。その他では、_DT[,colname, with=F]_が解決策です。しかし、たとえば、set()およびsubset()関数など、他のソリューションでは、まったく解決策が見つかりませんでした。最後に、極端な、非常に一般的なユースケースについても先に議論しました( プログラムで列名をdata.tableに渡す )。

おそらく私は物事を複雑にしすぎていますか?さまざまな一般的なシナリオの変数を使用して_data.table_列名を参照するための簡単なチートシートを書き留めることができれば、とても感謝しています。

UPDATE:

カラム名をハードコーディングできる場合、動作する特定の例:

_x.short = subset(x, abs(dist)<=100)
set(x, which(x$val<10), "val", 0) 
_

ここで、_distcol="dist"_、_valcol="val"_と仮定します。 distcolvalcolを使用してdistvalを使用せずに上記を行う最良の方法は何ですか?

41
msp

j式内で複雑な操作を行う場合は、おそらくevalおよびquoteを使用する必要があります。 _data.table_の現在のバージョンにおける問題の1つは、evalの環境が常に正しく処理されないことです- data.tableの評価と引用 (注:パッケージの更新に基づいてその回答を更新します。)-およびそのための現在の修正は、evalに_.SD_を追加することです。いくつかのテストから、これを実行したことがわかる限り、これは速度に影響しません(たとえば、jに_.SD[1]_を含める方法)。

興味深いことに、この問題はjを悩ますだけで、通常evaliを使用しても問題ありません(ここで_.SD_は使用できません)。

もう1つの問題は割り当てです。そこには文字列が必要です。引用符で囲まれた式から文字列名を抽出する1つの方法を知っています-それはきれいではありませんが、機能します。すべてを組み合わせた例を次に示します。

_x = data.table(dist = c(1:10), val = c(1:10))
distcol = quote(dist)
valcol = quote(val)

x[eval(valcol) < 5,
  capture.output(str(distcol, give.head = F)) := eval(distcol)*sum(eval(distcol, .SD))]
_

eval(distcol)に_.SD_を追加しなくても問題ないことに注意してください。しかし、他のevalから削除しても意味がありません。

別のオプションは、getを使用することです。

_diststr = "dist"
valstr = "val"

x[get(valstr) < 5, c(diststr) := get(diststr)*sum(get(diststr))]
_
22
eddi

このソリューションについて既に知っているかもしれませんか?

DT[[colname]]

これは、OPの例を使用して、以下のコメントにある@eddiのソリューションに触発されています。

set.seed(1)
x = data.table(a = 1:10, b=rnorm(10))
colstr="b"
col <- eval(parse(text=paste("quote(",colstr,")",sep="")))
x[eval(col)<0]
x[eval(col)<0,c(colstr):=-100]
7
Frank

変数xに列名があるとしましょう。

colname = as.name(x)

colname関数でsubsetを使用できます

4
saiteja

evalは、サブセットa data.table動的に保存された変数を使用します。次の例が役立ちます。

# Toy data.table example
DT = data.table(a = c(1,2,3), b = c(4,5,6))

# Saved variable
mVar <- "a"

# Subset
DT[DT[[mVar]] < 2]

evalは、複雑な文字表現に非常に敏感であり、通常、実稼働コードには推奨されません。

1
mammask