0

Context: I'm trying to make an animated line plot where I compare the levels of Resting Blood Pressure (Y variable - The graph says cholesterol, but it should say Resting Blood Pressure) as the Age increases (x variable) in function of the patient having heart disease or not (0 for no heart disease and 1 for heart disease).

The plot has a lot of "spikes," so I'd like to create some classes/breaks to level things out a bit, but I'm not sure how I could do it given that age is a discrete variable. I was trying to add something like scale_x_discrete() and then adding a sequence like seq(10,80,10) but it didn't work. I was also taking a look at using cut with Sturges rules, but once again that's used for continuous variables.

This is the code:

p <- ggplot(
  df,
  aes(Age, RestingBP, group = HeartDisease, color = HeartDisease)
  ) +
  geom_line() +
  scale_color_viridis_d() +
  scale_alpha_manual(values=classes) +
  labs(x = "Age", y = "Cholesterol") +
  theme(legend.position = "top")
p + transition_reveal(Age)

This is the graph:

enter image description here

Thank you in advance!

Some data:

structure(list(Age = c(40L, 49L, 37L, 48L, 54L, 39L, 45L, 54L, 
37L, 48L, 37L, 58L, 39L, 49L, 42L, 54L, 38L, 43L, 60L, 36L, 43L, 
44L, 49L, 44L, 40L, 36L, 53L, 52L, 53L, 51L, 53L, 56L, 54L, 41L, 
43L, 32L, 65L, 41L, 48L, 48L, 54L, 54L, 35L, 52L, 43L, 59L, 37L, 
50L, 36L, 41L), Gr_etario = structure(c(2L, 2L, 1L, 2L, 2L, 1L, 
2L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 1L, 2L, 3L, 1L, 2L, 2L, 
2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 3L, 2L, 
2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 2L), .Label = c("Menos de 40 anos", 
"Entre 40 e 60 anos", "Acima de 60 anos"), class = "factor"), 
    Sex = structure(c(2L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 
    1L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 
    2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 1L, 
    1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("F", 
    "M"), class = "factor"), ChestPainType = structure(c(2L, 
    3L, 2L, 1L, 3L, 3L, 2L, 2L, 1L, 2L, 3L, 2L, 2L, 1L, 3L, 2L, 
    1L, 2L, 1L, 2L, 4L, 2L, 2L, 2L, 3L, 3L, 1L, 2L, 2L, 2L, 3L, 
    3L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 3L, 2L, 3L, 1L, 3L, 
    1L, 2L, 3L, 1L), .Label = c("ASY", "ATA", "NAP", "TA"), class = "factor"), 
    RestingBP = c(140L, 160L, 130L, 138L, 150L, 120L, 130L, 110L, 
    140L, 120L, 130L, 136L, 120L, 140L, 115L, 120L, 110L, 120L, 
    100L, 120L, 100L, 120L, 124L, 150L, 130L, 130L, 124L, 120L, 
    113L, 125L, 145L, 130L, 125L, 130L, 150L, 125L, 140L, 110L, 
    120L, 150L, 150L, 130L, 150L, 140L, 120L, 130L, 120L, 140L, 
    112L, 110L), Cholesterol = c(289, 180, 283, 214, 195, 339, 
    237, 208, 207, 284, 211, 164, 204, 234, 211, 273, 196, 201, 
    248, 267, 223, 184, 201, 288, 215, 209, 260, 284, 468, 188, 
    518, 167, 224, 172, 186, 254, 306, 250, 177, 227, 230, 294, 
    264, 259, 175, 318, 223, 216, 340, 289), FastingBS = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L), .Label = c("0", "1"), class = "factor"), 
    RestingECG = structure(c(2L, 2L, 3L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 3L, 2L, 2L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 2L, 2L, 2L, 3L, 
    3L, 2L, 2L, 3L, 2L, 3L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("LVH", 
    "Normal", "ST"), class = "factor"), MaxHR = c(172L, 156L, 
    98L, 108L, 122L, 170L, 170L, 142L, 130L, 120L, 142L, 99L, 
    145L, 140L, 137L, 150L, 166L, 165L, 125L, 160L, 142L, 142L, 
    164L, 150L, 138L, 178L, 112L, 118L, 127L, 145L, 130L, 114L, 
    122L, 130L, 154L, 155L, 87L, 142L, 148L, 130L, 130L, 100L, 
    168L, 170L, 120L, 120L, 168L, 170L, 184L, 170L), ExerciseAngina = structure(c(1L, 
    1L, 1L, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 
    1L, 1L, 1L, 1L), .Label = c("N", "Y"), class = "factor"), 
    Oldpeak = c(0, 1, 0, 1.5, 0, 0, 0, 0, 1.5, 0, 0, 2, 0, 1, 
    0, 1.5, 0, 0, 1, 3, 0, 1, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 2, 
    2, 0, 0, 1.5, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0), ST_Slope = structure(c(3L, 
    2L, 3L, 2L, 3L, 3L, 3L, 3L, 2L, 3L, 3L, 2L, 3L, 2L, 3L, 2L, 
    2L, 3L, 2L, 2L, 3L, 2L, 3L, 2L, 3L, 3L, 2L, 3L, 3L, 3L, 2L, 
    3L, 2L, 2L, 3L, 3L, 2L, 3L, 3L, 2L, 3L, 2L, 3L, 3L, 2L, 2L, 
    3L, 3L, 2L, 2L), .Label = c("Down", "Flat", "Up"), class = "factor"), 
    HeartDisease = structure(c(1L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 
    2L, 1L, 1L, 2L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 1L, 
    2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 
    1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 2L), .Label = c("0", 
    "1"), class = "factor")), row.names = c(NA, 50L), class = "data.frame")
  • Could you post your data `df` so that we can recreate the graph? Try using something like `dput(df)` and pasting the output. – jpsmith Dec 29 '21 at 19:53
  • @ROO It's not recommended on SO to link to outside sites when providing data. Usually, it's not necessary to share an entire dataset (https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). So, you can edit your question and paste in how much data you think we need to help answer the question using `head` within `dput` (e.g., `dput(head(df, 100))`). Also, in this case, I'd have to sign up for an account to download the data, which most people will not want to do. – AndrewGB Dec 29 '21 at 20:31
  • 1
    @AndrewGillreath-Brown Thank you for the input, Andrew! I've deleted the comment and added the first 50 observations using dput on the OP –  Dec 29 '21 at 20:40
  • Rather than binning age, you might consider smoothing it, changing `geom_line()` to `geom_smooth()`. – Gregor Thomas Dec 29 '21 at 20:57
  • (And I would point out that `ggplot` considers all numbers continuous, including your integer ages. To use a discrete scale you need the class of your x-axis variable to be `character` or `factor` or something like that---which `cut` could help you produce.) – Gregor Thomas Dec 29 '21 at 20:59
  • I'm afraid `geom_smooth()` doesn't work (At least with gganimate it seems) as I keep getting this error `Error in mapply(FUN = f, ..., SIMPLIFY = FALSE) : zero-length inputs cannot be mixed with those of non-zero length` –  Dec 29 '21 at 21:49

0 Answers0