Vivvi
Vivvi

Reputation: 43

Error message: no non-missing arguments to max; returning -Inf

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

Answers (1)

Allan Cameron
Allan Cameron

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

enter image description here

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")

enter image description here

Upvotes: 6

Related Questions