34

我一直无法找到这个问题的答案,主要是因为使用独立字母(如“I”)在谷歌上搜索任何内容都会导致问题。

“我”在这样的模型中做了什么?

data(rock)
lm(area~I(peri - mean(peri)), data = rock)

考虑到以下不起作用:

lm(area ~ (peri - mean(peri)), data = rock)

确实有效:

rock$peri - mean(rock$peri)

关于如何自己研究这个的任何关键词也将非常有帮助。

4

2 回答 2

55

I 隔离隔离I( ... )R 的公式解析代码的内容。它允许标准 R 运算符像在公式之外使用它们一样工作,而不是被视为特殊的公式运算符。

例如:

y ~ x + x^2

对 R 来说,意思是“给我:

  1. x= 的主效应x,和
  2. x^2= "的主效应和二阶交互作用x

不是预期的xx平方:

> model.frame( y ~ x + x^2, data = data.frame(x = rnorm(5), y = rnorm(5)))
           y           x
1 -1.4355144 -1.85374045
2  0.3620872 -0.07794607
3 -1.7590868  0.96856634
4 -0.3245440  0.18492596
5 -0.6515630 -1.37994358

这是因为^是公式中的特殊运算符,如 中所述?formula。您最终只包含x在模型框架中,因为公式中x的项已经包含了 的主要影响x,并且没有什么可以交叉x来获得项中的二阶交互作用x^2

要获得通常的运算符,您需要使用I()将调用与公式代码隔离开来:

> model.frame( y ~ x + I(x^2), data = data.frame(x = rnorm(5), y = rnorm(5)))
            y          x       I(x^2)
1 -0.02881534  1.0865514 1.180593....
2  0.23252515 -0.7625449 0.581474....
3 -0.30120868 -0.8286625 0.686681....
4 -0.67761458  0.8344739 0.696346....
5  0.65522764 -0.9676520 0.936350....

(最后一列是正确的,它只是看起来很奇怪,因为它属于 class AsIs。)

在您的示例中,-当在公式中使用时,表示从模型中删除了一个术语,您希望在其中具有减法-的通常二元运算符含义:

> model.frame( y ~ x - mean(x), data = data.frame(x = rnorm(5), y = rnorm(5)))
Error in model.frame.default(y ~ x - mean(x), data = data.frame(x = rnorm(5),  : 
  variable lengths differ (found for 'mean(x)')

这失败的原因mean(x)是长度为 1 的向量,并且model.frame()非常正确地告诉您这与其他变量的长度不匹配。一种解决方法是I()

> model.frame( y ~ I(x - mean(x)), data = data.frame(x = rnorm(5), y = rnorm(5)))
           y I(x - mean(x))
1  1.1727063   1.142200....
2 -1.4798270   -0.66914....
3 -0.4303878   -0.28716....
4 -1.0516386   0.542774....
5  1.5225863   -0.72865....

因此,如果您想在公式中使用具有特殊含义的运算符,但需要其非公式含义,则需要将运算的元素包装在I( ).

阅读?formula有关特殊运算符?I的更多信息,以及有关函数本身及其在数据帧中的其他主要用例的更多详细信息(AsIs如果您感兴趣,这是位的来源)。

于 2014-06-12T19:43:11.873 回答
2

From the docs:

功能 I 有两个主要用途。

  • 在函数 data.frame 中。通过在对 data.frame 的调用中将对象包含在 I() 中来保护对象,可以抑制字符向量到因子的转换和名称的删除,并确保矩阵作为单列插入。I 还可以用于保护要添加到数据框或通过 as.data.frame 转换为数据框的对象。

为了解决这一点:

df1 <- data.frame(stringi = I("dog"))
df2 <- data.frame(stringi = "dog")

str(df1)
str(df2)
  • 在函数公式中。它用于禁止将“+”、“-”、“*”和“^”等运算符解释为公式运算符,因此将它们用作算术运算符。这被 terms.formula 解释为一个符号。

为了解决这一点:

lm(mpg ~ disp + drat, mtcars)
lm(mpg ~ I(disp + drat), mtcars)

第二行。“创建一个新的预测变量”,即disp + drat

于 2018-09-25T10:00:00.787 回答