3

I have a problem with combining unicode shapes with legal ggplot2 shapes in geom_point. I have a variable including three event types and I want to plot a dagger for the level Death. Unfortunately, when I define level death as dagger in unicode and the other events as legal shapes from ggplot2, R throws the error message: "Error: All unnamed arguments must be length 1". This error does not occur, when I replace the unicode by a legal shape.
Here is some sample data:

library(tidyverse)

set.seed(123)
id <- 1:10
event <-  sample(c("X", "Y", "Death"), 10, replace = TRUE)
time_to_event <- sample(70:90, 10, replace = TRUE)

data <- data.frame(id, event, time_to_event)

I have a dataset including an ID, event, and the time to event. The plot code is the following:

colors <- c("X" = "dodgerblue3", 
            "Y" = "red2",
            "Death" = "black") # Defining the colors for the event type

event_symbols <- c("X" = 19,
                   "Y" = 19, 
                   "Death" = 84) # <-- Problem: When I use the shape 84 (T) the code is plotted. When I use "/u2020", I get the above-mentioned error message

five_day_lines <- seq(0, 90, 5)
day_lines <- 1:90
day_lines <- day_lines[!day_lines %in% five_day_lines]

data$id <- factor(data$id, levels = data$id[order(data$time_to_event, decreasing = T)])

ggplot(data = data) +
  
  geom_hline(yintercept = c(seq(0, 90, 5)), color = "grey", alpha = .35) +
  geom_hline(yintercept = day_lines, color = "grey", alpha = .25) +
  
  geom_point(aes(x = id, y = time_to_event, shape = event, color = event), size = 3) +
  
  scale_y_continuous(limits = c(0,90), breaks = c(seq(0, 90, 5)), name = "Days after study inclusion") + 
  scale_x_discrete(name = "ID") +
  coord_flip() +
  scale_color_manual(values = colors, breaks = c()) +
  scale_shape_manual(values = event_symbols, breaks = c("X", "Y", "Death"),
                     guide = guide_legend(override.aes = list(color = c("dodgerblue3", "red2", "black")))) +
  theme(legend.position = "bottom", 
        legend.title = element_text(size=12, face="bold"),
        panel.background = element_blank(),
        legend.background = element_blank()) +
  labs(color="Medication", shape="Event type")

I also tried to define all shapes as unicode shapes. Then, the error message did not occur, but the other unicode shapes were not correctly displayed. To be honest, it would be nice to have the legal circles from ggplot2 (19) and the dagger from unicode ("/u2020"). I searched a lot in the web but couldn't find a suitable answer.

I would be grateful, when somebody has an idea how to deal with it.

Thanks Florian

fbeese
  • 118
  • 8

1 Answers1

2

Unfortunately I'm afraid that this couldn't be achieved. From the docs:

Shapes take five types of values:

  • An integer in [0,25]
  • The name of the shape
  • A single character, to use that character as a plotting symbol.

Hence it looks as if it is not possible to mix the types. Instead I would suggest to use unicode symbols for the other shapes too, e.g. "\u25CF" for a circle

library(tidyverse)

set.seed(123)
id <- 1:10
event <-  sample(c("X", "Y", "Death"), 10, replace = TRUE)
time_to_event <- sample(70:90, 10, replace = TRUE)

data <- data.frame(id, event, time_to_event)

  colors <- c("X" = "dodgerblue3", 
              "Y" = "red2",
              "Death" = "black") # Defining the colors for the event type

event_symbols <- c("X" = "\u25CF",
                   "Y" =  "\u25CF", 
                   "Death" = "\u2020") # <-- Problem: When I use the shape 84 (T) the code is plotted. When I use "/u2020", I get the above-mentioned error message

five_day_lines <- seq(0, 90, 5)
day_lines <- 1:90
day_lines <- day_lines[!day_lines %in% five_day_lines]

data$id <- factor(data$id, levels = data$id[order(data$time_to_event, decreasing = T)])

ggplot(data = data) +
  
  geom_hline(yintercept = c(seq(0, 90, 5)), color = "grey", alpha = .35) +
  geom_hline(yintercept = day_lines, color = "grey", alpha = .25) +
  
  geom_point(aes(x = id, y = time_to_event, shape = event, color = event), size = 3) +
  
  scale_y_continuous(limits = c(0,90), breaks = c(seq(0, 90, 5)), name = "Days after study inclusion") + 
  scale_x_discrete(name = "ID") +
  coord_flip() +
  scale_color_manual(values = colors, breaks = c()) +
  scale_shape_manual(values = event_symbols, breaks = c("X", "Y", "Death"),
                     guide = guide_legend(override.aes = list(color = c("dodgerblue3", "red2", "black")))) +
  theme(legend.position = "bottom", 
        legend.title = element_text(size=12, face="bold"),
        panel.background = element_blank(),
        legend.background = element_blank()) +
  labs(color="Medication", shape="Event type")

Created on 2021-06-06 by the reprex package (v2.0.0)

stefan
  • 90,330
  • 6
  • 25
  • 51
  • 1
    Hey Stefan, this is all I need. I wasn't aware that it is possible to change the color of the unicode shapes as well, so I tried to implement the large red circle and the large blue circle, but this threw the same error message. Your solution is very straightforward. Thanks for your help and the quick response! – fbeese Jun 06 '21 at 19:10