2

I'm trying to find an easy and intuitive way to calculate and display the peaks of a ggplot2::geom_density() object.

This blog explains how to do it in base R, but it is a multistep process.

But it seems much more intuitive to use the stat_peaks() function of the ggpmisc package.

However, when running the code below, I get the error: stat_peaks requires the following missing aesthetics: y

library(tidyverse)
library(ggpmisc)

ggplot(iris, aes(x = Petal.Length)) +
  geom_density() +
  stat_peaks(colour = "red")

When creating a geom_density() you don't need to supply a y aesthetic.

So if indeed stat_peaks is the way to go, is there a work around to this issue? Perhaps there is a better solution to my problem.

axme100
  • 377
  • 5
  • 13

1 Answers1

2

Here is a simple workaround. The idea is to call ggplot_build, let ggplot do the calculations for you and then extract the needed y aesthetic from the resulting object, which is density in your case.

library(ggplot2)
library(ggpmisc)

p <- ggplot(iris, aes(x = Petal.Length)) +
  geom_density()

pb <- ggplot_build(p)
p + stat_peaks(
  data = pb[['data']][[1]], # take a look at this object
  aes(x = x, y = density),
  colour = "red",
  size = 3
)

enter image description here

I'm sure that this approach can be improved by one of the ggplot2 wizards around that can explain why this is not working...

ggplot(iris, aes(x = Petal.Length, y = stat(density))) +
  geom_density() +
  stat_peaks()

error: stat_peaks requires the following missing aesthetics: y

... which was my first guess.

E_net4
  • 27,810
  • 13
  • 101
  • 139
markus
  • 25,843
  • 5
  • 39
  • 58
  • 1
    Not sure why you got the down vote.....Also: What would be the best way to pull the values corresponding to the red dots? – axme100 Dec 18 '18 at 22:32
  • To get the values try `head(sort(pb[['data']][[1]]$density, decreasing = TRUE), 2)`. For more info take a look at: http://ianmadd.github.io/pages/PeakDensityDistribution.html – markus Dec 18 '18 at 22:40