| cifpanel | R Documentation |
cifpanel() is the panel-building counterpart of cifplot().
It takes one or more model formulas (or, alternatively, one formula and several
event-coding specifications) and returns a multi-panel figure, typically as a
patchwork-compatible object. Most display options (axis labels, marks, style, ggsave options)
are shared with cifplot(), but per-panel legends and number-at-risk tables are
suppressed to avoid duplicated display. Typical use cases are:
Compare CIF (event 1) vs CIF (event 2) in a 1×2 layout.
Compare survival/CIF curves across strata with a shared legend and matched axes.
Display a plot with an enlarged y-axis inside a full-scale plot.
cifpanel(
plots = NULL,
formula = NULL,
formulas = NULL,
data = NULL,
weights = NULL,
subset.condition = NULL,
na.action = na.omit,
outcome.type = NULL,
code.event1 = 1,
code.event2 = 2,
code.censoring = 0,
code.events = NULL,
error = NULL,
conf.type = NULL,
conf.int = NULL,
n.risk.type = c("weighted", "unweighted", "ess"),
type.y = NULL,
label.x = NULL,
label.y = NULL,
label.strata = NULL,
order.strata = NULL,
level.strata = NULL,
limits.x = NULL,
limits.y = NULL,
breaks.x = NULL,
breaks.y = NULL,
add.conf = NULL,
add.risktable = NULL,
add.estimate.table = NULL,
symbol.risk.table = NULL,
font.size.risk.table = NULL,
add.censor.mark = NULL,
shape.censor.mark = NULL,
size.censor.mark = NULL,
add.competing.risk.mark = NULL,
competing.risk.time = NULL,
shape.competing.risk.mark = NULL,
size.competing.risk.mark = NULL,
add.intercurrent.event.mark = NULL,
intercurrent.event.time = NULL,
shape.intercurrent.event.mark = NULL,
size.intercurrent.event.mark = NULL,
add.quantile = NULL,
level.quantile = NULL,
rows.columns.panel = c(1, 1),
inset.panel = FALSE,
title.panel = NULL,
subtitle.panel = NULL,
caption.panel = NULL,
tag.panel = NULL,
title.plot = NULL,
style = "classic",
palette = NULL,
linewidth = 0.8,
linetype = FALSE,
font.family = "sans",
font.size = 8,
legend.position = "top",
legend.collect = TRUE,
inset.left = 0.6,
inset.bottom = 0.05,
inset.right = 0.98,
inset.top = 0.45,
inset.align.to = c("panel", "plot", "full"),
inset.legend.position = NULL,
print.panel = FALSE,
filename.ggsave = NULL,
width.ggsave = NULL,
height.ggsave = NULL,
dpi.ggsave = 300,
survfit.info = NULL,
axis.info = NULL,
visual.info = NULL,
panel.info = NULL,
style.info = NULL,
inset.info = NULL,
print.info = NULL,
ggsave.info = NULL,
engine = "cifplot",
...
)
plots |
Optional list of existing ggplot objects to be arranged into a panel. When plots is supplied, no new models are fitted; the plots are used as-is. |
formula |
A model formula specifying the time-to-event outcome on the
left-hand side (typically |
formulas |
Optional list of formulas. When given, each formula defines one panel. This is the most common way to create “one variable per plot” panels. |
data |
A data frame containing variables in the formula. |
weights |
Optional name of the weight variable in |
subset.condition |
Optional character string giving a logical condition to subset
|
na.action |
A function specifying the action to take on missing values (default |
outcome.type |
Character string specifying the type of time-to-event outcome.
One of |
code.event1 |
Integer code of the event of interest (default |
code.event2 |
Integer code of the competing risk (default |
code.censoring |
Integer code of censoring (default |
code.events |
Optional specification of event/censoring codes.
For single-panel calls, supply a numeric vector. For competing-risk outcomes, use |
error |
Character string specifying the method for SEs and CIs used internally.
For |
conf.type |
Character specifying the method of transformation for CIs
used internally (default |
conf.int |
Numeric two-sided level of CIs (default |
n.risk.type |
Character string; one of |
type.y |
Character string specifying the y-scale. For survival/CIF curves,
|
label.x |
Character x-axis label (default |
label.y |
Character y-axis label (default is chosen automatically from |
label.strata |
Character vector or named character vector specifying labels for strata.
Names (if present) must match the (re-ordered) underlying strata levels.
Note: when any of the panel modes is active
( |
order.strata |
Optional character vector specifying the display order of strata in the legend/number-at-risk table. Specify the levels of strata. Levels not listed are dropped. |
level.strata |
Optional character vector giving the full set of expected strata levels.
When provided, both |
limits.x |
Numeric length-2 vector specifying x-axis limits. If |
limits.y |
Numeric length-2 vector specifying y-axis limits. If |
breaks.x |
Numeric vector of x-axis breaks (default |
breaks.y |
Numeric vector of y-axis breaks (default |
add.conf |
Logical; if |
add.risktable |
Logical; if |
add.estimate.table |
Logical; if |
symbol.risk.table |
Character specifying the symbol used in the risk table to denote
strata: |
font.size.risk.table |
Numeric font size for texts in risk / estimate tables (default |
add.censor.mark |
Logical; if |
shape.censor.mark |
Integer point shape used for censoring marks (default |
size.censor.mark |
Numeric point size used for censoring marks (default |
add.competing.risk.mark |
Logical; if |
competing.risk.time |
A named list of numeric vectors. Each name must correspond to a
strata label, and its numeric vector gives the times at which the competing event occurred
in that stratum. Typically left as |
shape.competing.risk.mark |
Integer point shape for competing-risk marks (default |
size.competing.risk.mark |
Numeric point size for competing-risk marks (default |
add.intercurrent.event.mark |
Logical; if |
intercurrent.event.time |
A named list of numeric vectors for intercurrent events (names must match strata labels). |
shape.intercurrent.event.mark |
Integer point shape for intercurrent-event marks
(default |
size.intercurrent.event.mark |
Numeric point size for intercurrent-event marks
(default |
add.quantile |
Logical; if |
level.quantile |
Numeric quantile level to be shown (default |
rows.columns.panel |
Optional integer vector |
inset.panel |
Logical. If |
title.panel, subtitle.panel, caption.panel |
Character annotations applied to the
whole panel layout (not to individual plots). These are passed to
|
tag.panel |
Passed to |
title.plot |
Character vector of titles for each panel in the order they are drawn. Length-1 values are recycled to all panels. In inset mode, the first element refers to the main plot and the second (if present) to the inset. |
style |
Character choosing the base plot style: |
palette |
Optional character vector specifying the color palette to use across strata. |
linewidth |
Optional numeric specifying the line width of curve (default |
linetype |
Optional logical using different line types of curve (default |
font.family |
Character specifying the font family: |
font.size |
Integer specifying the base font size (default |
legend.position |
Character specifying the legend position:
|
legend.collect |
Logical; if |
inset.left, inset.bottom, inset.right, inset.top |
Numeric values in the range
|
inset.align.to |
Character string specifying the coordinate system for the
inset box. One of |
inset.legend.position |
Optional legend position for the inset plot only.
If |
print.panel |
Logical. When |
filename.ggsave |
Character; if non- |
width.ggsave |
Numeric width passed to |
height.ggsave |
Numeric height passed to |
dpi.ggsave |
Numeric DPI passed to |
survfit.info, axis.info, visual.info, panel.info, style.info, print.info, ggsave.info, inset.info |
Internal lists used for programmatic control. Not intended for direct user input. |
engine |
Character string specifying the internal rendering engine used to build each panel.
Currently intended for internal use; default is |
... |
Additional arguments forwarded to the internal |
cifpanel() composes multiple survival/CIF plots into a single figure.
For each panel, it estimates curves via cifcurve() and renders them with
cifplot(). You can supply a single formula reused across panels or a
list in formulas (one per panel). When both are provided, formulas wins.
Use outcome.type to set per-panel estimator ("survival"=KM, "competing-risk"=AJ).
Alternatively, pass code.events per panel to infer the type:
length 2 = survival: c(event1, censor)
length 3 = competing-risk: c(event1, event2, censor)
If code.events is NULL, code.event1, code.event2, code.censoring
are combined into code.events = list(c(code.event1, code.event2, code.censoring))
with NA values dropped.
If outcome.type is NULL, the function infers each panel from its
code.events[[i]] length. When both are given, outcome.type takes precedence.
Control risk-set displays via n.risk.type, which is recycled per panel and
forwarded to cifcurve() to decide which risk set size populates $n.risk
(e.g., weighted vs. unweighted counts).
Panel layout is specified by length-2 vector rows.columns.panel.
This function can also automatically determine the panel count in the following order:
(1) if plots is supplied, its length defines the number of plots,
(2) else if formulas is supplied, its length defines the number of plots,
(3) else if code.events is supplied, its length defines the number of plots
together with formula, and (4) otherwise rows.columns.panel=c(1,1).
Many arguments accept a scalar (recycled to all panels) or a list/vector (one entry per panel). Precedence: panel-wise explicit values > shared scalar > internal defaults. Length-1 inputs are recycled.
Grid mode (inset.panel = FALSE, default): plots are arranged with
patchwork::wrap_plots() and plot_layout(). If legend.collect = TRUE,
legends are collected across panels where possible.
Inset mode (inset.panel = TRUE): the second plot is overlaid
into the first using patchwork::inset_element(). Only the first two
plots are used; extra plots are ignored. Control the inset box with
inset.left, inset.bottom, inset.right, inset.top, and its
reference frame via inset.align.to ("panel", "plot", or "full").
cifplot())The following arguments allow per-panel control by supplying vectors/lists,
or shared control by supplying scalars. They are forwarded to cifplot().
formula or formulas: one formula or a list of formulas; each entry creates a panel.
data, outcome.type, code.events, type.y: recycled across panels unless a list is supplied for per-panel control.
rows.columns.panel: specification of grid layout by c(rows, cols).
inset.panel: inset layout.
title.panel, subtitle.panel, caption.panel, title.plot: overall titles and captions.
tag.panel: panel tag style (e.g., "A", "a", "1").
label.x, label.y, limits.x, limits.y, breaks.x, breaks.y: shared axis control unless a list is supplied for per-panel control.
| Argument | Meaning | Default |
type.y | "risk" (CIF y-axis) or NULL (survival). | inferred |
label.x, label.y | Axis labels per panel. | auto |
label.strata | Legend labels per panel. | from data |
limits.x, limits.y | Axis limits c(min, max). | auto |
breaks.x, breaks.y | Axis breaks (forwarded to breaks.x/breaks.y). | auto |
| Argument | Effect | Default |
add.conf | CI ribbon. | TRUE |
add.censor.mark | Censor marks. | TRUE |
add.competing.risk.mark | Marks for event2 at supplied times. | FALSE |
add.intercurrent.event.mark | User-specified intercurrent marks. | FALSE |
add.quantile | Quantile reference line(s). | FALSE |
(Time marks inputs such as competing.risk.time / intercurrent.event.time
can be given via ... if needed; names must match strata labels.)
legend.position: "top", "right", "bottom", "left", or "none" (applies to all panels).
Grid mode: legend.collect = TRUE attempts a shared legend.
Panel annotations: title.panel, subtitle.panel, caption.panel.
Tagging: tag.panel is passed to patchwork::plot_annotation().
In inset mode, title.plot = c(title_base, title_inset) labels the two plots.
If filename.ggsave is non-NULL, the composed panel is saved with
ggsave() using width.ggsave, height.ggsave, and dpi.ggsave.
Otherwise, the function returns objects without saving.
Notes
Mixed panel types are supported (e.g., AJ in panel 1; KM in panel 2).
If formulas is shorter than the grid capacity, empty slots are ignored.
When supplying vectors/lists per panel, their lengths must match the number of panels; length-1 inputs are recycled; otherwise an error is thrown.
For CIF displays, set type.y = "risk". For survival scale, use type.y = NULL or = "surv".
For ADaM-style data, use code.events=c(0,1) or
code.event1 = 0, code.censoring = 1.
Additional graphical options (e.g., theme) can be added post-hoc to each
element of list.plot or to the composed patchwork.
A "cifpanel" object (returned invisibly), which is a list
with at least the following elements:
list.plot: a list of ggplot objects, one per panel
patchwork: a patchwork object representing the composed panel
plot: reserved for backwards compatibility (always NULL)
metadata fields mirroring those in cifplot() (such as information
on the fitted curves and display settings)
When print.panel = TRUE, the patchwork object is printed in interactive
sessions in addition to being returned.
experimental
polyreg() for log-odds product modeling of CIFs; cifcurve() for KM/AJ estimators; cifplot() for display of a CIF; ggsurvfit::ggsurvfit, patchwork::patchwork and modelsummary::modelsummary for display helpers.
data(diabetes.complications)
output1 <- cifpanel(
title.panel = "A comparison of cumulative incidence of competing events",
rows.columns.panel = c(1,2),
formula = Event(t, epsilon) ~ fruitq,
data = diabetes.complications,
outcome.type = "competing-risk",
code.events = list(c(1,2,0), c(2,1,0)),
label.y = c("Diabetic retinopathy", "Macrovascular complications"),
label.x = "Years from registration",
subtitle.panel = "Stratified by fruit intake",
caption.panel = "Data: diabetes.complications",
title.plot = c("Diabetic retinopathy", "Macrovascular complications"),
legend.position = "bottom",
legend.collect=TRUE
)
print(output1)
output2 <- cifplot(Event(t,epsilon) ~ fruitq,
data = diabetes.complications,
outcome.type="competing-risk",
code.event1=2,
code.event2=1,
add.conf = FALSE,
add.risktable = FALSE,
label.y="CIF of macrovascular complications",
label.x="Years from registration")
output3 <- cifplot(Event(t,epsilon) ~ fruitq,
data = diabetes.complications,
outcome.type="competing-risk",
code.event1=2,
code.event2=1,
add.conf = FALSE,
add.risktable = FALSE,
label.y="",
label.x="",
limits.y=c(0,0.15))
output4 <- list(a = output2$plot, b = output3$plot)
output5 <- cifpanel(plots = output4,
inset.panel = TRUE,
inset.left = 0.40, inset.bottom = 0.45,
inset.right = 1.00, inset.top = 0.95,
inset.align.to = "plot",
inset.legend.position = "none",
legend.position = "bottom")
print(output5)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.