注意:我在此问题中遇到的确切问题不适用于最新版本的数据表.如果你想做标题中描述的事情,请查看包FAQ中的相应问题,1.6确定,但我不提前知道这些表达式.我如何以编程方式传递它们?.
我已经看到一个答案,说明如何构建一个要进行评估的表达式
DT[,j=eval(expr)]
Run Code Online (Sandbox Code Playgroud)
我正在使用这个作业,```:=`(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)
Run Code Online (Sandbox Code Playgroud)
我想将设置和使用阶段分开,因此我的代码更易于维护.我的真实表达比这个例子更麻烦(它只选择一列).
第一个问题:如何使分配到的列"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)
Run Code Online (Sandbox Code Playgroud)
这仍然涉及两步操作和跟踪"Vtmp"的轻微烦恼,所以第一个问题仍然是部分开放.
也许我不太了解这个问题,但这样就足够了:
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
Run Code Online (Sandbox Code Playgroud)
要回答已编辑的问题,要开始eval工作,请将其.SD用作环境:
DT[, (col_out) := eval(expr, .SD)]
Run Code Online (Sandbox Code Playgroud)
另外,请参阅此问题并在那里进行更新 - 在data.table中引用和引用
最简单的方法是在评估表达式之后设置它.毕竟,执行的时间是恒定的,接近0.
someDummyVar <- "tempColName_XCWF5D"
DT [, (someDummyVar) := eval(expr) ]
setnames(DT, someDummyVar, RealColumnName)
Run Code Online (Sandbox Code Playgroud)
至于问题二:不要打开详细的警告,你不会得到详细的警告;)
options(datatable.verbose=FALSE)
Run Code Online (Sandbox Code Playgroud)
至于Reduce:尝试将其作为单独的简化问题发布,以便更容易理解您正在做的事情(eval问题之外)
| 归档时间: |
|
| 查看次数: |
1066 次 |
| 最近记录: |