Predicted values are computed and, by default, plotted. Depending on the
fit method, a confidence band can be computed and plotted. The confidence
band can be interpreted similarly as that produced by stat_smooth()
and stat_poly_line().
Usage
stat_quant_line(
mapping = NULL,
data = NULL,
geom = "smooth",
position = "identity",
...,
orientation = NA,
quantiles = c(0.25, 0.5, 0.75),
formula = NULL,
se = length(quantiles) == 1L,
fit.seed = NA,
fm.values = FALSE,
n = 80,
method = "rq",
method.args = list(),
n.min = 3L,
level = 0.95,
type = "direct",
interval = "confidence",
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE
)Arguments
- mapping
The aesthetic mapping, usually constructed with
aes. Only needs to be set at the layer level if you are overriding the plot defaults.- data
A layer specific dataset, only needed if you want to override the plot defaults.
- geom
The geometric object to use display the data
- position
The position adjustment to use for overlapping points on this layer.
- ...
other arguments passed on to
layer. This can include aesthetics whose values you want to set, not map. Seelayerfor more details.- orientation
character Either "x" or "y" controlling the default for
formula. The letter indicates the aesthetic considered the explanatory variable in the model fit.- quantiles
numeric vector Values in 0..1 indicating the quantiles.
- formula
a formula object. Using aesthetic names
xandyinstead of original variable names.- se
logical Passed to
quantreg::predict.rq().- fit.seed
RNG seed argument passed to
set.seed(). Defaults toNA, indicating thatset.seed()should not be called.- fm.values
logical Add metadata and parameter estimates extracted from the fitted model object;
FALSEby default.- n
Number of points at which to predict with the fitted model.
- method
function or character If character, "rq", "rqss" or the name of a model fit function are accepted, possibly followed by the fit function's
methodargument separated by a colon (e.g."rq:br"). If a function different torq(), it must accept arguments namedformula,data,weights,tauandmethodand return a model fit object of classrq,rqsorrqss.- method.args
named list with additional arguments passed to
rq(),rqss()or to another function passed as argument tomethod.- n.min
integer Minimum number of distinct values in the explanatory variable (on the rhs of formula) for fitting to the attempted.
- level
numeric in range [0..1] Passed to
quantreg::predict.rq().- type
character Passed to
quantreg::predict.rq().- interval
character Passed to
quantreg::predict.rq().- na.rm
a logical indicating whether NA values should be stripped before the computation proceeds.
- show.legend
logical. Should this layer be included in the legends?
NA, the default, includes if any aesthetics are mapped.FALSEnever includes, andTRUEalways includes.- inherit.aes
If
FALSE, overrides the default aesthetics, rather than combining with them. This is most useful for helper functions that define both data and aesthetics and shouldn't inherit behaviour from the default plot specification, e.g.borders.
Value
The value returned by the statistic is a data frame, that will have
n rows of predicted values and and their confidence limits
for each quantile, with quantiles creating groups, or expanding
existing groups. The variables are x and
y with y containing predicted values. In addition,
quantile and quantile.f indicate the quantile used and and
edited group preserves the original grouping adding a new "level"
for each quantile. Is se = TRUE, a confidence band is computed and
values for it returned in ymax and ymin.
Details
stat_quant_line() behaves similarly to
ggplot2::stat_smooth() and stat_poly_line() but supports
fitting regressions for multiple quantiles in the same plot layer. This
statistic interprets the argument passed to formula accepting
y as well as x as explanatory variable, matching
stat_quant_eq(). While stat_quant_eq() supports only method
"rq", stat_quant_line() and stat_quant_band() support
both "rq" and "rqss", In the case of "rqss" the model
formula makes normally use of qss() to formulate the spline and its
constraints.
geom_smooth, which is used by default, treats each
axis differently and thus is dependent on orientation. If no argument is
passed to formula, it defaults to y ~ x. Formulas with
y as explanatory variable are treated as if x was the
explanatory variable and orientation = "y".
Package 'ggpmisc' does not define a new geometry matching this statistic as
it is enough for the statistic to return suitable x, y,
ymin, ymax and group values.
The minimum number of observations with distinct values in the explanatory
variable can be set through parameter n.min. The default n.min
= 3L is the smallest usable value. However, model fits with very few
observations are of little interest and using larger values of n.min
than the default is wise.
There are multiple uses for double regression on x and y. For example, when two variables are subject to mutual constrains, it is useful to consider both of them as explanatory and interpret the relationship based on them. So, from version 0.4.1 'ggpmisc' makes it possible to easily implement the approach described by Cardoso (2019) under the name of "Double quantile regression".
Computed variables
`stat_quant_line()` provides the following variables, some of which depend on the orientation:
- y or x
predicted value
- ymin or xmin
lower confidence limit around the fitted line
- ymax or xmax
upper confidence limit around the fitted line
If fm.values = TRUE is passed then one column with the number of
observations n used for each fit is also included, with the same
value in each row within a group. This is wasteful and disabled by default,
but provides a simple and robust approach to achieve effects like colouring
or hiding of the model fit line based on the number of observations.
Model fit methods supported
Several model fit functions are
supported explicitly (see tables), and some of their differences smoothed
out. Compatibility is checked late, based on the class of the returned
fitted model object. This makes it possible to use wrapper functions that
do model selection or other adjustments to the fit procedure on a per panel
or per group basis. Moreover, if the value returned as model fit object is
NULL no layer is added to the plot on a per group within panel
basis.
In the case of fitted model objects of classes not explicitly supported an attempt is made to find the usual accessors and/or fitted object members, and if found, either complete or partial support is frequently achieved. In this case a message is issued encouraging users to check the valisdity of the values extracted.
The argument to parameter method can be either the name of a
function object, possibly using double colon notation, or a character
string matching the function name. This approach makes it possible to
support model fit functions that are not dependencies of 'ggpmisc'. Either
by attaching the package where the function is defined and passing it by
name or as string, or using double colon notation when passing the name of
the function. User-defined functions can be passed as argument to parameter
method as long as they have parameters formula, data
subset and possibly weights. Additional arguments can be
passed to any method as a named list as an argument to parameter
method.args. As in stat_smooth()
prior weights are passed to the model fit functions' weights
(plural!) parameter by mapping a numeric variable to plot aesthetic
weight (singular!).
The table below lists natively supported model fit functions, with the caveat that only some 'broom' methods' specializations have been actually tested with statistics from 'ggpmisc'. In addition, the statistics based on 'broom' methods require the user to tailor their behaviour by passing additional arguments in the call.
| Statistic | \(f\) | Supported model fit methods |
stat_poly_line() | G | "lm", "rlm", "lts", "sma", "ma", "gls", others with methods predict() or fitted() |
stat_poly_eq() | G | "lm", "rlm", "lts", "sma", "ma", "gls", others with needed accesors |
stat_quant_line() | G | "rq", "rqss" |
stat_quant_band() | G | "rq", "rqss" |
stat_quant_eq() | G | "rq", "rqss" |
stat_ma_line() | G | "SMA", "MA", "RMA", "OLS" |
stat_ma_eq() | G | "SMA", "MA", "RMA", "OLS" |
stat_fit_residuals() | G | "lm", "rlm", "lts", "sma", "ma", "gls", "rq", "rqss" others with method residuals() |
stat_fit_fitted() | G | "lm", "rlm", "lts", "gls", "rq", "rqss" others with method fitted() |
stat_fit_deviations() | G | "lm", "rlm", "lts", "gls", "rq", "rqss" others with methods fitted() and weights() |
stat_fit_augment() | G | any with 'broom' method augment() |
stat_fit_glance() | G | any with 'broom' method glance() |
stat_fit_tidy() | G | any with 'broom' method tidy() |
stat_fit_tb() | P | any with 'broom' method tidy() |
The table below lists the names for fit methods coded in the statistics
as given in the table above. The single colon notation is based on parsing
the name and is available whenever passing the name of the fit method as a
character string. In a string such as "head:tail" the "head" gives the name
of the model fit function and the "tail" gives the argument to pass it's
method parameter. In some cases the default formula = y ~ x
needs to be overridden with an explicit argument.
| Predefined method names | Model fit methods | R package | Object class |
| "lm", "lm:qr" | lm() | 'stats' | "lm" |
| "rlm", "rlm:M", "rlm:MM" | rlm() | 'MASS' | "rlm" ("lm") |
| "lts", "ltsReg" | ltsReg() | 'robustbase' | "lts" |
| "ma", "sma", "sma:SMA", "sma:MA", "sma:OLS" | sma() | 'smatr' | "ma" or "sma" |
| "gls", "gls:REML", "gls:ML" | gls() | 'nlme' | "gls" |
| "rq", "rq:sfn", "rq:sfnc", "rq:lasso" | rq() | 'quantreg' | "rq" |
| "rqss", "rqss:sfn", "rqss:sfnc", "rqss:lasso" | rqss() | 'quantreg' | "rqss" |
| "SMA", "MA", "RMA", "OLS" | lmodel2() | 'lmodel2' |
References
Cardoso, G. C. (2019) Double quantile regression accurately assesses distance to boundary trade-off. Methods in ecology and evolution, 10(8), 1322-1331.
Aesthetics
stat_quant_line() understands the following aesthetics. Required aesthetics are displayed in bold and defaults are displayed for optional aesthetics:
| • | x | |
| • | y | |
| • | group | → after_stat(group) |
| • | weight | → 1 |
Learn more about setting these aesthetics in vignette("ggplot2-specs").
Examples
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line()
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(quantiles = 0.5)
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(se = TRUE)
# If you need the fitting to be done along the y-axis set the orientation
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(orientation = "y")
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(orientation = "y", se = TRUE)
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(formula = y ~ x)
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(formula = x ~ y)
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(formula = y ~ poly(x, 3))
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(formula = x ~ poly(y, 3))
# Instead of rq() we can use rqss() to fit an additive model:
library(quantreg)
#> Loading required package: SparseM
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(method = "rqss",
formula = y ~ qss(x, constraint = "D"),
quantiles = 0.5, se = FALSE)
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(method = "rqss",
formula = x ~ qss(y, constraint = "D"),
quantiles = 0.5)
ggplot(mpg, aes(displ, hwy)) +
geom_point()+
stat_quant_line(method="rqss",
interval="confidence",
se = TRUE,
mapping = aes(fill = factor(after_stat(quantile)),
color = factor(after_stat(quantile))),
quantiles=c(0.05,0.5,0.95))
# Smooths are automatically fit to each group (defined by categorical
# aesthetics or the group aesthetic) and for each facet.
ggplot(mpg, aes(displ, hwy, colour = drv, fill = drv)) +
geom_point() +
stat_quant_line(method = "rqss",
formula = y ~ qss(x, constraint = "V"),
quantiles = 0.5)
ggplot(mpg, aes(displ, hwy)) +
geom_point() +
stat_quant_line(formula = y ~ poly(x, 2)) +
facet_wrap(~drv)
# Inspecting the returned data using geom_debug_group()
gginnards.installed <- requireNamespace("gginnards", quietly = TRUE)
if (gginnards.installed)
library(gginnards)
if (gginnards.installed)
ggplot(mpg, aes(displ, hwy)) +
stat_quant_line(geom = "debug_group")
#> [1] "PANEL 1; group(s) -1-0.25; 'draw_function()' input 'data' (head):"
#> x y ymin ymax quantile group quantile.f flipped_aes PANEL
#> 1 1.600000 28.42857 NA NA 0.25 -1-0.25 0.25 FALSE 1
#> 2 1.668354 28.16817 NA NA 0.25 -1-0.25 0.25 FALSE 1
#> 3 1.736709 27.90778 NA NA 0.25 -1-0.25 0.25 FALSE 1
#> 4 1.805063 27.64738 NA NA 0.25 -1-0.25 0.25 FALSE 1
#> 5 1.873418 27.38698 NA NA 0.25 -1-0.25 0.25 FALSE 1
#> 6 1.941772 27.12658 NA NA 0.25 -1-0.25 0.25 FALSE 1
#> orientation
#> 1 x
#> 2 x
#> 3 x
#> 4 x
#> 5 x
#> 6 x
#> [1] "PANEL 1; group(s) -1-0.5; 'draw_function()' input 'data' (head):"
#> x y ymin ymax quantile group quantile.f flipped_aes PANEL
#> 81 1.600000 29.85714 NA NA 0.5 -1-0.5 0.50 FALSE 1
#> 82 1.668354 29.61302 NA NA 0.5 -1-0.5 0.50 FALSE 1
#> 83 1.736709 29.36890 NA NA 0.5 -1-0.5 0.50 FALSE 1
#> 84 1.805063 29.12477 NA NA 0.5 -1-0.5 0.50 FALSE 1
#> 85 1.873418 28.88065 NA NA 0.5 -1-0.5 0.50 FALSE 1
#> 86 1.941772 28.63653 NA NA 0.5 -1-0.5 0.50 FALSE 1
#> orientation
#> 81 x
#> 82 x
#> 83 x
#> 84 x
#> 85 x
#> 86 x
#> [1] "PANEL 1; group(s) -1-0.75; 'draw_function()' input 'data' (head):"
#> x y ymin ymax quantile group quantile.f flipped_aes PANEL
#> 161 1.600000 32.00000 NA NA 0.75 -1-0.75 0.75 FALSE 1
#> 162 1.668354 31.76659 NA NA 0.75 -1-0.75 0.75 FALSE 1
#> 163 1.736709 31.53319 NA NA 0.75 -1-0.75 0.75 FALSE 1
#> 164 1.805063 31.29978 NA NA 0.75 -1-0.75 0.75 FALSE 1
#> 165 1.873418 31.06638 NA NA 0.75 -1-0.75 0.75 FALSE 1
#> 166 1.941772 30.83297 NA NA 0.75 -1-0.75 0.75 FALSE 1
#> orientation
#> 161 x
#> 162 x
#> 163 x
#> 164 x
#> 165 x
#> 166 x
if (gginnards.installed)
ggplot(mpg, aes(displ, hwy)) +
stat_quant_line(geom = "debug_group", fm.values = TRUE)
#> [1] "PANEL 1; group(s) -1-0.25; 'draw_function()' input 'data' (head):"
#> x y ymin ymax quantile group n fm.class fm.method
#> 1 1.600000 28.42857 NA NA 0.25 -1-0.25 234 rq rq
#> 2 1.668354 28.16817 NA NA 0.25 -1-0.25 234 rq rq
#> 3 1.736709 27.90778 NA NA 0.25 -1-0.25 234 rq rq
#> 4 1.805063 27.64738 NA NA 0.25 -1-0.25 234 rq rq
#> 5 1.873418 27.38698 NA NA 0.25 -1-0.25 234 rq rq
#> 6 1.941772 27.12658 NA NA 0.25 -1-0.25 234 rq rq
#> fm.formula.chr quantile.f flipped_aes PANEL orientation
#> 1 y ~ x 0.25 FALSE 1 x
#> 2 y ~ x 0.25 FALSE 1 x
#> 3 y ~ x 0.25 FALSE 1 x
#> 4 y ~ x 0.25 FALSE 1 x
#> 5 y ~ x 0.25 FALSE 1 x
#> 6 y ~ x 0.25 FALSE 1 x
#> [1] "PANEL 1; group(s) -1-0.5; 'draw_function()' input 'data' (head):"
#> x y ymin ymax quantile group n fm.class fm.method
#> 81 1.600000 29.85714 NA NA 0.5 -1-0.5 234 rq rq
#> 82 1.668354 29.61302 NA NA 0.5 -1-0.5 234 rq rq
#> 83 1.736709 29.36890 NA NA 0.5 -1-0.5 234 rq rq
#> 84 1.805063 29.12477 NA NA 0.5 -1-0.5 234 rq rq
#> 85 1.873418 28.88065 NA NA 0.5 -1-0.5 234 rq rq
#> 86 1.941772 28.63653 NA NA 0.5 -1-0.5 234 rq rq
#> fm.formula.chr quantile.f flipped_aes PANEL orientation
#> 81 y ~ x 0.50 FALSE 1 x
#> 82 y ~ x 0.50 FALSE 1 x
#> 83 y ~ x 0.50 FALSE 1 x
#> 84 y ~ x 0.50 FALSE 1 x
#> 85 y ~ x 0.50 FALSE 1 x
#> 86 y ~ x 0.50 FALSE 1 x
#> [1] "PANEL 1; group(s) -1-0.75; 'draw_function()' input 'data' (head):"
#> x y ymin ymax quantile group n fm.class fm.method
#> 161 1.600000 32.00000 NA NA 0.75 -1-0.75 234 rq rq
#> 162 1.668354 31.76659 NA NA 0.75 -1-0.75 234 rq rq
#> 163 1.736709 31.53319 NA NA 0.75 -1-0.75 234 rq rq
#> 164 1.805063 31.29978 NA NA 0.75 -1-0.75 234 rq rq
#> 165 1.873418 31.06638 NA NA 0.75 -1-0.75 234 rq rq
#> 166 1.941772 30.83297 NA NA 0.75 -1-0.75 234 rq rq
#> fm.formula.chr quantile.f flipped_aes PANEL orientation
#> 161 y ~ x 0.75 FALSE 1 x
#> 162 y ~ x 0.75 FALSE 1 x
#> 163 y ~ x 0.75 FALSE 1 x
#> 164 y ~ x 0.75 FALSE 1 x
#> 165 y ~ x 0.75 FALSE 1 x
#> 166 y ~ x 0.75 FALSE 1 x
