Local polynomial regression plot type

Description

Type function for plotting a LOESS (LOcal regrESSion) fit. Arguments are passed to loess.

Usage

type_loess(
  span = 0.75,
  degree = 2,
  family = "gaussian",
  control = loess.control(),
  se = TRUE,
  level = 0.95,
  n = 100,
  weights = NULL
)

Arguments

span the parameter \(\alpha\) which controls the degree of smoothing.
degree the degree of the polynomials to be used, normally 1 or 2. (Degree 0 is also allowed, but see the ‘Note’.)
family a description of the error distribution and link function to be used in the model. For glm this can be a character string naming a family function, a family function or the result of a call to a family function. For glm.fit only the third option is supported. (See family for details of family functions.)
control control parameters: see loess.control.
se logical. If TRUE (the default), confidence intervals are drawn.
level the confidence level required if se = TRUE. Default is 0.95.
n integer. Number of equally-spaced points at which the fitted model is evaluated for drawing, per group. Default is 100. Note that this affects only where the fitted curve is sampled, not the fit itself, which always uses every observation. Larger values trace a wiggly fit more faithfully, at proportionally greater cost; consider raising it if you combine a small span with a large dataset.
weights an optional numeric vector of observation weights for the model fit, of the same length as the number of data points. Weights can also be supplied via the top-level weights argument of tinyplot (which is evaluated with non-standard evaluation in the formula method, and takes precedence if both are given).

Plotting large data

loess can be a time-consuming algorithm. From a plotting perspective, though, the expensive half is usually not the model fit but the prediction step (y values corresponding to each x). type_loess() mitigates this in two ways.

First, the fitted model is evaluated on an equally-spaced grid of n points spanning the data range of each group, rather than at every observation. On large data this skips a great deal of redundant work—dozens of observations can crowd into a single pixel, so evaluating the curve at each of them costs time without revealing anything—while n points remain ample to trace a smooth curve. The model is still fitted on the full dataset, so the estimates are unchanged. It’s only the points along x at which they are read off that differ. (If the x-axis is logarithmic, the grid is spaced evenly in log(x), so that the curve is traced evenly across the plot.)

Second, once prediction is cheap the fit itself becomes the bottleneck, and here lowess is substituted for loess() wherever the two are equivalent: unweighted local linear fits, without standard errors, on a non-logarithmic x-axis. That path smooths millions of observations in seconds. Standard errors, quadratic fits and weighted fits all fall back to loess(), as does a logarithmic x-axis, where lowess() interpolates too coarsely through the compressed decades.

Note that se = TRUE carries a hard ceiling of its own: predict.loess’s workspace grows quadratically in the number of observations—regardless of how many points you predict at—and fails outright at around 38,000. Confidence intervals are thus unavailable at the sizes where the lowess() path matters most, and se = FALSE is required to draw a smooth over very large data.

Examples

library("tinyplot")

# "loess" type convenience string
tinyplot(dist ~ speed, data = cars, type = "loess")

# Use `type_loess()` to pass extra arguments for customization
tinyplot(dist ~ speed, data = cars, type = type_loess(span = 0.5, degree = 1))

# The fast `lowess` path is used automatically where it is equivalent, which
# makes short work of larger datasets
tinyplot(sunspots, type = "l", col = "grey")
tinyplot_add(type = type_loess(span = 0.05, degree = 1, se = FALSE), lwd = 2)

# Raise `n` if a small `span` needs more than 100 points to trace faithfully
tinyplot(sunspots, type = "l", col = "grey")
tinyplot_add(type = type_loess(span = 0.05, degree = 1, se = FALSE, n = 500), lwd = 2)