有类似的问题,我正在寻找比为这个问题提供的更通用的解决方案:如何替换语言对象中的符号?
我有一个未计算的表达式foo <- quote(bar + baz)
,它是其他表达式中的一个变量:qux <- quote(bla + foo)
。
我们可以检查:
exists("foo", envir=.GlobalEnv) & class(foo)=="call"
[1] TRUE
exists("qux", envir=.GlobalEnv) & class(qux)=="call"
[1] TRUE
现在我想编写一个通用函数,将(解析?)分解qux
成组件表达式,并用它们的值替换存在于.GlobalEnv
和类call
中的那些:
replaceFUN <- function(x) {
# do something
}
运行replaceFUN(qux)
应该返回:
bla + (bar + baz)
实际问题的背景:
我正在构建一个量化交易规则回测引擎。我的目标是延迟对 quote()d 表达式的评估,例如在定义之后的规则和指标计算。
require(data.table)
require(TTR) # for the `SMA` function
DT <- data.table(Instrument=rep("SPX",3),Date=1:3, Close=c(1050, 1052, 1051))
# define parameters
nSMA <-2
t <- 2
# define indicators
time.filter <- quote( Date==t )
moving.average <- quote( SMA(Close, nSMA) )
buy <- quote( Close > moving.average & time.filter )
AddColumn <- function(x, colname) {
DT[,eval(substitute(colname)):=eval(x, envir=.SD)]
}
AddColumn(time.filter, "filter")
Instrument Date Close filter
1: SPX 1 1050 FALSE
2: SPX 2 1052 TRUE
3: SPX 3 1051 FALSE
AddColumn(moving.average, "MA")
Instrument Date Close filter MA
1: SPX 1 1050 FALSE NA
2: SPX 2 1052 TRUE 1051.0
3: SPX 3 1051 FALSE 1051.5
AddColumn(buy, "Buy")
Error in Close > moving.average & time.filter :
operations are possible only for numeric, logical or complex types
这显然会引发错误,因为AddColumn
函数缺少解析嵌套变量moving.average
和time.filter
变量(以及用户定义和嵌套的任何其他变量)的机制。内部规则的嵌套buy
是为了可读性,确实是一种语法糖。