我一直无法找到这个问题的答案,主要是因为使用单独字母(例如“I”)进行任何谷歌搜索都会导致问题。
在这样的模型中,“I”有什么作用?
data(rock)
lm(area~I(peri - mean(peri)), data = rock)
鉴于以下内容无法正常工作:
lm(area ~ (peri - mean(peri)), data = rock)
而且这个确实有效:
rock$peri - mean(rock$peri)
任何关于如何自己进行研究的关键词都将非常有帮助。
我一直无法找到这个问题的答案,主要是因为使用单独字母(例如“I”)进行任何谷歌搜索都会导致问题。
在这样的模型中,“I”有什么作用?
data(rock)
lm(area~I(peri - mean(peri)), data = rock)
鉴于以下内容无法正常工作:
lm(area ~ (peri - mean(peri)), data = rock)
而且这个确实有效:
rock$peri - mean(rock$peri)
任何关于如何自己进行研究的关键词都将非常有帮助。
I
隔离或保护I( ... )
内部的内容,防止R公式解析代码扫视。它允许标准的R运算符像在公式外部使用时一样工作,而不被视为特殊的公式运算符。
例如:
y ~ x + x^2
would, to R, mean "give me:
x
= x
的主效应,以及x^2
= x
的主效应和二阶交互作用",而不是意图的x
加上x
平方:
> 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^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....
(最后一列是正确的,只是看起来很奇怪,因为它属于 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
的来源)。X:X
而不是X^2
,但它仍然没有起作用,你知道为什么吗? - Jason GoalI(X:X)
做什么?我猜它会尝试应用序列操作符,就像 seq(from = X, to = X, by = 1L)
一样。但这对我来说毫无意义。 - Gavin SimpsonX: Y
是指 X
和 Y
之间的交互项吗? - Jason GoalX:Y
(不用I()
包裹)表示X
和Y
之间的交互作用。这就是重点;:
、^
和其他一些运算符在公式中有不同的用途/解释。如果您想要通常的非公式解释,您需要将其包装在I()
中。我认为X:X
不会起作用,因为它并不是字面意义上的X * X
,因为这对于因子变量无效。:
表示交互作用。 - Gavin Simpson从文档中可以看到:
函数I有两种主要用途。
针对这一点:
df1 <- data.frame(stringi = I("dog"))
df2 <- data.frame(stringi = "dog")
str(df1)
str(df2)
针对这一点:
lm(mpg ~ disp + drat, mtcars)
lm(mpg ~ I(disp + drat), mtcars)
第二行。“创建一个新的预测器”,它是disp + drat
的字面意义之和。
formula
的文档中写道:
所以我认为这段代码应该是:"^ 运算符表示交叉到指定的程度。例如 (a+b+c)^2 等同于 (a+b+c)*(a+b+c),进一步展开为一个包含 a、b 和 c 的主效应以及它们的二阶交互作用的公式。"
lm(Y ~ X^2)
X
,以及(3)二次项的系数X^2
。但它并没有。X1 <- runif(100)
X1_2 <- X1^2
set.seed(61)
Y1 <- 5*X1 + -4.5*X1^2 + rnorm(100,0,.05)
> lm(Y1 ~ X1^2)
>
> Call: lm(formula = Y1 ~ X1^2)
>
> Coefficients: (Intercept) X1
> 1.0486 0.0343
> > lm(Y1 ~ X1)
>
> Call: lm(formula = Y1 ~ X1)
>
> Coefficients: (Intercept) X1
> 1.0486 0.0343
I
时,我得到了这个:> > lm(Y1 ~ I(X1^2))
>
> Call: lm(formula = Y1 ~ I(X1^2))
>
> Coefficients: (Intercept) I(X1^2)
> 1.0602 -0.1145 ,
> > lm(Y1 ~ X1 + I(X1^2))
>
> Call: lm(formula = Y1 ~ X1 + I(X1^2))
>
> Coefficients: (Intercept) X1 I(X1^2) -0.009738
> 5.021233 -4.518124
poly
函数对于所有这些来说是最好的选择。)
help("I")
。 - RolandI()
=绝缘。这可能会有所帮助。而且我同意I()
的文档确实有点简略。 - Stephan KolassaI
是一个函数,所以你需要它们,就像你在mean()
上需要它们一样。此外(但这个效果是次要的),它还可以视觉上指示哪些内容受到公式解析代码的保护。 - Gavin Simpson