1

I am trying to write a custom function where I want to display an effect size estimate and its confidence intervals in ggplot2 plot subtitle. I am using plotmath to properly display Greek letters and other mathematical symbols.

This is what the two variants of the subtitle I want look like-

To achieve this, I've written a simple function-

# set up
set.seed(123)
library(tidyverse)
library(cowplot)

# creating a fictional dataframe with effect size estimate and its confidence
# intervals
effsize_df <- tibble::tribble(
  ~estimate, ~conf.low, ~conf.high,
  0.25, 0.10, 0.40
)

# function to prepare subtitle
subtitle_maker <- function(effsize_df, effsize.type) {
  if (effsize.type == "p_eta") {
    # preparing the subtitle
    subtitle <-
      # extracting the elements of the statistical object
      base::substitute(
        expr =
          paste(
            eta["p"]^2,
            " = ",
            effsize,
            ", 95% CI",
            " [",
            LL,
            ", ",
            UL,
            "]",
          ),
        env = base::list(
          effsize = effsize_df$estimate[1],
          LL = effsize_df$conf.low[1],
          UL = effsize_df$conf.high[1]
        )
      )
  } else if (effsize.type == "p_omega") {
    # preparing the subtitle
    subtitle <-
      # extracting the elements of the statistical object
      base::substitute(
        expr =
          paste(
            omega["p"]^2,
            " = ",
            effsize,
            ", 95% CI",
            " [",
            LL,
            ", ",
            UL,
            "]",
          ),
        env = base::list(
          effsize = effsize_df$estimate[1],
          LL = effsize_df$conf.low[1],
          UL = effsize_df$conf.high[1]
        )
      )
  }

  # return the subtitle
  return(subtitle)
}

Note that the code for the conditional statements differs only on one line: eta["p"]^2 (if it's "p_eta") or omega["p"]^2 (if it's "p_omega") and the rest of the code is identical. I want to refactor this code to avoid this repetition.

I can't conditionally assign eta["p"]^2 and omega["p"]^2 to a different object in the function body (let's say effsize.text <- eta["p"]^2) because R will complain that the objects eta and omega are not found in the environment.

How can I do this?

---------------------- post-script--------------------------------------

Following is the code used to create the combined plot shown above-

# creating and joining two plots (plot is shown above)
cowplot::plot_grid(
  # plot 1
  ggplot(mtcars, aes(x = wt, y = mpg)) + geom_blank() +
    labs(
      subtitle = subtitle_maker(effsize_df, "p_omega"),
      title = "partial omega"
    ),
  # plot 2
  ggplot(mtcars, aes(x = wt, y = mpg)) + geom_blank() +
    labs(
      subtitle = subtitle_maker(effsize_df, "p_eta"),
      title = "partial eta"
    ),
  labels = c("(a)", "(b)"),
  nrow = 1
)
Indrajeet Patil
  • 4,673
  • 2
  • 20
  • 51

2 Answers2

2

Here's a unicode solution. I use case_when from dplyr to make life easier.

# function to prepare subtitle
subtitle_maker <- function(effsize_df, effsize.type) {
  # preparing the subtitle
  subtitle <-
    # extracting the elements of the statistical object
    base::substitute(
      expr =
        paste(
          effsize_sym["p"]^2,
          " = ",
          effsize,
          ", 95% CI",
          " [",
          LL,
          ", ",
          UL,
          "]",
        ),
      env = base::list(
        effsize = effsize_df$estimate[1],
        LL = effsize_df$conf.low[1],
        UL = effsize_df$conf.high[1],
        effsize_sym = case_when(
          effsize.type == "p_eta" ~ "\U1D702",
          effsize.type == "p_omega" ~ "\U1D714",
          TRUE ~ NA_character_
        )
      )
    )

  # return the subtitle
  return(subtitle)
}

enter image description here

Dan
  • 11,370
  • 4
  • 43
  • 68
  • Thanks. Just a quick question before I accept this answer: Will the unicode solution work across different operating systems? I always work with a `Windows` machine and this works, but I'd prefer if this also works on other OS as my collaborators mostly use `unix` machines. – Indrajeet Patil Dec 03 '18 at 01:13
  • @IndrajeetPatil I think so. I'm running Ubuntu and it works fine. – Dan Dec 03 '18 at 01:16
  • Ah, I thought you were on a Windows machine. Unfortunately, this doesn't work on Windows. This is what you get with your code: https://gist.github.com/IndrajeetPatil/0e0a2df5a19b553f13cbe7eaa6abdf95#gistcomment-2776016 Do you have some other solution in mind that doesn't involve changing character encoding? – Indrajeet Patil Dec 03 '18 at 21:56
1

a combination of quote and bquote can help,

subtitle_maker <- function(d, type){

  et <- if(type == 'a') quote(eta) else if(type == 'b') quote(omega)

  bquote(.(et)['p']^2==.(d$x)~", 95% CI ["*.(d$y)*","*.(d$z)*"]")

}

d <- list(x=1,y=2,z=3)
grid::grid.newpage()
grid::grid.text(subtitle_maker(d,"a"), y=0.3)
grid::grid.text(subtitle_maker(d,"b"), y=0.7)

Note: or substitute instead of bquote, that's just personal preference

subtitle_maker <- function(effsize_df, effsize.type) {

  effsize.text <- if (effsize.type == "p_eta") quote(eta["p"]) else 
    if (effsize.type == "p_omega") quote(omega["p"])

      base::substitute(
        expr =
          paste(effsize.text^2,
            " = ",
            effsize,
            ", 95% CI",
            " [",
            LL,
            ", ",
            UL,
            "]",
          ),
        env = base::list(effsize.text = effsize.text,
          effsize = effsize_df$estimate[1],
          LL = effsize_df$conf.low[1],
          UL = effsize_df$conf.high[1]
        )
      )
}