2013-10-09 75 views
8

表情:我打了这个问题的确切问题并不适用于最新版本的数据表。如果您想按照标题中的描述进行操作,请查看包装常见问题解答1.6 OK, but I don’t know the expressions in advance. How do I programatically pass them in?中的相应问题。data.table`:=`分配与动态输入(现有列)和输出(新列名)

我看到an answer阐释如何构建表达在

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”的小烦恼,所以第一个问题还是部分打开。

+0

相关:HTTP:/ /stackoverflow.com/questions/15790743/data-table-meta-programming/15791747#15791747 –

回答

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)] 

而且,看到这个问题,并没有更新 - eval and quote in data.table

+0

像这样的东西可能没问题,但我宁愿保留我的表情,并将其用于(可能在多个地方)分开。此外,这应该是缓慢的,因为你正在创建'.SD'并且为'th'调用'[.data.table',对吧? .SD [[x]]比'get(x)'更好吗? ......好的,里卡多的链接解释说,它比“get”更好。 – Frank

+0

@Frank抱歉,我不认为我理解你想要做什么 - 一个更简单的例子集中在这个问题上会有所帮助。 Re' get':使用带'.SDcols'的'.SD'比'get'好,因为在第一种情况下,只有'.SDcols'中的列被构造为'.SD';因为这里使用了所有的'.SD',所以使用'.SD'应该没有任何开销(但它可能更好地完成整个reduce业务) – eddi

+0

感谢您提供它。我添加了一些粗体文本(我讨厌这样做)并更改了示例。我将编辑你的答案来匹配新的例子。 – Frank

5

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

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

setnames(DT, someDummyVar, RealColumnName) 

对于问题二:不要打开详细的警告,你不会得到详细的警告;)

options(datatable.verbose=FALSE) 

至于Reduce :尝试张贴,作为一个独立的和简化的问题,以便更容易跟着你在做什么(外面的eval问题)

+0

+1。对,是真的;我只是不希望维护两倍的代码来运行该操作。我想我可以将它们捆绑到一个函数中。关于#2的任何想法 - 避免“获取”警告;或#3 - 给予'eval'线性表达式本身,而不是'Reduce'它必须转换... – Frank

+0

@Frank,看看上面链接的问题 –

+0

啊,谢谢,我正在寻找这个问题。 – Frank