Skip to content

Commit

Permalink
Create separate vignette for 'old friends': ggmice equivalents for …
Browse files Browse the repository at this point in the history
…the `mice` plotting functions
  • Loading branch information
hanneoberman committed Mar 8, 2022
1 parent ecd8e8b commit b1fb93a
Show file tree
Hide file tree
Showing 13 changed files with 211 additions and 80 deletions.
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ export("%>%")
export(bwplot)
export(densityplot)
export(ggmice)
export(plot_chains)
export(plot_corr)
export(plot_pattern)
export(plot_pred)
export(plot_trace)
export(stripplot)
export(theme_mice)
export(xyplot)
Expand Down
56 changes: 56 additions & 0 deletions R/corr.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#' Plot correlations between (incomplete) variables
#'
#' @param dat A dataset of class `data.frame`, `tibble`, or `matrix`.
#' @param vrb String or vector with variable name(s), default is "all".
#' @param label Logical indicating whether correlation values should be displayed.
#' @param square Logical indicating whether the plot tiles should be squares.
#' @param diagonal Logical indicating whether the correlation of each variable with itself should be displayed.
#' @param rotate Logical indicating whether the variable name labels should be rotated 90 degrees.
#'
#' @return An object of class `ggplot`.
#'
#' @examples
#' plot_corr(mice::nhanes, label = TRUE)
#' @export
plot_corr <- function(dat, vrb = "all", label = FALSE, square = TRUE, diagonal = FALSE, rotate = FALSE) {
if (!is.data.frame(dat) & !is.matrix(dat)) {
stop("Dataset should be a 'data.frame' or 'matrix'.")
}
if (vrb[1] == "all") {
vrb <- names(dat)
}
p <- length(vrb)
corrs <- data.frame(
vrb = rep(vrb, each = p),
prd = vrb,
corr = matrix(round(stats::cov2cor(stats::cov(data.matrix(dat[, vrb]), use = "pairwise.complete.obs")), 2), nrow = p * p, byrow = TRUE)
)
if (!diagonal) {
corrs[corrs$vrb == corrs$prd, "corr"] <- NA
}
gg <- ggplot2::ggplot(corrs, ggplot2::aes(x = .data$prd, y = .data$vrb, label = .data$corr, fill = .data$corr)) +
ggplot2::geom_tile(color = "black") +
ggplot2::scale_x_discrete(limits = vrb, position = "top") +
ggplot2::scale_y_discrete(limits = rev(vrb)) +
ggplot2::scale_fill_gradient2(low = "deepskyblue", mid = "lightyellow", high = "orangered", na.value = "white", limits = c(-1, 1)) +
ggplot2::labs(
x = "Imputation model predictor",
y = "Variable to impute",
fill = "Correlation*",
caption = "*pairwise complete observations"
) +
theme_minimice()
if (label) {
gg <- gg + ggplot2::geom_text(color = "black", show.legend = FALSE)
}
if (square) {
gg <- gg + ggplot2::coord_fixed()
}
if (rotate) {
gg <- gg + ggplot2::theme(axis.text.x.top = ggplot2::element_text(angle = 90))
}
return(gg)
}

# TODO: add plot for missingness indicators predictors
# TODO: maybe add model.matrix argument to correlation plot?
18 changes: 18 additions & 0 deletions R/flux.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# plot_flux <- function(dat) {
# # escape function if dataset is complete
# # if(!any(is.na(dat))){return(plot_a_mouse())}
# # plot in and outflux
# flx <- mice::flux(dat) %>% cbind(variable = rownames(.))
# gg <- flx %>%
# ggplot2::ggplot(ggplot2::aes(x = influx,
# y = outflux,
# label = variable)) +
# ggplot2::geom_abline(intercept = 1,
# slope = -1,
# linetype = "dashed") +
# ggplot2::geom_text(position = ggplot2::position_jitter(width = 0.01, height = 0.01)) +
# ggplot2::lims(x = c(-0.01, 1.01), y = c(-0.01, 1.01)) +
# ggplot2::theme_classic()
# # output
# return(gg)
# }
10 changes: 5 additions & 5 deletions R/ggmice.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ ggmice <- function(data = NULL, mapping = ggplot2::aes()) {
if (is.character(mapping$x) | is.character(mapping$y)) {
stop("The mapping argument requires variable name(s) of type 'quosure', typically created with ggplot2::aes(). To supply a string instead, try using ggplot2::aes_string()")
}
if (any(c("colour", "fill") %in% mapping_args)) {
warning("The aes() arguments 'colour', 'fill' and 'group' have a special use in ggmmice() and will be overwritten. Try using 'shape' or 'linetype' for additional mapping, or use faceting.")
if ("colour" %in% mapping_args) {
warning("The aes() argument 'colour' has a special use in ggmmice() and will be overwritten. Try using 'shape' or 'linetype' for additional mapping, or use faceting.")
}
# extract variable names from mapping object
if (mice::is.mids(data)) {
Expand All @@ -48,7 +48,7 @@ ggmice <- function(data = NULL, mapping = ggplot2::aes()) {
),
.imp = factor(.imp, ordered = TRUE)
)
mice_mapping <- utils::modifyList(mapping, ggplot2::aes(colour = .where, fill = .where))
mice_mapping <- utils::modifyList(mapping, ggplot2::aes(colour = .where)) #, fill = .where
mice_colors <- c("observed" = "#006CC2B3", "imputed" = "#B61A51B3")
} else {
where_xy <- rowSums(is.na(as.matrix(data[, c(vrb_x, vrb_y)]))) > 0L
Expand All @@ -60,13 +60,13 @@ ggmice <- function(data = NULL, mapping = ggplot2::aes()) {
}),
.where = factor(where_xy, levels = c(FALSE, TRUE), labels = c("observed", "missing"), ordered = TRUE)
)
mice_mapping <- utils::modifyList(mapping, ggplot2::aes(colour = .where, fill = .where))
mice_mapping <- utils::modifyList(mapping, ggplot2::aes(colour = .where)) #, fill = .where
mice_colors <- c("observed" = "#006CC2B3", "missing" = "#B61A51B3")
}
# create plot
gg <- ggplot2::ggplot(data = mice_data, mapping = mice_mapping) +
ggplot2::scale_color_manual(values = mice_colors, drop = TRUE, name = "") +
ggplot2::scale_fill_manual(values = mice_colors, drop = TRUE, name = "") +
#ggplot2::scale_fill_manual(values = mice_colors, drop = TRUE, name = "") +
theme_mice()
if (!mice::is.mids(data)) {
gg <- gg +
Expand Down
2 changes: 2 additions & 0 deletions R/pattern.R
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,5 @@ plot_pattern <- function(dat, square = FALSE, rotate = FALSE) {

return(gg)
}


57 changes: 0 additions & 57 deletions R/pred.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,61 +47,4 @@ plot_pred <- function(pred, label = FALSE, square = TRUE, rotate = FALSE) {
return(gg)
}

#' Plot correlations between (incomplete) variables
#'
#' @param dat A dataset of class `data.frame`, `tibble`, or `matrix`.
#' @param vrb String or vector with variable name(s), default is "all".
#' @param label Logical indicating whether correlation values should be displayed.
#' @param square Logical indicating whether the plot tiles should be squares.
#' @param diagonal Logical indicating whether the correlation of each variable with itself should be displayed.
#' @param rotate Logical indicating whether the variable name labels should be rotated 90 degrees.
#'
#' @return An object of class `ggplot`.
#'
#' @examples
#' plot_corr(mice::nhanes, label = TRUE)
#' @export
plot_corr <- function(dat, vrb = "all", label = FALSE, square = TRUE, diagonal = FALSE, rotate = FALSE) {
if (!is.data.frame(dat) & !is.matrix(dat)) {
stop("Dataset should be a 'data.frame' or 'matrix'.")
}
if (vrb[1] == "all") {
vrb <- names(dat)
}
p <- length(vrb)
corrs <- data.frame(
vrb = rep(vrb, each = p),
prd = vrb,
corr = matrix(round(stats::cov2cor(stats::cov(data.matrix(dat[, vrb]), use = "pairwise.complete.obs")), 2), nrow = p * p, byrow = TRUE)
)
if (!diagonal) {
corrs[corrs$vrb == corrs$prd, "corr"] <- NA
}
gg <- ggplot2::ggplot(corrs, ggplot2::aes(x = .data$prd, y = .data$vrb, label = .data$corr, fill = .data$corr)) +
ggplot2::geom_tile(color = "black") +
ggplot2::scale_x_discrete(limits = vrb, position = "top") +
ggplot2::scale_y_discrete(limits = rev(vrb)) +
ggplot2::scale_fill_gradient2(low = "deepskyblue", mid = "lightyellow", high = "orangered", na.value = "white", limits = c(-1, 1)) +
ggplot2::labs(
x = "Imputation model predictor",
y = "Variable to impute",
fill = "Correlation*",
caption = "*pairwise complete observations"
) +
theme_minimice()
if (label) {
gg <- gg + ggplot2::geom_text(color = "black", show.legend = FALSE)
}
if (square) {
gg <- gg + ggplot2::coord_fixed()
}
if (rotate) {
gg <- gg + ggplot2::theme(axis.text.x.top = ggplot2::element_text(angle = 90))
}
return(gg)
}

# TODO: add imputation method to pred plot
# TODO: add plot for missingness indicators predictors
# TODO: maybe add model.matrix argument to correlation plot?
# TODO: add argument to rotate/shorten variable names
2 changes: 2 additions & 0 deletions R/theme.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ theme_minimice <- function() {
panel.grid.minor = ggplot2::element_blank()
)
}

# TODO: make facets in plot_trace() look more pretty
8 changes: 5 additions & 3 deletions R/chains.R → R/trace.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# plot convergence
#' Convergence plot for Multiply Imputed Data Sets
#' Plot the trace lines of the MICE algorithm for convergence evaluation
#'
#' @param imp An object of class `mids`.
#' @param vrb String or vector with variable name(s), default is "all".
Expand All @@ -8,9 +8,9 @@
#'
#' @examples
#' imp <- mice::mice(mice::nhanes, print = FALSE)
#' plot_chains(imp)
#' plot_trace(imp)
#' @export
plot_chains <- function(imp, vrb = "all") {
plot_trace <- function(imp, vrb = "all") {
if (!mice::is.mids(imp)) {
stop("argument 'imp' must be a 'mids' object", call. = FALSE)
}
Expand Down Expand Up @@ -56,3 +56,5 @@ plot_chains <- function(imp, vrb = "all") {
) +
theme_mice()
}

# TODO: make iterations and statistic arguments as well
2 changes: 1 addition & 1 deletion man/plot_corr.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions man/plot_chains.Rd → man/plot_trace.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions tests/testthat/test-mids.R

This file was deleted.

2 changes: 1 addition & 1 deletion vignettes/ggmice.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ The `ggmice` package contains functions to evaluate observed and imputed data.
## Algorithmic convergence

```{r convergence}
plot_chains(imp, "bmi")
plot_trace(imp, "bmi")
```

## Box and whiskers plot
Expand Down
113 changes: 113 additions & 0 deletions vignettes/old_friends.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
title: "old_friends"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{old_friends}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```

```{r setup}
library(ggmice)
imp <- mice::mice(mice::boys, method = "pmm", printFlag = FALSE)
```

How to re-create the plotting functions from `mice` with `ggmice`, in alphabetical order.

# `mice::bwplot()`

Box-and-whisker plot of observed and imputed data.

```{r bwplot}
# original plot
mice::bwplot(imp, bmi ~ .imp)
# ggmice equivalent
ggmice(imp, ggplot2::aes(x = .imp, y = bmi)) +
ggplot2::geom_boxplot() +
ggplot2::labs(x = "Imputation number")
# extended reproduction with ggmice
ggmice(imp, ggplot2::aes(x = .imp, y = bmi)) +
ggplot2::stat_boxplot(geom = 'errorbar', linetype = "dashed") +
ggplot2::geom_boxplot(outlier.colour = "grey", outlier.shape = 1) +
ggplot2::labs(x = "Imputation number")
```

# `mice::densityplot()`

Density plot of observed and imputed data.

```{r densityplot}
# original plot
mice::densityplot(imp, ~bmi)
# ggmice equivalent
ggmice(imp, ggplot2::aes(x = bmi, group = .imp)) +
ggplot2::geom_density()
# extended reproduction with ggmice
ggmice(imp, ggplot2::aes(x = bmi, group = .imp, size = .where)) +
ggplot2::geom_density() +
ggplot2::scale_size_manual(values = c("observed" = 1, "imputed" = 0.5), guide = "none")
```

# `mice::flux()`

[To be added]

# `mice::md.pattern()`

Missing data pattern plot.

```{r md.pattern}
# original plot
mice::md.pattern(imp$data)
# ggmice equivalent
plot_pattern(imp$data)
```

# `mice::plot.mids()`

Plot the trace lines of the MICE algorithm.

```{r plot.mids}
# original plot
plot(imp, bmi ~ .it | .ms)
# ggmice equivalent
plot_trace(imp, "bmi")
```

# `mice::stripplot()`

Stripplot of observed and imputed data.

```{r stripplot}
# original plot
mice::stripplot(imp, bmi ~ .imp)
# ggmice equivalent
ggmice(imp, ggplot2::aes(x = .imp, y = bmi)) +
ggplot2::geom_jitter(width = 0.25) +
ggplot2::labs(x = "Imputation number")
# extended reproduction with ggmice
```

# `mice::xyplot()`

Scatterplot of observed and imputed data.

```{r}
# original plot
mice::xyplot(imp, bmi ~ age)
# ggmice equivalent
ggmice(imp, ggplot2::aes(age, bmi)) +
ggplot2::geom_point()
# extended reproduction with ggmice
ggmice(imp, ggplot2::aes(age, bmi)) +
ggplot2::geom_point(shape = 1)
```

0 comments on commit b1fb93a

Please sign in to comment.