Plots observed responses against their conditional quantiles. An optional inset compares the forest's continuous ranked probability score (CRPS) curve with a predictor-free reference based on the training responses.

# S3 method for class 'rfsrc'
plot.quantreg(x, prbL = .25, prbU = .75,
  m.target = NULL, crps = TRUE, subset = NULL,
  xlab = NULL, ylab = NULL, ...,
  inset.args = list(), crps.null = TRUE, quantreg.tau = NULL)

Arguments

x

A quantile regression object returned by quantreg. Observed responses must be retained in the object. Predictions made without response values cannot be displayed by this diagnostic.

prbL, prbU

Single probabilities in \((0,1)\) specifying the lower and upper conditional quantiles. Require prbL < prbU. The middle probability is 0.5 when it lies strictly between these bounds; otherwise it is their midpoint. Each requested probability is matched to the nearest stored probability by get.quantile(). Include the desired probabilities in the original quantreg() call for exact matching.

m.target

Name of one continuous response to display. The default is the first response with stored quantiles. For multivariate or mixed outcomes, this selects existing results for plotting and does not request new predictions.

crps

Logical. If TRUE, add the standardized, finite-grid CRPS curve returned by get.quantile.crps().

subset

Positive integer row indices, or a logical vector with one nonmissing entry per row of the quantile output. The default uses all rows. Repeated integer indices repeat those observations in the plot and score calculation. Row indices refer to the stored results, after any preprocessing performed during training or prediction.

xlab, ylab

Axis labels for the main quantile panel. Defaults are the selected response name and "Target Quantiles".

...

Named graphical arguments for the main quantile panel, passed to plot.default. In particular, xlim and ylim set its axis limits; main, cex.axis, las, and related options customize its title and axes. Entries pch, col, and cex customize the middle quantile points. The plotted coordinates and initial empty-panel type are controlled internally. These arguments apply whether or not the CRPS inset is displayed.

inset.args

Named list of graphical arguments for the CRPS inset, passed to plot.default. Entries xlim and ylim set the inset limits; col, lty, and lwd control the forest curve. Axis options such as cex.axis, las, and tck also apply to the inset. Use axes = FALSE to suppress both inset axes, or yaxt = "n" to suppress its right-hand axis. The default list() uses the inset's own settings, independently of .... Ignored when crps = FALSE. Must be supplied by its full argument name.

quantreg.tau

Optional numeric vector of levels strictly between zero and one. Adds a lower-right annotation of mean pinball losses at these levels for the selected response and subset, using get.pinball.error(). The default NULL adds no pinball annotation, even when a session reporting option is set. It does not change prbL, prbU, or the CRPS inset. Must be supplied by its full argument name.

crps.null

Logical. If TRUE, add the null reference when crps = TRUE. The reference is drawn as a dashed black curve, with a legend identifying Forest and Null. Set to FALSE to display only the forest curve. Must be supplied by its full argument name.

Details

The main panel places observed response values on the horizontal axis and the requested conditional quantiles on the vertical axis. A point marks the middle quantile, and a vertical segment with endpoint marks spans the lower and upper quantiles. The dashed diagonal is the identity line. Horizontal jitter reduces overplotting; it does not change the response values used for CRPS. Rows with unavailable responses or requested quantiles are omitted from the main panel with a warning.

An explicit quantreg.tau adds pinball losses to the main panel. Each loss is averaged over the requested subset, excluding unavailable responses and quantiles separately at that level. It uses the original response values, not their jittered display positions. These are the same values returned by get.pinball.error(x, tau = quantreg.tau, subset = subset, m.target = m.target) for the selected response. The reporting levels are independent of the lower and upper quantiles shown in the plot. The session option quantreg.tau sets defaults for printing and loss extraction; plotting keeps this annotation off unless levels are supplied explicitly.

The inset shows the average squared CDF error, integrated by the trapezoidal rule from the first response-grid value to each successive grid value and divided by the width of that interval. Its horizontal axis is the response threshold and its right-hand vertical axis is standardized CRPS. Lower values indicate less error over the corresponding integration interval. This is the finite-grid curve computed by get.quantile.crps(), with the same dependence on the reporting grid. The first value is unavailable because its integration interval has zero width. An entirely unavailable curve is omitted with a warning.

The null reference uses the empirical CDF of all finite training responses for the selected outcome, $$F_0(t) = \frac{1}{n_0}\sum_{j=1}^{n_0} I(Y_j^{\mathrm{train}}\leq t),$$ where \(n_0\) is the number of finite training responses. Repeated response values retain their frequencies. This same predictor-free CDF is used for every evaluated observation. Training responses are read from x$forest$yvar, or from x$yvar for a grow object without saved training responses in its forest. Test responses are used only for evaluation, not to construct the reference. Distinct reporting-grid values are not a replacement for the training sample.

Both curves use the same response grid, subset, integration rule, and standardization. At each threshold, both scores exclude the same rows with an unavailable observed response or forest CDF prediction. The reference distribution itself is not restricted by subset. In training plots, the full-training empirical reference includes the evaluated training response; it is an in-sample benchmark, not an OOB or leave-one-out null estimate. If training responses are unavailable, the null curve is omitted with a warning.

Graphical arguments in ... control the main panel. Customize the inset separately with inset.args, for example, inset.args = list(ylim = c(0, 0.3), lwd = 1.5). Default inset limits cover both curves. Limits supplied inside inset.args change the displayed inset window only; they do not recompute or truncate either score integral. Main-panel limits also leave both score calculations unchanged. Inset graphics settings are restored before returning so additional drawing refers to the main panel, and successive calls can be used in a multi-panel layout.

Value

Used for its graphical side effect. Invisibly returns NULL.

Author

Hemant Ishwaran and Udaya B. Kogalur

Examples

# \donttest{
## Univariate quantiles, with forest and null CRPS curves.
library(randomForestSRC)
set.seed(19)
dta <- na.omit(airquality)
prob <- c(.25, .50, .75)
q <- quantreg(Temp ~ ., data = dta, prob = prob, ntree = 100)
plot.quantreg(q)

## Add pinball losses for this plot only; the interval and inset are unchanged.
plot.quantreg(q, quantreg.tau = c(.2, .5, .8))
print(get.pinball.error(q, tau = c(.2, .5, .8)))

## Customize the main panel directly, and the inset separately.
plot.quantreg(q, main = "Temperature",
              xlim = c(50, 100), ylim = c(45, 110), pch = 19,
              inset.args = list(xlim = c(60, 95), ylim = c(0, .35),
                                lwd = 1.5))

## Keep the inset, but suppress its null reference.
plot.quantreg(q, crps.null = FALSE)

## Multivariate forest: select each response for plotting only.
mv <- quantreg(cbind(Ozone, Temp) ~ ., data = dta,
               splitrule = "mahalanobis", prob = prob, ntree = 100)
print(names(get.quantile(mv, pretty = FALSE)))
op <- par(mfrow = c(1, 2))
plot.quantreg(mv, m.target = "Ozone")
plot.quantreg(mv, m.target = "Temp", main = "Temperature",
              xlim = c(50, 100), ylim = c(45, 110),
              inset.args = list(ylim = c(0, .35)))
par(op)
# }