質問

data.tableがあります DT 名前付きの列付き RF そして、下線を持つ多くの列 _初期化。下線でそれらすべての列をループして、 RF それから列。しかし、私は立ち往生しています。 RHSのすべてがすべてのようです:= のオペレーター data.table 動的変数では動作しません。

これが私のものです DT および目的の出力(ハードコード):

library(data.table)
DT <- data.table(RF  = 1:10,
                 S_1 = 11:20,
                 S_2 = 21:30)
#Desired output
DT[ , S_1 := S_1 - RF]
DT[ , S_2 := S_2 - RF]
DT
      RF S_1 S_2
 [1,]  1  10  20
 [2,]  2  10  20
 [3,]  3  10  20
...

ただし、これをより柔軟にしたい、すなわち、すべての列を介して「_」という名前と減算をしたいと考えています。 RF:

#1. try: Does not work; Interestingly, the i on the LHS of := is interpreted as the column i, but on the RHS of
#:= it is interpreted as 2 and 3, respectively
for (i in grep("_", names(DT))){
  DT[ , i:= i - 1, with=FALSE]
}
DT
          RF  S_1 S_2
 [1,]  1   1   2
 [2,]  2   1   2
 [3,]  3   1   2
...

#2. try: Work with parse and eval
for (i in grep("_", names(DT), value=TRUE)){
  DT[ , eval(parse(text=i)):= eval(parse(text=i)) - RF]
}
#Error in eval(expr, envir, enclos) : object 'S_1' not found

それを行う方法をヒントすることは素晴らしいことです。

編集:質問を投稿したらすぐに、私は自分自身に考えました:なぜあなたは := そもそもオペレーター、そして確かに、私はそうする必要がないことに気付きました。これは機能し、ループは必要ありません。

DT[, grep("_", names(DT)), with=FALSE] - DT[, RF]

そのために残念。ただし、なぜ私のアプローチが := オペレーターは機能しません。だから誰かがそこで私を助けることができるかもしれません。

役に立ちましたか?

解決

あなたは2回目の試みで正しい軌道に乗っていました。使用するアプローチは次のとおりです substitute で渡される式を構築するために 'j' 議論 DT[ , j ].

for (i in grep("_", names(DT), value=TRUE)){
    e <- substitute(X := X - RF, list(X = as.symbol(i)))
    DT[ , eval(e)]
}
DT
#     RF S_1 S_2
# [1,]  1  10  20
# [2,]  2  10  20
# [3,]  3  10  20
# [4,]  4  10  20
# [5,]  5  10  20

シンボルではなく、LHS式を使用することもできます。

for (i in grep("_", names(DT), value=TRUE))
    DT[, (i) := get(i)-RF]

他のヒント

残念ながら質問を投稿した後に発見した回避策は次のとおりです。

DT[, .SD, .SDcols = patterns('_')] - DT[, RF]

これはまた、より複雑な設定で機能します。この設定では、保持する追加の列がありますが、追加の努力があります。

library(data.table)
DT <- data.table(RF  = 1:10,
                 S_1 = 11:20,
                 S_2 = 21:30,
                 addCol = rnorm(10)) #Column that should not be subtracted by RF, but still kept in DT

DT <- cbind(DT[, .SD, .SDcols = patterns("_")] - DT[, RF], addCol = DT[, addCol])

使用するために更新されました set()+..; set 強力です(以前の試みの編集を参照)。

varnames <- grep("_", names(DT), value=TRUE)
set(DT, j = varnames, value = DT[, ..varnames] - DT[, RF])
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top