16

我的问题与创建一个变量有关,该变量取决于 data.table 中的其他列,而事先不知道任何变量名称。

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

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"

下面的代码有效,但感觉就像我在滥用这个包!

DT[,Col4:=ifelse(DT[[Col1]]=="A",
                 DT[[Col2]],
                 DT[[Col3]]),with=FALSE]

更新: 谢谢,我对下面的答案做了一些快速的计时。一次在具有 500 万行且仅相关列的 data.table 上,然后在添加 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              |
+-------------------------+---------------------+------------------+

看起来 .SDCols 最适合速度和使用易于阅读的代码的替代品。

4

2 回答 2

12

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

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

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

setkeyv(DT, Col1)
DT[, (Col4):=get(Col3)]["A", (Col4):=get(Col2)]

3. .SDCols 或这个:

setkeyv(DT, Col1)
DT[, (Col4):=.SD, .SDcols = Col3]["A", (Col4):=.SD, .SDcols = Col2]

更新:添加了一些额外的方法。

于 2013-07-03T14:45:27.850 回答
6

使用ifelseget

DT[, (Col4) := ifelse (get(Col1) == "A",get(Col2) , get(Col3))]

或使用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)]
于 2013-07-03T16:51:01.520 回答