定义在公式中使用的中缀运算符

时间:2015-09-16 19:08:24

标签: r formula infix-operator

我正在尝试创建this解决方案的更简约版本,这需要以d1 + d1:d2形式指定公式的RHS。

鉴于公式上下文中的*是完全交互的简洁替代(即d1 * d2给出d1 + d2 + d1:d2),我的方法是尝试定义替代方案运算符,说%+:%使用我在其他应用程序中习惯使用的中缀方法, a la

"%+:%" <- function(d1,d2) d1 + d2 + d1:d2

然而,这可以预见失败,因为我没有注意评估;让我们举一个例子来说明我的进展:

set.seed(1029)
v1 <- runif(1000)
v2 <- runif(1000)
y <- .8*(v1 < .3) + .2 * (v2 > .25 & v2 < .8) - 
  .4 * (v2 > .8) + .1 * (v1 > .3 & v2 > .8)

通过这个例子,希望很清楚为什么简单地写出这两个术语可能是不可取的:

y ~ cut(v2, breaks = c(0, .25, .8, 1)) +
  cut(v2, breaks = c(0, .25, .8, 1)):I(v1 < .3)

接近我想要的输出的一个解决方法是将整个公式定义为函数:

plus.times <- function(outvar, d1, d2){
  as.formula(paste0(quote(outvar), "~", quote(d1),
                    "+", quote(d1), ":", quote(d2)))
}

这给出了传递给lm时的预期系数,但名称更难直接解释(特别是在我们注意提供d1d2描述的真实数据中名称,与此通用示例相反):

out1 <- lm(y ~ cut(v2, breaks = c(0, .25, .8, 1)) +
             cut(v2, breaks = c(0, .25, .8, 1)):I(v1 < .3))
out2 <- lm(plus.times(y, cut(v2, breaks = c(0, .25, .8, 1)), I(v1 < .3)))
any(out1$coefficients != out2$coefficients)
# [1] FALSE
names(out2$coefficients)
# [1] "(Intercept)"         "d1(0.25,0.8]"        "d1(0.8,1]"           "d1(0,0.25]:d2TRUE"  
# [5] "d1(0.25,0.8]:d2TRUE" "d1(0.8,1]:d2TRUE"

所以这不是最佳的。

有没有办法定义调整代码,以便我上面提到的中缀运算符按预期工作?如何更改plus.times的形式以便不重命名变量?

我一直在四处寻找(?formula?"~"?":"getAnywhere(formula.default)this回答等等。)但是还没有看到正确的R解释*当它在公式中遇到时,我可以做出我想要的微小调整。

0 个答案:

没有答案