【问题标题】:Defining an infix operator for use within a formula定义在公式中使用的中缀运算符
【发布时间】:2015-09-16 19:08:23
【问题描述】:

我正在尝试创建一个更简洁的 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 在遇到 * 时如何解释它一个公式,以便我可以进行所需的细微调整。

【问题讨论】:

  • 它们被解释为 stats:::model.frame.default in c github.com/wch/r-source/blob/…
  • @rawr 谢谢。不能说我知道 C 代码中发生了什么——我看到它们“定义”了 formula 理解的每个符号,但它们似乎只使用 tildeSymbol。这是否意味着无论如何我将无法获得自己的中缀而不去 C 和定义,比如 plusColonSymbol 就像在这里完成?
  • @HeatherTurner 的回答对我来说似乎完全正确。如果您真的想开始弄乱扩展公式,我建议您从(1)查看model.frame() 结果的terms 组件和(2)查看代码here ...

标签: r formula infix-operator


【解决方案1】:

在这种情况下,您不需要定义新的运算符:在公式中,d1/d2 扩展为 d1 + d1:d2。换句话说,d1/d2 指定 d2 嵌套在 d1 中。继续你的例子:

out3 <- lm(y ~ cut(v2,breaks=c(0,.25,.8,1))/I(v1 < .3))
all.equal(coef(out1), coef(out3))
# [1] TRUE

更多课程

因子可以是交叉嵌套。如果可以观察到两个因素水平的每个组合,例如两个因素,则交叉两个因素。性别和治疗、温度和 pH 值等。如果该因子的每个级别只能在另一个因子的一个级别中观察到,则该因子嵌套在另一个因子中,例如城镇和国家,工作人员和商店等。

这些关系反映在模型的参数化中。对于交叉因素,我们使用d1*d2d1 + d2 + d1:d2 来给出每个因素的主效应以及交互作用。对于嵌套因子,我们使用d1/d2d1 + d1:d2d1 的每个级别提供1 + d2 形式的单独子模型。

嵌套的想法不限于因素,例如,我们可以使用sex/x 来为男性和女性在x 上拟合一个单独的线性回归。

在公式中,%in% 等价于:,但它可用于强调数据/模型的嵌套或层次结构。例如,a + b %in% aa + a:b 相同,但将其读作“a 中的 a 加 b”可以更好地描述正在拟合的模型。即便如此,使用/的好处是简化模型公式的同时强调结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    相关资源
    最近更新 更多