Reputation: 43
I am trying to determine the width at half height of a density plot, and I found the following code in a previous post:
d <- ggplot(A0, aes(DIAMETER)) +
geom_density()
xmax <- d$x[d$y==max(d$y, na.rm = TRUE)]
x1 <- d$x[d$x < xmax][which.min(abs(d$y[d$x < xmax]-max(d$y)/2))]
x2 <- d$x[d$x > xmax][which.min(abs(d$y[d$x > xmax]-max(d$y)/2))]
FWHM <- x2-x1
when I execute it though I get the following error message relative to the function max()
Warning message:
In max(d$y, na.rm = TRUE) : no non-missing arguments to max; returning -Inf
I looked a bit around and saw that this could be due to the presence of NA value in my dataset but that is not the case (structure of data frame below).. does someone know how I could fix this problem ? thanks in advance!
str(A0)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 387 obs. of 3 variables:
$ SAMPLE : Factor w/ 5 levels "A","B","C","D",..: 1 1 1 1 1 1 1 1 1 1 ...
$ TIME : Factor w/ 3 levels "0","24","72": 1 1 1 1 1 1 1 1 1 1 ...
$ DIAMETER: num 13.57 3.76 10.67 14.74 4.2 ...
Upvotes: 1
Views: 5259
Reputation: 173803
I think you're possibly misinterpreting the code you found. A ggplot
object simply doesn't have a member called y
. Suppose we make a density plot like this:
library(ggplot2)
set.seed(69)
d <- ggplot(data = data.frame(x = rnorm(100)), aes(x)) + geom_density()
d
We can replicate your error like this:
xmax <- d$x[d$y==max(d$y, na.rm = TRUE)]
#> Warning message:
#> In max(d$y, na.rm = TRUE) : no non-missing arguments to max; returning -Inf
And if we try to look at d$y
we get:
d$y
#> NULL
If you want to work with the underlying data from a plot you need to use ggbuild
, like this:
p <- ggplot_build(d)
Now p
contains a list of data frames, one for each plot layer, so in our case we can do:
df <- p$data[[1]]
Now df
is a data frame containing our x
and y
coordinates, so we can run your algorithm
xmax <- df$x[df$y==max(df$y, na.rm = TRUE)]
x1 <- df$x[df$x < xmax][which.min(abs(df$y[df$x < xmax]-max(df$y)/2))]
x2 <- df$x[df$x > xmax][which.min(abs(df$y[df$x > xmax]-max(df$y)/2))]
FWHM <- x2-x1
FWHM
#> [1] 2.100466
and we can see this calculation is correct by plotting a segment between the x1 and x2 values at half the maximum height:
d + geom_segment(aes(x = x1, xend = x2, y = max(df$y)/2, yend = max(df$y)/2),
linetype = 2, colour = "red")
Upvotes: 6