| 42333 |
ripley |
1 |
% File src/library/stats/man/plot.lm.Rd
|
| 68948 |
ripley |
2 |
% Part of the R package, https://www.R-project.org
|
| 88563 |
hornik |
3 |
% Copyright 1995-2025 R Core Team
|
| 42333 |
ripley |
4 |
% Distributed under GPL 2 or later
|
|
|
5 |
|
| 27442 |
ripley |
6 |
\name{plot.lm}
|
| 56186 |
murdoch |
7 |
\alias{plot.lm}
|
| 63605 |
ripley |
8 |
% \alias{plot.mlm} %which is .NotYetImplemented()
|
| 81512 |
smeyer |
9 |
\title{Plot Diagnostics for an \code{lm} Object}
|
| 27442 |
ripley |
10 |
\usage{
|
| 76078 |
maechler |
11 |
\method{plot}{lm}(x, which = c(1,2,3,5), %% was which = 1:4
|
| 84026 |
plummer |
12 |
caption = list("Residuals vs Fitted", "Q-Q Residuals",
|
| 56280 |
ripley |
13 |
"Scale-Location", "Cook's distance",
|
|
|
14 |
"Residuals vs Leverage",
|
| 81099 |
maechler |
15 |
expression("Cook's dist vs Leverage* " * h[ii] / (1 - h[ii]))),
|
| 76078 |
maechler |
16 |
panel = if(add.smooth) function(x, y, ...)
|
| 89683 |
pd |
17 |
panel.smooth(x, y, iter=iter.smooth, ...) else panel.raw,
|
| 35617 |
maechler |
18 |
sub.caption = NULL, main = "",
|
| 27442 |
ripley |
19 |
ask = prod(par("mfcol")) < length(which) && dev.interactive(),
|
|
|
20 |
\dots,
|
| 34063 |
maechler |
21 |
id.n = 3, labels.id = names(residuals(x)), cex.id = 0.75,
|
| 35617 |
maechler |
22 |
qqline = TRUE, cook.levels = c(0.5, 1.0),
|
| 81110 |
maechler |
23 |
cook.col = 8, cook.lty = 2, cook.legendChanges = list(),
|
| 76078 |
maechler |
24 |
add.smooth = getOption("add.smooth"),
|
| 77525 |
pd |
25 |
iter.smooth = if(isGlm) 0 else 3,
|
| 89684 |
pd |
26 |
panel.raw = points,
|
| 76078 |
maechler |
27 |
label.pos = c(4,2),
|
| 89684 |
pd |
28 |
cex.caption = 1, cex.oma.main = 1.25,
|
|
|
29 |
extend.ylim.f = 0.08
|
| 81101 |
maechler |
30 |
)
|
| 27442 |
ripley |
31 |
}
|
|
|
32 |
\arguments{
|
|
|
33 |
\item{x}{\code{lm} object, typically result of \code{\link{lm}} or
|
|
|
34 |
\code{\link{glm}}.}
|
| 81099 |
maechler |
35 |
\item{which}{a subset of the numbers \code{1:6}, by default \code{1:3, 5},
|
|
|
36 |
referring to \enumerate{
|
| 85977 |
hornik |
37 |
\item "Residuals vs Fitted", aka \sQuote{\I{Tukey}-\I{Anscombe}} plot % 1
|
| 84026 |
plummer |
38 |
\item "Residual Q-Q" plot % 2
|
| 81099 |
maechler |
39 |
\item "Scale-Location" % 3
|
|
|
40 |
\item "Cook's distance" % 4
|
|
|
41 |
\item "Residuals vs Leverage" % 5
|
|
|
42 |
\item "Cook's dist vs Lev./(1-Lev.)" % 6
|
| 81512 |
smeyer |
43 |
}
|
|
|
44 |
See also \sQuote{Details} below.}
|
| 45710 |
maechler |
45 |
\item{caption}{captions to appear above the plots;
|
|
|
46 |
\code{\link{character}} vector or \code{\link{list}} of valid
|
| 68206 |
maechler |
47 |
graphics annotations, see \code{\link{as.graphicsAnnot}}, of length
|
| 81099 |
maechler |
48 |
6, the j-th entry corresponding to \code{which[j]}, see also the
|
|
|
49 |
default vector in \sQuote{Usage}. Can be set to
|
| 68206 |
maechler |
50 |
\code{""} or \code{NA} to suppress all captions.
|
| 45710 |
maechler |
51 |
}
|
| 89683 |
pd |
52 |
\item{panel}{panel function for plotting points. This will by default
|
| 89684 |
pd |
53 |
add a smoothing curve via
|
| 89683 |
pd |
54 |
\code{\link{panel.smooth}}
|
|
|
55 |
if \code{add.smooth = TRUE} and use \code{panel.raw} (which by
|
| 89684 |
pd |
56 |
default is \code{\link{points}}) otherwise. For the residuals vs
|
| 89683 |
pd |
57 |
leverage plot, the smooth makes little sense and
|
|
|
58 |
\code{panel.raw} is used.}
|
| 49470 |
ripley |
59 |
\item{sub.caption}{common title---above the figures if there are more
|
|
|
60 |
than one; used as \code{sub} (s.\code{\link{title}}) otherwise. If
|
|
|
61 |
\code{NULL}, as by default, a possible abbreviated version of
|
| 34063 |
maechler |
62 |
\code{deparse(x$call)} is used.}
|
| 49470 |
ripley |
63 |
\item{main}{title to each plot---in addition to \code{caption}.}
|
| 27442 |
ripley |
64 |
\item{ask}{logical; if \code{TRUE}, the user is \emph{ask}ed before
|
|
|
65 |
each plot, see \code{\link{par}(ask=.)}.}
|
|
|
66 |
\item{\dots}{other parameters to be passed through to plotting
|
|
|
67 |
functions.}
|
|
|
68 |
\item{id.n}{number of points to be labelled in each plot, starting
|
|
|
69 |
with the most extreme.}
|
|
|
70 |
\item{labels.id}{vector of labels, from which the labels for extreme
|
|
|
71 |
points will be chosen. \code{NULL} uses observation numbers.}
|
|
|
72 |
\item{cex.id}{magnification of point labels.}
|
| 35621 |
maechler |
73 |
\item{qqline}{logical indicating if a \code{\link{qqline}()} should be
|
| 68201 |
maechler |
74 |
added to the normal Q-Q plot.}
|
| 34063 |
maechler |
75 |
\item{cook.levels}{levels of Cook's distance at which to draw contours.}
|
| 81110 |
maechler |
76 |
\item{cook.col, cook.lty}{color and line type to use for these contour
|
|
|
77 |
lines.}
|
|
|
78 |
\item{cook.legendChanges}{a \code{\link{list}} (or \code{NULL} to
|
|
|
79 |
suppress the call) of arguments to \code{\link{legend}} which should be
|
|
|
80 |
\emph{modified} from (or added to) the \code{plot.lm()} default \code{
|
| 81512 |
smeyer |
81 |
list(x = "bottomleft", legend = "Cook's distance",
|
| 81110 |
maechler |
82 |
lty = cook.lty, col = cook.col, text.col = cook.col,
|
| 81512 |
smeyer |
83 |
bty = "n", x.intersp = 1/4, y.intersp = 1/8) }.}
|
| 35617 |
maechler |
84 |
\item{add.smooth}{logical indicating if a smoother should be added to
|
|
|
85 |
most plots; see also \code{panel} above.}
|
| 76078 |
maechler |
86 |
\item{iter.smooth}{the number of robustness iterations, the argument
|
|
|
87 |
\code{iter} in \code{\link{panel.smooth}()}; the default uses no such
|
| 77525 |
pd |
88 |
iterations for \code{\link{glm}} fits which is
|
|
|
89 |
particularly desirable for the (predominant) case of binary
|
|
|
90 |
observations, but also for other models where the response
|
|
|
91 |
distribution can be highly skewed.}
|
| 89684 |
pd |
92 |
\item{panel.raw}{a function to use for plots without a smoother.}
|
| 34063 |
maechler |
93 |
\item{label.pos}{positioning of labels, for the left half and right
|
| 81102 |
maechler |
94 |
half of the graph respectively, for plots 1-3, 5, 6.}
|
| 43067 |
ripley |
95 |
\item{cex.caption}{controls the size of \code{caption}.}
|
| 68206 |
maechler |
96 |
\item{cex.oma.main}{controls the size of the \code{sub.caption} only if
|
|
|
97 |
that is \emph{above} the figures when there is more than one.}
|
| 81101 |
maechler |
98 |
\item{extend.ylim.f}{a numeric vector of length 1 or 2, to be used in
|
|
|
99 |
\code{ylim <- \link{extendrange}(r=ylim, f = *)}
|
|
|
100 |
for plots \code{1} and \code{5} when \code{id.n} is non-empty.}
|
| 27442 |
ripley |
101 |
}
|
|
|
102 |
\description{
|
| 34063 |
maechler |
103 |
Six plots (selectable by \code{which}) are currently available: a plot
|
| 27442 |
ripley |
104 |
of residuals against fitted values, a Scale-Location plot of
|
| 50807 |
ripley |
105 |
\eqn{\sqrt{| residuals |}}{sqrt(| residuals |)}
|
| 84026 |
plummer |
106 |
against fitted values, a Q-Q plot of residuals, a
|
| 34063 |
maechler |
107 |
plot of Cook's distances versus row labels, a plot of residuals
|
|
|
108 |
against leverages, and a plot of Cook's distances against
|
| 68206 |
maechler |
109 |
leverage/(1-leverage). By default, the first three and \code{5} are
|
|
|
110 |
provided.
|
| 27442 |
ripley |
111 |
}
|
|
|
112 |
\details{
|
|
|
113 |
\code{sub.caption}---by default the function call---is shown as
|
|
|
114 |
a subtitle (under the x-axis title) on each plot when plots are on
|
|
|
115 |
separate pages, or as a subtitle in the outer margin (if any) when
|
|
|
116 |
there are multiple plots per page.
|
|
|
117 |
|
| 81099 |
maechler |
118 |
The \sQuote{Scale-Location} plot (\code{which=3}), also called \sQuote{Spread-Location} or
|
| 42961 |
ripley |
119 |
\sQuote{S-L} plot, takes the square root of the absolute residuals in
|
| 74363 |
maechler |
120 |
order to diminish skewness (\eqn{\sqrt{| E |}}{sqrt(|E|)} is much less skewed
|
| 27442 |
ripley |
121 |
than \eqn{| E |} for Gaussian zero-mean \eqn{E}).
|
|
|
122 |
|
| 81099 |
maechler |
123 |
The \sQuote{S-L}, the Q-Q, and the Residual-Leverage (\code{which=5}) plot use
|
| 34063 |
maechler |
124 |
\emph{standardized} residuals which have identical variance (under the
|
|
|
125 |
hypothesis). They are given as
|
| 50807 |
ripley |
126 |
\eqn{R_i / (s \times \sqrt{1 - h_{ii}})}{R[i] / (s * sqrt(1 - h.ii))}
|
| 81099 |
maechler |
127 |
where the \emph{\sQuote{leverages}} \eqn{h_{ii}}{h.ii} are the diagonal entries
|
|
|
128 |
of the hat matrix,
|
| 50420 |
ripley |
129 |
\code{\link{influence}()$hat} (see also \code{\link{hat}}), and
|
| 81099 |
maechler |
130 |
where the Residual-Leverage plot uses the standardized Pearson residuals
|
| 45676 |
maechler |
131 |
(\code{\link{residuals.glm}(type = "pearson")}) for \eqn{R[i]}.
|
| 34063 |
maechler |
132 |
|
| 81099 |
maechler |
133 |
The Residual-Leverage plot (\code{which=5}) shows contours of equal Cook's distance,
|
| 36637 |
ripley |
134 |
for values of \code{cook.levels} (by default 0.5 and 1) and omits
|
| 45687 |
maechler |
135 |
cases with leverage one with a warning. If the leverages are constant
|
|
|
136 |
(as is typically the case in a balanced \code{\link{aov}} situation)
|
|
|
137 |
the plot uses factor level combinations instead of the leverages for
|
|
|
138 |
the x-axis. (The factor levels are ordered by mean fitted value.)
|
| 35617 |
maechler |
139 |
|
| 81512 |
smeyer |
140 |
In the Cook's distance vs leverage/(1-leverage) (= \dQuote{leverage*})
|
|
|
141 |
plot (\code{which=6}), contours of
|
| 71501 |
maechler |
142 |
standardized residuals (\code{\link{rstandard}(.)}) that are equal in
|
| 81099 |
maechler |
143 |
magnitude are lines through the origin. These lines are labelled with
|
|
|
144 |
the magnitudes. The x-axis is labeled with the (non equidistant)
|
|
|
145 |
leverages \eqn{h_{ii}}{h.ii}.
|
| 77525 |
pd |
146 |
|
| 84026 |
plummer |
147 |
For the \code{glm} case, the Q-Q plot is based on the absolute value
|
|
|
148 |
of the standardized deviance residuals. When the saddlepoint
|
|
|
149 |
approximation applies, these have an approximate half-normal
|
| 84029 |
smeyer |
150 |
distribution. The saddlepoint approximation is exact for the normal
|
|
|
151 |
and inverse Gaussian family, and holds approximately for the Gamma
|
|
|
152 |
family with small dispersion (large shape) and for the Poisson and
|
| 88563 |
hornik |
153 |
binomial families with large counts \bibcitep{R:Dunn+Smyth:2018}.
|
| 27442 |
ripley |
154 |
}
|
| 81099 |
maechler |
155 |
|
| 27442 |
ripley |
156 |
\references{
|
| 88563 |
hornik |
157 |
\bibshow{*,
|
|
|
158 |
R:Belsley+Kuh+Welsch:1980,
|
|
|
159 |
R:Cook+Weisberg:1982,
|
| 88704 |
hornik |
160 |
R:Firth:1991,
|
| 88598 |
hornik |
161 |
R:Hinkley:1975,
|
|
|
162 |
R:McCullagh+Nelder:1989}
|
| 27442 |
ripley |
163 |
}
|
|
|
164 |
\author{
|
|
|
165 |
John Maindonald and Martin Maechler.
|
|
|
166 |
}
|
|
|
167 |
\seealso{\code{\link{termplot}}, \code{\link{lm.influence}},
|
| 34063 |
maechler |
168 |
\code{\link{cooks.distance}}, \code{\link{hatvalues}}.
|
| 27442 |
ripley |
169 |
}
|
|
|
170 |
\examples{
|
| 41508 |
ripley |
171 |
require(graphics)
|
|
|
172 |
|
| 27442 |
ripley |
173 |
## Analysis of the life-cycle savings data
|
|
|
174 |
## given in Belsley, Kuh and Welsch.
|
| 56280 |
ripley |
175 |
lm.SR <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings)
|
|
|
176 |
plot(lm.SR)
|
| 27442 |
ripley |
177 |
|
| 44243 |
ripley |
178 |
## 4 plots on 1 page;
|
|
|
179 |
## allow room for printing model formula in outer margin:
|
| 81110 |
maechler |
180 |
par(mfrow = c(2, 2), oma = c(0, 0, 2, 0)) -> opar
|
| 27442 |
ripley |
181 |
plot(lm.SR)
|
| 61168 |
ripley |
182 |
plot(lm.SR, id.n = NULL) # no id's
|
|
|
183 |
plot(lm.SR, id.n = 5, labels.id = NULL) # 5 id numbers
|
| 27442 |
ripley |
184 |
|
| 44243 |
ripley |
185 |
## Was default in R <= 2.1.x:
|
|
|
186 |
## Cook's distances instead of Residual-Leverage plot
|
| 34063 |
maechler |
187 |
plot(lm.SR, which = 1:4)
|
|
|
188 |
|
| 81110 |
maechler |
189 |
## All the above fit a smooth curve where applicable
|
|
|
190 |
## by default unless "add.smooth" is changed.
|
|
|
191 |
## Give a smoother curve by increasing the lowess span :
|
| 61168 |
ripley |
192 |
plot(lm.SR, panel = function(x, y) panel.smooth(x, y, span = 1))
|
| 27442 |
ripley |
193 |
|
| 81110 |
maechler |
194 |
par(mfrow = c(2,1)) # same oma as above
|
| 27442 |
ripley |
195 |
plot(lm.SR, which = 1:2, sub.caption = "Saving Rates, n=50, p=5")
|
| 34063 |
maechler |
196 |
|
| 81512 |
smeyer |
197 |
## Cook's distance tweaking
|
| 81110 |
maechler |
198 |
par(mfrow = c(2,3)) # same oma ...
|
|
|
199 |
plot(lm.SR, which = 1:6, cook.col = "royalblue")
|
|
|
200 |
|
|
|
201 |
## A case where over plotting of the "legend" is to be avoided:
|
| 81512 |
smeyer |
202 |
if(dev.interactive(TRUE)) getOption("device")(height = 6, width = 4)
|
|
|
203 |
par(mfrow = c(3,1), mar = c(5,5,4,2)/2 +.1, mgp = c(1.4, .5, 0))
|
|
|
204 |
plot(lm.SR, which = 5, extend.ylim.f = c(0.2, 0.08))
|
|
|
205 |
plot(lm.SR, which = 5, cook.lty = "dotdash",
|
|
|
206 |
cook.legendChanges = list(x = "bottomright", legend = "Cook"))
|
|
|
207 |
plot(lm.SR, which = 5, cook.legendChanges = NULL) # no "legend"
|
| 81110 |
maechler |
208 |
|
| 34063 |
maechler |
209 |
\dontshow{
|
|
|
210 |
## An example with *long* formula that needs abbreviation:
|
| 81110 |
maechler |
211 |
par(mfrow = c(2,2))
|
| 61160 |
ripley |
212 |
for(i in 1:5) assign(paste("long.var.name", i, sep = "."), runif(10))
|
| 34063 |
maechler |
213 |
plot(lm(long.var.name.1 ~
|
|
|
214 |
long.var.name.2 + long.var.name.3 + long.var.name.4 + long.var.name.5))
|
| 27442 |
ripley |
215 |
}
|
| 81110 |
maechler |
216 |
par(opar) # reset par()s
|
| 34063 |
maechler |
217 |
}
|
| 27442 |
ripley |
218 |
\keyword{hplot}
|
|
|
219 |
\keyword{regression}
|