R: Replacing Axis Labels With Another Variable

Advertisements

I am working with the R programming language.

I have the following dataset:

library(stringi)
library(dplyr)
library(tidyverse)
set.seed(123)
n <- 100
final <- data.frame(id = 1:n,
                    var1 = rnorm(n),
                    var2 = rnorm(n),
                    var3 = rnorm(n))
final$new_id <- stri_rand_strings(n, 6, pattern = "[A-Za-z0-9]")

The dataset looks something like this:

  id        var1        var2       var3 new_id
1  1 -0.56047565 -0.71040656  2.1988103 EgEJAn
2  2 -0.23017749  0.25688371  1.3124130 9pKNd5
3  3  1.55870831 -0.24669188 -0.2651451 1zamtk
4  4  0.07050839 -0.34754260  0.5431941 y2urmN
5  5  0.12928774 -0.95161857 -0.4143399 2MGqMI
6  6  1.71506499 -0.04502772 -0.4762469 lqSj6D

Based on this dataset, I was able to make the following plot:

library(ggplot2)

ggplot(final, aes(x = id)) +
  geom_line(aes(y = var1, color = "var1")) +
  geom_line(aes(y = var2, color = "var2")) +
  geom_line(aes(y = var3, color = "var3")) +
  scale_x_continuous(breaks = seq(0, max(final$id), by = 1)) +
  labs(title = "My Plot",
       x = "id",
       y = "var_value") +
  theme_minimal()

My Question: I am trying to replace the ID label (x-axis) with new_id and have the labels appear vertically instead of horizontally (to avoid clutter and save space). I am also only trying to show a random 10% of all new_id’s on the x-axis to avoid clutter and save space.

I tried to adapt my code:

# randomly sample 10% of new_id values
final_sampled <- final %>% 
  mutate(display_label = ifelse(runif(n) < 0.1, new_id, ""))

ggplot(final, aes(x = new_id)) +
  geom_line(aes(y = var1, color = "var1")) +
  geom_line(aes(y = var2, color = "var2")) +
  geom_line(aes(y = var3, color = "var3")) +
  scale_x_discrete(breaks = final$new_id[sample(nrow(final), round(0.1 * nrow(final)))],
                   labels = function(x) str_wrap(x, width = 10)) +
  labs(title = "My Plot",
       x = "new_id",
       y = "var_value") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

When I run this code I get an empty plot:

And the following warnings:

`geom_line()`: Each group consists of only one observation.
i Do you need to adjust the group aesthetic?
`geom_line()`: Each group consists of only one observation.
i Do you need to adjust the group aesthetic?
`geom_line()`: Each group consists of only one observation.
i Do you need to adjust the group aesthetic?

Can someone please show me how to fix this?

Thanks!

>Solution :

You could use scale_x_continuous and assign the labels you want to display to labels with the breaks. For rotating labels you could also use guides like this:

library(stringi)
library(dplyr)
library(tidyverse)
set.seed(123)
n <- 100
final <- data.frame(id = 1:n,
                    var1 = rnorm(n),
                    var2 = rnorm(n),
                    var3 = rnorm(n))
final$new_id <- stri_rand_strings(n, 6, pattern = "[A-Za-z0-9]")

# randomly sample 10% of new_id values
final_sampled <- final %>% 
  mutate(display_label = ifelse(runif(n) < 0.1, new_id, ""))

library(ggplot2)
ggplot(final, aes(x = id)) +
  geom_line(aes(y = var1, color = "var1")) +
  geom_line(aes(y = var2, color = "var2")) +
  geom_line(aes(y = var3, color = "var3")) +
  scale_x_continuous(labels = final_sampled$display_label, 
                     breaks = seq(1, max(final_sampled$id), by = 1)) +
  guides(x = guide_axis(angle = 90)) +
  labs(title = "My Plot",
       x = "id",
       y = "var_value") +
  theme_minimal()

Created on 2023-04-06 with reprex v2.0.2

Leave a ReplyCancel reply