R语言 向geom_smooth平滑线添加上限/下限

toiithl6  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(229)

我想给geom_line(ggplot2)使用loose方法生成的平滑线加上一个上限。我的数据没有超过1,但平滑线超过了。
我在这方面找到的唯一帖子是2012年的,然而,这个问题并没有得到解决(见以下链接:https://groups.google.com/g/ggplot2/c/Mxsbb4p3V7Y)。
为了方便起见,我重复了提问者最初发布的工作示例。我希望这不会造成太多麻烦。正如同一个人所指出的,平滑后的线会小于0,尽管min(y)= 0.007593811。

library(ggplot2)
y<-rep(0:1,each=20,times=5)+runif(10,0,0.05)
x<-seq(1:length(y))
ggplot()+geom_line(aes(x=x,y=y))+geom_smooth(aes(x=x,y=y),method='loess',span=0.20,se=F)

是否可以为geom_smooth添加一个上限/下限,以便使用黄土方法生成的平滑线的值位于特定范围内(例如,0和1)?谢谢大家。

    • 编辑**

谢谢你们两个伟大的解决方案!

cygmwpex

cygmwpex1#

您的示例包含大于1的值,因此让我们创建一个不大于1的等效数据集:

library(ggplot2)

df <- data.frame(x = 1:200, 
                 y = ifelse(rep(0:1 == 0, each = 20, times = 5), 
                            runif(200)/20, runif(200, 0.95, 1)))

ggplot(df, aes(x, y)) +
  geom_line() +
  geom_smooth(method = 'loess', span = 0.20, se = FALSE) +
  geom_hline(yintercept = c(0, 1), linetype = 2)

虽然我们可以简单地将黄土固定在[0,1]范围内,但一个稍微复杂的方法是执行logit变换,对 that 进行回归,然后反转变换,这会得到一个更平滑的结果:

df$logit_y <- log(df$y/(1 - df$y)) # logit transform
df$pred <- predict(loess(logit_y ~ x, data = df, span = 0.2))
df$pred <- exp(df$pred)/(exp(df$pred) + 1) # Reverse logit

ggplot(df, aes(x, y)) +
  geom_line() +
  geom_line(aes(y = pred), color = "blue", linewidth = 1) +
  geom_hline(yintercept = c(0, 1), linetype = 2)

m4pnthwp

m4pnthwp2#

我认为这可以通过使用delayed evaluation来实现,以便在最后一分钟将平滑值限制在所需的范围内:

ggplot(data.frame(x,y), aes(x=x,y=y))+
  geom_line()+
  geom_smooth(aes(y=stage(y, after_stat = pmax(0,pmin(1, y)))),
              method='loess', span=0.20, se = FALSE)

相关问题