Это на самом деле довольно интересное наблюдение. Фактически, среди всех 6 графиков, поддерживаемых plot.lm
, в этом случае сбой только 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
, Q-Q участок просто производится следующим образом:
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
будет.
Можете ли вы опубликовать 'summary fit'? – Christoph
@ Кристоф Я собирался опубликовать резюме, но ответ Чжэюань Ли достаточно хорошо дополняет мой пост. – ZzKr