這實際上是一個非常有趣的觀察。事實上,在plot.lm
支持的所有6個地塊中,在這種情況下只有Q-Q圖失敗。請看下面的可重複的例子:
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)
內plot.lm
,在分位圖被簡單地製造如下:
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!!!
Error: $ operator is invalid for atomic vectors
因此,這純粹abline
功能的問題!注:
is.object(int)
# [1] TRUE
is.object(slope)
# [1] TRUE
也即,二者int
和slope
具有類屬性(讀?is.object
;它是檢查對象是否具有類屬性非常有效的方式)。什麼級別?
class(int)
# [1] AsIs
class(slope)
# [1] AsIs
這是使用I()
的結果。準確地說,他們從rs
繼承這樣的類,並從響應變量中繼承。也就是說,如果我們使用I()
作爲響應,模型公式的RHS,我們會得到這種行爲。
你可以在這裏做一些實驗:
所以abline(a, b)
是第一個參數a
是否有類屬性,或者不是很靈敏。
爲什麼?因爲abline
可以接受具有「lm」類的線性模型對象。內部abline
:
if (is.object(a) || is.list(a)) {
p <- length(coefa <- as.vector(coef(a)))
如果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!!!
Error: $ operator is invalid for atomic vectors
因此,這裏的結論是:避免在模型公式中的響應變量使用I()
。關於協變量有I()
是確定的,但不是響應。 lm
和大多數通用函數不會有處理這個問題,但plot.lm
會。
你可以發表'總結適合'嗎? – Christoph
@Christoph本人即將發表總結,但李哲源的回答充分說明了我的觀點。 – ZzKr