plot.lm错误:$运算符对原子向量无效

k88*_*074 3 plot regression r linear-regression lm

我有以下带有转换的回归模型:

fit <- lm( I(NewValue ^ (1 / 3)) ~ I(CurrentValue ^ (1 / 3)) + Age + Type - 1,
           data = dataReg)
plot(fit)                                                                      
Run Code Online (Sandbox Code Playgroud)

但是plot给我以下错误:

Error: $ operator is invalid for atomic vectors
Run Code Online (Sandbox Code Playgroud)

关于我在做什么错的任何想法吗?

注意summarypredictresiduals都可以正常工作。

李哲源*_*李哲源 5

这实际上是一个非常有趣的观察。实际上,plot.lm在这种情况下,在所有受支持的6个图中,只有QQ图失败。考虑以下可重现的示例:

x <- runif(20)
y <- runif(20)
fit <- lm(I(y ^ (1/3)) ~ I(x ^ (1/3)))
## only `which = 2L` (QQ plot) fails; `which = 1, 3, 4, 5, 6` all work
stats:::plot.lm(fit, which = 2L)
Run Code Online (Sandbox Code Playgroud)

在内部plot.lm,QQ图简单地产生如下:

rs <- rstandard(fit)  ## standardised residuals
qqnorm(rs)  ## fine
## inside `qqline(rs)`
yy <- quantile(rs, c(0.25, 0.75))
xx <- qnorm(c(0.25, 0.75))
slope <- diff(yy)/diff(xx)
int <- yy[1L] - slope * xx[1L]
abline(int, slope)  ## this fails!!!
Run Code Online (Sandbox Code Playgroud)

错误:$运算符对原子向量无效

因此,这纯粹是abline功能问题!注意:

is.object(int)
# [1] TRUE

is.object(slope)
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

即,两个intslope具有类属性(?is.object,它是检查对象是否具有类属性的非常有效的方式)。什么级别?

class(int)
# [1] AsIs

class(slope)
# [1] AsIs
Run Code Online (Sandbox Code Playgroud)

这是使用的结果I()。确切地说,它们rs从响应变量继承或从响应变量继承此类。也就是说,如果我们I()在响应时使用模型公式的RHS ,则会得到这种行为。

您可以在此处进行一些实验:

abline(as.numeric(int), as.numeric(slope))  ## OK
abline(as.numeric(int), slope)  ## OK
abline(int, as.numeric(slope))  ## fails!!
abline(int, slope)  ## fails!!
Run Code Online (Sandbox Code Playgroud)

因此abline(a, b)对第一个参数是否a具有类属性非常敏感。

为什么?因为abline可以接受带有“ lm”类的线性模型对象。内部abline

if (is.object(a) || is.list(a)) {
    p <- length(coefa <- as.vector(coef(a)))
Run Code Online (Sandbox Code Playgroud)

如果a有一个类,abline则将其假定为模型对象(无论它是否真的是!!!),然后尝试使用coef来获取系数。此处进行的检查相当不可靠;我们可以abline很容易地使失败:

plot(0:1, 0:1)
a <- 0  ## plain numeric
abline(a, 1)  ## OK
class(a) <- "whatever"  ## add a class
abline(a, 1)  ## oops, fails!!!
Run Code Online (Sandbox Code Playgroud)

错误:$运算符对原子向量无效

因此,得出的结论是:避免I()在模型公式中使用您的响应变量。可以有I()协变量,但不能有响应。lm而且大多数通用函数都不会遇到麻烦,但是plot.lm会。

  • 确实,“残差拟合”图是正确生成的,而在绘制QQ图时遇到了问题。当我避免I()时,一切都会顺利进行。 (2认同)