I'd recommend to use set
with a for-loop
to do this, but on the current stable (CRAN) version 1.8.10, set
doesn't add new columns. So, I'd do something like:
require(data.table)
out_names <- paste("newvar", 1:3, sep="_")
DT[, c(out_names) := 0]
invar1 <- names(DT)[1:3]
invar2 <- names(DT)[4:6]
for (i in seq_along(invar1)) {
set(DT, i=NULL, j=out_names[i], value=DT[[invar1[i]]]/DT[[invar2[i]]])
}
In the current devel version (1.8.11), set
can add new columns. So in that, you don't need the assignment using :=
. That is:
require(data.table)
out_names <- paste("newvar", 1:3, sep="_")
invar1 <- names(DT)[1:3]
invar2 <- names(DT)[4:6]
for (i in seq_along(invar1)) {
set(DT, i=NULL, j=out_names[i], value=DT[[invar1[i]]]/DT[[invar2[i]]])
}
For completeness, another way is :
EVAL = function(...)eval(parse(text=paste0(...))) # helper function
New_Var_names <- paste("New_Var_", i, sep = "")
New_Var <- sprintf("%s/%s", nm1[i], nm2[i])
for (i in 1:3)
EVAL("DT[,", New_Var_names[i], ":=", New_Var[i], "]")
This is more general in that you can also vary the operator /
in the sprintf
and vary the by=
clause too, etc. It's similar to constructing a dynamic SQL statement, if that helps. If you wanted to log the dynamic query being executed, you could add a cat
in your definition of EVAL
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…