Search code examples
rggplot2gghighlight

Error when using gghighlight to highlight one group of data


I have data on in-hospital cardiac arrest that contains month, event location (Unit), number of events in that location for that month (unitCount), and percentages of if the event was witnessed, if epinephrine was given, if defibrillation occurred, if airway was confirmed, and if CPR quality was monitored (quality metrics).

I am trying to create scorecards that highlight each location's quality metrics as compared to the other locations using gghighlight. Here is a minimum dataset and code for plotting:

# Session info
# R version 4.2.2 (2022-10-31 ucrt)
# Platform: x86_64-w64-mingw32/x64 (64-bit)
# Running under: Windows 10 x64 (build 19045)

# Matrix products: default

# locale:
# [1] LC_COLLATE=English_United States.utf8  LC_CTYPE=English_United States.utf8   
# [3] LC_MONETARY=English_United States.utf8 LC_NUMERIC=C                          
# [5] LC_TIME=English_United States.utf8    

# attached base packages:
# [1] stats     graphics  grDevices utils     datasets  methods   base     

# other attached packages:
#  [1] gridExtra_2.3     gghighlight_0.4.0 forcats_1.0.0     stringr_1.5.0    
#  [5] purrr_1.0.1       tidyr_1.3.0       tibble_3.1.8      ggplot2_3.4.1    
#  [9] tidyverse_1.3.2   lubridate_1.9.2   dplyr_1.1.0       readr_2.1.4      

# loaded via a namespace (and not attached):
#  [1] Rcpp_1.0.10         pillar_1.8.1        compiler_4.2.2      cellranger_1.1.0   
#  [5] dbplyr_2.3.1        tools_4.2.2         bit_4.0.5           jsonlite_1.8.4     
#  [9] googledrive_2.0.0   lifecycle_1.0.3     gargle_1.3.0        gtable_0.3.1       
# [13] timechange_0.2.0    pkgconfig_2.0.3     rlang_1.0.6         reprex_2.0.2       
# [17] DBI_1.1.3           cli_3.6.0           rstudioapi_0.14     ggrepel_0.9.3      
# [21] parallel_4.2.2      haven_2.5.1         xml2_1.3.3          withr_2.5.0        
# [25] httr_1.4.5          generics_0.1.3      vctrs_0.5.2         fs_1.6.1           
# [29] hms_1.1.2           bit64_4.0.5         googlesheets4_1.0.1 grid_4.2.2         
# [33] tidyselect_1.2.0    glue_1.6.2          R6_2.5.1            fansi_1.0.4        
# [37] readxl_1.4.2        vroom_1.6.1         farver_2.1.1        modelr_0.1.10      
# [41] tzdb_0.3.0          magrittr_2.0.3      backports_1.4.1     scales_1.2.1       
# [45] ellipsis_0.3.2      rvest_1.0.3         colorspace_2.1-0    labeling_0.4.2     
# [49] utf8_1.2.3          stringi_1.7.12      munsell_0.5.0       broom_1.0.3        
# [53] crayon_1.5.2       

library("readr")
library("lubridate")
library("tidyverse")
library("gghighlight")

df <- structure(list(month = structure(c(18993, 18993, 18993, 18993, 
19024, 19024, 19024, 19052, 19052, 19052, 19083, 19083), class = "Date"), 
    Unit = c("CICU", "MICU", "NSICU", "SICU", "CICU", "MICU", 
    "NSICU", "CICU", "MICU", "SICU", "CICU", "MICU"), unitCount = c(4L, 
    6L, 2L, 2L, 5L, 12L, 1L, 2L, 6L, 3L, 1L, 8L), witness = c(75, 
    83, 100, 50, 60, 67, 100, 100, 100, 100, 100, 100), epi = c(75, 
    83, 100, 100, 80, 83, 100, 100, 100, 100, 0, 88), defib = c(0, 
    100, NaN, NaN, 50, 100, NaN, NaN, NaN, NaN, NaN, NaN), airwayConfirm = c(75, 
    50, 0, 50, 40, 33, 0, 0, 33, 67, 0, 25), CPRQuality = c(25, 
    33, 0, 50, 0, 25, 0, 0, 17, 33, 0, 12)), row.names = c(NA, 
12L), class = "data.frame")

# Function for plotting witnessed, epi, airway confirmation, and CPR quality metrics by unit
plotUnitMetric <- function(y, unitHighlight) {
  ggplot(df, aes(x = month, y, color = Unit)) +
    geom_line(linewidth = 0.5) +
    geom_point(shape = 21, fill = "white", stroke = 1.5, size = 2) +
    gghighlight(Unit == unitHighlight, use_direct_label = FALSE) + 
    scale_x_date(date_breaks = "1 month", date_labels = "%b") +
    labs(x = "Month", y = "Percentage") +
    theme_bw() +
    theme(legend.position = "none")
}

unitWitness <- plotUnitMetric(y = df$witness, "MICU") + 
  labs(title = "Percentage of CPAs that were witnessed by unit and month")

However, the line that calls gghighlight gets the following warning messages when run:

Warning messages:
1: Tried to calculate with group_by(), but the calculation failed.
Falling back to ungrouped filter operation... 
2: Tried to calculate with group_by(), but the calculation failed.
Falling back to ungrouped filter operation... 

And when I try to print, I get the following:

Error in `geom_line()`:
! Problem while computing aesthetics.
ℹ Error occurred in the 3rd layer.
Caused by error in `check_aesthetics()`:
! Aesthetics must be either length 1 or the same as the data (12)
✖ Fix the following mappings: `y`
Run `rlang::last_error()` to see where the error occurred.

Running rlang::last_error() gets the following:

<error/rlang_error>
Error in `geom_line()`:
! Problem while computing aesthetics.
ℹ Error occurred in the 3rd layer.
Caused by error in `check_aesthetics()`:
! Aesthetics must be either length 1 or the same as the data (12)
✖ Fix the following mappings: `y`
---
Backtrace:
  1. base::print(unitWitness)
  2. ggplot2:::print.ggplot(unitWitness)
  4. ggplot2:::ggplot_build.ggplot(x)
  5. ggplot2:::by_layer(...)
 12. ggplot2 (local) f(l = layers[[i]], d = data[[i]])
 13. l$compute_aesthetics(d, plot)
 14. ggplot2 (local) compute_aesthetics(..., self = self)
 15. ggplot2:::check_aesthetics(evaled, n)

I get this error if I take gghighlight out of the function and concatenate it to the line that defines "unitWitness" as well.

I'm not sure where I've gone wrong as I've double checked the syntax several times. I'm hoping to end up with a plot that looks like this:

MICU highlighted plot


Solution

  • Generally ggplot2 & all packages that follow it don't like aesthetic mappings of the form <dataframe>$<variable>, which is what you tried to pass into your function in the form of df$witness.

    Replace ggplot(df, aes(x = month, y, color = Unit)) with ggplot(df, aes(x = month, get(y), color = Unit)) in plotUnitMetric() and call it with

    plotUnitMetric(y = "witness", "MICU")
    

    should get you past that hurdle.

    As for the warning message, I'm not seeing any reason to use dplyr::group_by for anything in your use case anyway. If the warning bothers you, adding use_group_by = FALSE inside gghighlight() will remove it.

    My modified version:

    plotUnitMetric <- function(y, unitHighlight) {
      ggplot(df, aes(x = month, get(y), color = Unit)) +
        geom_line(linewidth = 0.5) +
        geom_point(shape = 21, fill = "white", stroke = 1.5, size = 2) +
        gghighlight(Unit == unitHighlight, use_direct_label = FALSE,
                    use_group_by = FALSE) + 
        scale_x_date(date_breaks = "1 month", date_labels = "%b") +
        labs(x = "Month", y = "Percentage") +
        theme_bw() +
        theme(legend.position = "none")
    }
    
    unitWitness <- plotUnitMetric(y = "witness", "MICU") + 
      labs(title = "Percentage of CPAs that were witnessed by unit and month")
    
    unitWitness
    

    result