我试图确定密度图的半高处的宽度,我在上一篇文章中找到了以下代码:
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
Run Code Online (Sandbox Code Playgroud)
当我执行它时,虽然我收到以下与函数 max() 相关的错误消息
Warning message:
In max(d$y, na.rm = TRUE) : no non-missing arguments to max; returning -Inf
Run Code Online (Sandbox Code Playgroud)
我环顾四周,发现这可能是由于我的数据集中存在 NA 值,但事实并非如此(下面的数据框结构)..有人知道我如何解决这个问题吗?提前致谢!
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 ...
Run Code Online (Sandbox Code Playgroud)
我认为您可能误解了您找到的代码。一个ggplot
对象根本没有一个叫做成员y
。假设我们制作这样的密度图:
library(ggplot2)
set.seed(69)
d <- ggplot(data = data.frame(x = rnorm(100)), aes(x)) + geom_density()
d
Run Code Online (Sandbox Code Playgroud)
我们可以像这样复制您的错误:
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
Run Code Online (Sandbox Code Playgroud)
如果我们尝试查看,d$y
我们会得到:
d$y
#> NULL
Run Code Online (Sandbox Code Playgroud)
如果您想使用绘图中的基础数据,则需要使用ggbuild
,如下所示:
p <- ggplot_build(d)
Run Code Online (Sandbox Code Playgroud)
现在p
包含一个数据框列表,每个绘图层一个,所以在我们的例子中我们可以这样做:
df <- p$data[[1]]
Run Code Online (Sandbox Code Playgroud)
现在df
是一个包含我们x
和y
坐标的数据框,因此我们可以运行您的算法
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
Run Code Online (Sandbox Code Playgroud)
通过在最大高度的一半处绘制 x1 和 x2 值之间的线段,我们可以看到这个计算是正确的:
d + geom_segment(aes(x = x1, xend = x2, y = max(df$y)/2, yend = max(df$y)/2),
linetype = 2, colour = "red")
Run Code Online (Sandbox Code Playgroud)