data.table:在未知列名时创建条件变量的正确方法是什么?

Dom*_*rds 14 if-statement r data.table

我的问题涉及创建一个变量,该变量依赖于data.table中的其他列,当事先没有知道任何变量名时.

下面是一个玩具示例,其中我有5行,当条件等于A时,新变量应为1,否则为4.

library(data.table)
DT <- data.table(Con = c("A","A","B","A","B"),
                 Eval_A = rep(1,5),
                 Eval_B = rep(4,5))
Col1 <- "Con"
Col2 <- "Eval_A"
Col3 <- "Eval_B"
Col4 <- "Ans"
Run Code Online (Sandbox Code Playgroud)

下面的代码有效,但感觉我误用了包!

DT[,Col4:=ifelse(DT[[Col1]]=="A",
                 DT[[Col2]],
                 DT[[Col3]]),with=FALSE]
Run Code Online (Sandbox Code Playgroud)

更新: 谢谢,我快速完成了以下答案.一旦在data.table上有500万行而只有相关列,并在添加10个非相关列后再次出现,下面是结果:

+-------------------------+---------------------+------------------+
|         Method          | Only relevant cols. | With extra cols. |
+-------------------------+---------------------+------------------+
| List method             | 1.8                 | 1.91             |
| Grothendieck - get/if   | 26.79               | 30.04            |
| Grothendieck - get/join | 0.48                | 1.56             |
| Grothendieck - .SDCols  | 0.38                | 0.79             |
| agstudy - Substitute    | 2.03                | 1.9              |
+-------------------------+---------------------+------------------+
Run Code Online (Sandbox Code Playgroud)

看起来像.SDCols最适合速度,并使用替代易于阅读的代码.

G. *_*eck 11

1.获取/如果 尝试使用get:

DT[, (Col4) := if (get(Col1) == "A") get(Col2) else get(Col3), by = 1:nrow(DT)]
Run Code Online (Sandbox Code Playgroud)

2.获取/加入 或尝试这种方法:

setkeyv(DT, Col1)
DT[, (Col4):=get(Col3)]["A", (Col4):=get(Col2)]
Run Code Online (Sandbox Code Playgroud)

3. .SDCols 或者这个:

setkeyv(DT, Col1)
DT[, (Col4):=.SD, .SDcols = Col3]["A", (Col4):=.SD, .SDcols = Col2]
Run Code Online (Sandbox Code Playgroud)

更新:添加了一些其他方法.

  • 在第一个答案中,它应该是`Col4:=`或`c("Col4"):=`. (2认同)

ags*_*udy 5

使用ifelseget:

DT[, (Col4) := ifelse (get(Col1) == "A",get(Col2) , get(Col3))]
Run Code Online (Sandbox Code Playgroud)

或者substitute用来创建这样的表达式:

expr <- substitute(a4 := ifelse (a1 == "A",a2 , a3),
                   list(a1=as.name(Col1),
                        a2=as.name(Col2),
                        a3=as.name(Col3),
                        a4=as.name(Col4)))

DT[, eval(expr)]
Run Code Online (Sandbox Code Playgroud)