8

注意:我在这个问题中遇到的确切问题不适用于最新版本的数据表。如果你想做标题中描述的事情,请查看包FAQ中的相应问题,1.6 OK,但我不知道提前表达。我如何以编程方式传递它们?.

我已经看到了一个答案,该答案说明了如何构造要在其中进行评估的表达式

DT[,j=eval(expr)]

我将它与作业一起使用,```:=`(mycol=my_calculation)`,我想知道......

  • 如何动态分配名称“mycol”?
  • 让“my_calculation”采用动态确定的一组列的正确方法是什么?

通过“动态”,我的意思是“在我为我的“编写代码后确定expr”。

新示例

编辑:为了更好地说明这个问题,这里是不同的例子。查看编辑历史以查看原件。

require(data.table)
require(plyr)
options(datatable.verbose=TRUE)
DT <- CJ(a=0:1,b=0:1,y=2)

# setup:
expr  <- as.quoted(paste(expression(get(col_in_one)+get(col_in_two))))[[1]]

# usage: 
col_in_one <- 'a'
col_in_two <- 'b'
col_out    <- 'bah'
DT[,(col_out):=eval(expr)] # fails, should take the form j=eval(expr)

我想保持设置和使用阶段分开,所以我的代码更容易维护。我的真实表达比这个例子更混乱(它只选择一列)。

问题

第一个问题:如何使分配给列“col_out”动态化?我的意思是:我想同时指定“cols_in_*”和“col_out”。

我曾尝试在“expr”中创建各种表达式,但as.quoted会抛出一个错误,即未将某些内容放在=符号的左侧。

第二个问题:如何避免使用警告get

警告建议使用.SDcols, 来[.data.table告知我正在使用哪些列。但是,如果我使用该.SDcols参数,另一个警告说除非.SD正在使用,否则这样做是没有意义的。

暂定解决方案

到目前为止,我的解决方案是......

# Ricardo + eddi:
expr2 <- as.quoted(paste(expression(`:=`(
  Vtmp=.SD[[col_in_one]]+.SD[[col_in_two]]))))[[1]]

# usage
col_in_one <- 'a'
col_in_two <- 'b'
col_out    <- 'bah'
DT[,eval(expr2),.SDcols=c(col_in_one,col_in_two)]
setnames(DT,'Vtmp',col_out)

这仍然涉及分两步执行操作并跟踪“Vtmp”的小烦恼,因此第一个问题仍然部分开放。

4

2 回答 2

8

也许我不太了解这个问题,但这是否足够:

DT[, (col_out) := .SD[[col_in_one]]+.SD[[col_in_two]],
     .SDcols = c(col_in_one,col_in_two)]
DT
#   a b y bah
#1: 0 0 2   0
#2: 0 1 2   1
#3: 1 0 2   1
#4: 1 1 2   2

要回答已编辑的问题,要eval使其正常工作,请.SD用作环境:

DT[, (col_out) := eval(expr, .SD)]

另外,请参阅此问题和那里的更新 - data.table 中的 eval 和 quote

于 2013-10-09T15:52:14.123 回答
5

最简单的方法是在评估表达式之后设置它。毕竟,执行时间是恒定的,几乎为 0。

someDummyVar <- "tempColName_XCWF5D"
DT [, (someDummyVar) := eval(expr) ]

setnames(DT, someDummyVar, RealColumnName)

至于问题二:不要打开详细警告,您不会收到详细警告;)

options(datatable.verbose=FALSE)

至于Reduce:尝试将其作为一个单独且简化的问题发布,以便更容易理解您正在做的事情(在eval问题之外)

于 2013-10-09T15:39:04.673 回答