Skip to content

Commit

Permalink
version 0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Finnesgard authored and cran-robot committed Jan 26, 2021
1 parent d7ddf20 commit e24d87d
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 300 deletions.
10 changes: 5 additions & 5 deletions DESCRIPTION
@@ -1,8 +1,8 @@
Package: utile.visuals
Title: Create Visuals for Publication
Version: 0.2.5
Version: 0.3.0
Authors@R: c(person('Eric', 'Finnesgard', email = 'efinite@outlook.com', role = c('aut', 'cre')))
Description: A small set of functions for making visuals for publication in ggplot2. Includes minimalist themes with transparent backgrounds and a suite of tools for building Kaplan-Meier curves with risk tables.
Description: A small set of functions to aid in the production of visuals in ggplot2. Includes minimalist themes with transparent backgrounds and a suite of tools for building survival curves with risk tables.
License: LGPL (>= 2)
URL: https://github.com/efinite/utile.visuals
BugReports: https://github.com/efinite/utile.visuals/issues
Expand All @@ -11,10 +11,10 @@ LazyData: TRUE
Depends: R (>= 3.4.0)
Imports: dplyr, ggplot2, gridExtra, purrr
Suggests: survival, broom, grid
RoxygenNote: 7.1.0
RoxygenNote: 7.1.1
NeedsCompilation: no
Packaged: 2020-05-01 15:45:20 UTC; M130239
Packaged: 2021-01-19 22:02:31 UTC; Eric
Author: Eric Finnesgard [aut, cre]
Maintainer: Eric Finnesgard <efinite@outlook.com>
Repository: CRAN
Date/Publication: 2020-05-01 22:40:02 UTC
Date/Publication: 2021-01-26 23:10:02 UTC
20 changes: 9 additions & 11 deletions MD5
@@ -1,17 +1,15 @@
ddf9f2f6cb731509b25cbc70d1f1b339 *DESCRIPTION
41f88c1f58d0008d2930873366f4af4c *NAMESPACE
e8aed63dae9a28b7ff645b59bee82a9a *NEWS.md
002bae586ab7354b4fad0cf739378e0c *DESCRIPTION
f942bf723d0e40fff5ba6225eeefbe2a *NAMESPACE
93a7b696e7310a6ffd978c3eef3ae4ba *NEWS.md
4eddc50505f36b1c8cbf6fe203866867 *R/append.R
c5bbfd5bb1f0377cda8115144998aeba *R/connect.R
bc578ba07f7803417795c6c55f5eea55 *R/geoms.R
9ed414d267ff239827200fb1a6b806ad *R/gg.R
059a97d7239e11e83ab34da3deab11ae *R/geoms.R
35e0741e647dd1d856b15ba8736581c4 *R/gg.R
6b951278a1ee8efed59689986122cc36 *R/themes.R
d026624c4569dfeddd8a4ac2efd5a8eb *R/utils.R
7dd762c53265331aeea4d09f2e2fcea0 *README.md
e1532517ffe8c9691192ea13a6b6937f *R/utils.R
2377d075fcf3d6801937fc209298795a *README.md
0dbb7a1722de9fb2405278ab4ca0476a *man/append_table.Rd
787c0f7b4620d171dfaee5772d6a763a *man/connect_origin.Rd
89e70c2960eab427fd92abb6d849e477 *man/geom_stepconfint.Rd
6ba6f68b624774b3b5a66b5c79d9b157 *man/ggrisktable.Rd
092d7a1c02c677f2a15a8891111b1c10 *man/geom_stepconfint.Rd
739c3dd0a89c0a7d46570ff0f66f41f1 *man/ggrisktable.Rd
3d10b82cb6b472297136f76b39c05286 *man/theme_black.Rd
de491a1f2f860f7ae03ba4ba19983e04 *man/theme_risk_black.Rd
30baa7ecde76f22b7d829d261402c4fc *man/theme_risk_white.Rd
Expand Down
1 change: 0 additions & 1 deletion NAMESPACE
@@ -1,7 +1,6 @@
# Generated by roxygen2: do not edit by hand

export(append_table)
export(connect_origin)
export(geom_stepconfint)
export(ggrisktable)
export(theme_black)
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
@@ -1,3 +1,6 @@
# utile.visuals 0.3.0
* `connect_origin()` was removed as it redundantly replicated the function of `survival::survfit0()`. Thanks for the tip, Beth!

# utile.visuals 0.2.4
* `connect_origin()` now verifies whether a strata column is present.

Expand Down
34 changes: 0 additions & 34 deletions R/connect.R

This file was deleted.

145 changes: 73 additions & 72 deletions R/geoms.R
@@ -1,72 +1,73 @@
#' @title Step function confidence intervals for ggplot2
#' @description Produces a step function confidence interval for survival curves. Essentially
#' the geom_step() for confidence intervals which ggplot2 elects not to provide.
#' @param mapping Aesthetic mappings with aes() function. Like geom_ribbon(), you must provide
#' columns for x, ymin (lower limit), ymax (upper limit).
#' @param data The data to be displayed in this layer. Can inherit from ggplot parent.
#' @param stat The statistical transformation to use on the data for this layer, as a string.
#' Defaults to 'identity'.
#' @param position Position adjustment, either as a string, or the result of a call to a
#' position adjustment function.
#' @param na.rm If FALSE, the default, missing values are removed with a warning. If TRUE,
#' missing values are silently removed.
#' @param ... Optional. All the other miscellaneous ggplot geom_ribbon() arguments.
#' @note Adapted from the survminer package <https://github.com/kassambara/survminer>.
#' @examples
#' library(survival)
#' library(broom)
#' library(ggplot2)
#'
#' fit <- survfit(Surv(time, status) ~ trt, data = diabetic)
#'
#' ggplot(
#' data = tidy(fit),
#' mapping = aes(x = time, y = estimate)
#' ) +
#' geom_step(aes(color = strata)) +
#' geom_stepconfint(aes(ymin = conf.low, ymax = conf.high, fill = strata), alpha = 0.3) +
#' coord_cartesian(c(0, 50)) +
#' scale_x_continuous(expand = c(0.02,0)) +
#' labs(x = 'Time', y = 'Freedom From Event') +
#' scale_color_manual(
#' values = c('#d83641', '#1A45A7'),
#' name = 'Treatment',
#' labels = c('None', 'Laser'),
#' aesthetics = c('colour', 'fill')) +
#' theme_black()
#' @export
geom_stepconfint <- function (
mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE, ...
) {
ggplot2::layer(
mapping = mapping,
data = data,
stat = stat,
geom = ggplot2::ggproto(
`_class` = 'GeomConfint',
`_inherit` = ggplot2::GeomRibbon,
required_aes = c("x", "ymin", "ymax"),
draw_group = function (self, data, panel_scales, coord, na.rm = FALSE) {
if (na.rm) data <- data[stats::complete.cases(self$required_aes), ]
data <- data[order(data$group, data$x), ]
data <- self$stairstep_confint(data)
ggplot2::GeomRibbon$draw_group(data, panel_scales, coord, na.rm = FALSE)
},
stairstep_confint = function (data) {
data <- as.data.frame(data)[order(data$x), ]
n <- nrow(data)
ys <- rep(1:n, each = 2)[-2 * n]
xs <- c(1, rep(2:n, each = 2))
data.frame(
x = data$x[xs],
ymin = data$ymin[ys],
ymax = data$ymax[ys],
data[xs, setdiff(names(data), c("x", "ymin", "ymax"))]
)
}
),
position = position,
params = list(na.rm = na.rm, ...)
)
}
#' @title Step function confidence intervals for ggplot2
#' @description Produces a step function confidence interval for survival curves. Essentially
#' the geom_step() for confidence intervals which ggplot2 does not provide.
#' @param mapping Aesthetic mappings with aes() function. Like geom_ribbon(), you must provide
#' columns for x, ymin (lower limit), ymax (upper limit).
#' @param data The data to be displayed in this layer. Can inherit from ggplot parent.
#' @param stat The statistical transformation to use on the data for this layer, as a string.
#' Defaults to 'identity'.
#' @param position Position adjustment, either as a string, or the result of a call to a
#' position adjustment function.
#' @param na.rm If FALSE, the default, missing values are removed with a warning. If TRUE,
#' missing values are silently removed.
#' @param ... Optional. Any other ggplot geom_ribbon() arguments.
#' @note Adapted from the survminer package <https://github.com/kassambara/survminer>.
#' @examples
#' library(survival)
#' library(broom)
#' library(ggplot2)
#'
#' fit <- survfit(Surv(time, status) ~ trt, data = diabetic)
#' fit <- survfit0(fit) # connect origin
#'
#' ggplot(
#' data = tidy(fit),
#' mapping = aes(x = time, y = estimate)
#' ) +
#' geom_step(aes(color = strata)) +
#' geom_stepconfint(aes(ymin = conf.low, ymax = conf.high, fill = strata), alpha = 0.3) +
#' coord_cartesian(c(0, 50)) +
#' scale_x_continuous(expand = c(0.02,0)) +
#' labs(x = 'Time', y = 'Freedom From Event') +
#' scale_color_manual(
#' values = c('#d83641', '#1A45A7'),
#' name = 'Treatment',
#' labels = c('None', 'Laser'),
#' aesthetics = c('colour', 'fill')) +
#' theme_black()
#' @export
geom_stepconfint <- function (
mapping = NULL, data = NULL, stat = "identity",
position = "identity", na.rm = FALSE, ...
) {
ggplot2::layer(
mapping = mapping,
data = data,
stat = stat,
geom = ggplot2::ggproto(
`_class` = 'GeomConfint',
`_inherit` = ggplot2::GeomRibbon,
required_aes = c("x", "ymin", "ymax"),
draw_group = function (self, data, panel_scales, coord, na.rm = FALSE) {
if (na.rm) data <- data[stats::complete.cases(self$required_aes), ]
data <- data[order(data$group, data$x), ]
data <- self$stairstep_confint(data)
ggplot2::GeomRibbon$draw_group(data, panel_scales, coord, na.rm = FALSE)
},
stairstep_confint = function (data) {
data <- as.data.frame(data)[order(data$x), ]
n <- nrow(data)
ys <- rep(1:n, each = 2)[-2 * n]
xs <- c(1, rep(2:n, each = 2))
data.frame(
x = data$x[xs],
ymin = data$ymin[ys],
ymax = data$ymax[ys],
data[xs, setdiff(names(data), c("x", "ymin", "ymax"))]
)
}
),
position = position,
params = list(na.rm = na.rm, ...)
)
}
102 changes: 51 additions & 51 deletions R/gg.R
@@ -1,51 +1,51 @@
utils::globalVariables(c('time', 'strata', 'n.risk'))

#' @title Create a ggplot2 table showing the number at risk
#' @description A simple wrapper function which calculates the
#' numbers at risk for a survival model and a given set of time points then
#' creates a ggplot2 table with them.
#' @param fit Required. survival::survfit() object.
#' @param times Required. Numeric. One or more time points to calculate
#' the number at risk for.
#' @param text.color Optional. Character. Color of text within table. Defaults
#' to 'black'.
#' @param strata.order Optional. Character. Ordered names of strata factor
#' levels.
#' @return An unformatted ggplot2 table showing the number at risk.
#' @examples
#' library(survival)
#'
#' fit <- survfit(Surv(time, status) ~ trt, data = diabetic)
#'
#' ggrisktable(
#' fit = fit,
#' times = c(0, 10, 20, 30, 40, 50),
#' strata.order = c('0', '1')
#' ) + theme_risk_black()
#' @export
ggrisktable <- function (fit = NULL, times = NULL, text.color = 'black', strata.order = NULL) {

# Hard stops
if (is.null(fit) | class(fit) != 'survfit') stop('No valid fit object provided. [Check: \'fit\']')
if (is.null(times) | !is.numeric(times)) stop('No valid time points provided. [Check: \'times\']')
if (!is.null(strata.order) & !is.character(strata.order)) stop('Invalid strata order data provided. [Check: \'strata.order\']')

# Generate risk table and order
risk_table <- .tabulate_at_risk(fit, times)

# Reorder strata
if (is.character(strata.order))
risk_table$strata <- factor(
risk_table$strata,
levels = unique(c(
rev(strata.order[strata.order %in% levels(risk_table$strata)]),
levels(risk_table$strata)
))
)

# Return plotted table
ggplot2::ggplot(
risk_table,
ggplot2::aes(x = time, y = strata, label = n.risk)
) + ggplot2::geom_text(color = text.color)
}
utils::globalVariables(c('time', 'strata', 'n.risk'))

#' @title Create a ggplot2 table showing the number at risk
#' @description A simple wrapper function which calculates the
#' numbers at risk for a survival model and a given set of time points then
#' creates a ggplot2 table with them.
#' @param fit Required. survival::survfit() object.
#' @param times Required. Numeric. One or more time points to calculate
#' the number at risk for.
#' @param text.color Optional. Character. Color of text within table. Defaults
#' to 'black'.
#' @param strata.order Optional. Character. Ordered names of strata factor
#' levels.
#' @return An unformatted ggplot2 table showing the number at risk.
#' @examples
#' library(survival)
#'
#' fit <- survfit(Surv(time, status) ~ trt, data = diabetic)
#'
#' ggrisktable(
#' fit = fit,
#' times = c(0, 10, 20, 30, 40, 50),
#' strata.order = c('0', '1')
#' ) + theme_risk_black()
#' @export
ggrisktable <- function (fit = NULL, times = NULL, text.color = 'black', strata.order = NULL) {

# Hard stops
if (is.null(fit) | class(fit) != 'survfit') stop('No valid fit object provided. [Check: \'fit\']')
if (is.null(times) | !is.numeric(times)) stop('No valid time points provided. [Check: \'times\']')
if (!is.null(strata.order) & !is.character(strata.order)) stop('Invalid strata order data provided. [Check: \'strata.order\']')

# Generate risk table and order
risk_table <- .tabulate_at_risk(fit, times)

# Reorder strata
if (is.character(strata.order))
risk_table$strata <- factor(
risk_table$strata,
levels = unique(c(
rev(strata.order[strata.order %in% levels(risk_table$strata)]),
levels(risk_table$strata)
))
)

# Return plotted table
ggplot2::ggplot(
risk_table,
ggplot2::aes(x = time, y = strata, label = n.risk)
) + ggplot2::geom_text(color = text.color)
}
30 changes: 15 additions & 15 deletions R/utils.R
@@ -1,15 +1,15 @@
.tabulate_at_risk <- function(fit = NULL, times = NULL) {
fit_summary <- summary(fit, times = times)
dplyr::bind_cols(
strata = as.factor(
if (is.null(fit$strata)) rep('All', length(times))
else
purrr::map_chr(
as.character(fit_summary$strata),
~ strsplit(.x, '=')[[1]][2]
)
),
time = fit_summary$time,
n.risk = fit_summary$n.risk,
)
}
.tabulate_at_risk <- function(fit = NULL, times = NULL) {
fit_summary <- summary(fit, times = times)
dplyr::bind_cols(
strata = as.factor(
if (is.null(fit$strata)) rep('All', length(times))
else
purrr::map_chr(
as.character(fit_summary$strata),
~ strsplit(.x, '=')[[1]][2]
)
),
time = fit_summary$time,
n.risk = fit_summary$n.risk
)
}

0 comments on commit e24d87d

Please sign in to comment.