2017-01-26 5 views
2

data.tableの代入演算子を使用して、既存の列を一定量で分割して新しい列を作成したいとします。私が試しているコードは、式の性質上、2項演算子のエラーをスローします。ここでdata.tableに名前付きベクトルを代入して算術演算を行う

は私がしようとしているものです:

DT <- data.table(x1=1:4,x2=5:8,x3=9:12) 
DT[, c("y1","y2") := mget(c("x1","x2"))] # works as expected 
DT[, c("y3","y4") := mget(c("x1","x2"))/2] # Error in mget(c("x1", "x2"))/2 : non-numeric argument to binary operator 

列名は変数、したがって文字ベクトルを通過しています。これを行う別の方法がありますか?

答えて

1

mgetを使用すると、list出力が返され、listの値はlapplyでアクセスできます。だから、我々はそれが新しい列「Y3」と「Y4」

DT[, c("y3","y4") := lapply(mget(c("x1","x2")), `/`, 2)] 

に(:=listをループにlapplyを使用して、割り当てるしかし、data.table構文は.SDcols

で列を指定することです
DT[, c("y3","y4") := lapply(.SD, `/`, 2), .SDcols = x1:x2] 
DT 
# x1 x2 x3 y3 y4 
#1: 1 5 9 0.5 2.5 
#2: 2 6 10 1.0 3.0 
#3: 3 7 11 1.5 3.5 
#4: 4 8 12 2.0 4.0 

これは、いくつかのベクトルを作成し、mget

listに置くことで、より明確になることができを使用して
z1 <- 1:4 
z2 <- 5:8 
mget(paste0("z", 1:2)) 
#$z1 
#[1] 1 2 3 4 

#$z2 
#[1] 5 6 7 8 

mget(paste0("z", 1:2)) /2 
#Error in mget(paste0("z", 1:2))/2 : 
# non-numeric argument to binary operator 

ながら、我々list要素をループし、その後、詳細な説明のために2つの

lapply(mget(paste0("z", 1:2)), `/`, 2) 
#$z1 
#[1] 0.5 1.0 1.5 2.0 

#$z2 
#[1] 2.5 3.0 3.5 4.0 
+0

おかげで割ます!私はエラーの原因を理解していないので、私はそれをループするとは思わなかった。最初の方法は、 'mget'を使って私のために働いた。 2番目のアプローチでは、慣用であれば答えを 'eval(c(" x1 "、" x2 ")に変更できますか?私は質問で変数名を単純化していました。 – Naumz

+1

@Naumz 'eval'は列の値を返さないので、' mget'または 'get'(1つの列)が必要です。 .SDcols = c( "x1"、 "x2") 'または.SDcols = c(1,2)つまり、カラムインデックス – akrun

+2

私はそれをお勧めしませんが、' DT [、setDT(mget(paste0 "DT [、.SD/2、.SDcols = x1:x2]" – Frank

関連する問題