【问题标题】:Draw geom_smooth only for fits that are significant仅为重要的拟合绘制 geom_smooth
【发布时间】:2015-06-11 22:45:17
【问题描述】:

如何制作 ggplot plot geom_smooth(method="lm"),但前提是它符合某些标准?例如,如果我只想在斜率具有统计意义的情况下画线(即,lm 拟合中的 p 小于 0.01)。

编辑:更新为涉及方面的更复杂的示例。我没有从头开始生成数据,而是修改了diamonds 数据集。

library(ggplot2)
library(data.table)

data(diamonds)

set.seed(777)
d <- data.table(diamonds)
d[color %in% c("D","E"), c("x","y") := list(x + runif(1000, -5, 5),
                                            y + runif(1000, -5, 5))] 
plt <- ggplot(d) + aes(x=x, y=y, color=color) + 
    geom_point() + facet_grid(clarity ~ cut, scales="free")
plt + geom_smooth(method="lm")

我想要的是一种绘制所有线的方法,除了那些没有统计显着斜率的线(即 D 和 E)。

【问题讨论】:

  • 在 ggplot 之外生成斜率和 CI 可能更容易
  • 或者至少适合模型并确定 ggplot 之外的重要性。然后您可以将数据的子集传递给geom_smooth

标签: r ggplot2 statistics


【解决方案1】:

您可以按组计算 p 值,然后在 geom_smooth 中进行子集计算(根据评论者):

# Determine p-values of regression
p.vals = sapply(unique(d$z), function(i) {
  coef(summary(lm(y ~ x, data=d[z==i, ])))[2,4]
})

plt <- ggplot(d) + aes(x=x, y=y, color=z) + geom_point() 

# Select only values of z for which regression p-value is < 0.05   
plt + geom_smooth(data=d[d$z %in% names(p.vals)[p.vals < 0.05],], 
                         aes(x, y, colour=z), method='lm')

更新:根据您的评论,试试这个,例如:

p1 = ggplot(mtcars, aes(wt, mpg)) +
  geom_point() + facet_grid(am ~ carb)

dat = data.frame(x=1:5, y=26:30, carb=1:5)

p1 + geom_point(data=dat, aes(x,y), colour="red", size=5)

请注意,由于dat 没有am 列,ggplot 只是在dat 中为am 的每个值绘制相同的值。当然,您可以为am 添加值,并逐面控制绘制的内容。

更新 2: 我认为这将处理分面情况。但是请注意,大多数回归的 p 值都小于 0.05,这可能是因为当您拥有大量数据时,即使是很小的系数也会具有统计显着性。

## Create a list holing the p-values for regressions on each 
## combination of color, cut, and clarity
pvals = lapply(levels(d$color), function(i) {
  lapply(levels(d$cut), function(j) {
    lapply(levels(d$clarity), function(k) {
      if(nrow(d[color==i & cut==j & clarity==k, ]) > 1) {
        data.frame(color=i, cut=j, clarity=k, 
                   p.val=coef(summary(lm(y ~ x, data = d[color==i & cut==j & clarity==k, ])))[2,4])
      }
    })
  })
})

# Flatten pvals to a single list level
pvals = unlist(unlist(pvals, recursive=FALSE), recursive=FALSE)

# Turn pvals into a data frame
pvals = do.call(rbind, pvals)

# Keep only rows with p.val < 0.05
pvals = pvals[pvals$p.val < 0.05, ]

plt <- ggplot(d) + aes(x=x, y=y, color=color) + 
  geom_point() + facet_grid(clarity ~ cut, scales="free")

# Create a subset of data frame d containing only combinations of 
# color, cut, and clarity for which we want to plot regression lines
# (you could subset right in the call to geom_smooth, but I thought this would be more clear)
d.subset = d[color %in% pvals$color & 
               cut %in% pvals$cut & 
               clarity %in% pvals$clarity, ]

# Plot regression lines only for groups in d.subset
plt + geom_smooth(data=d.subset, method="lm")

【讨论】:

  • 很公平,但是如果我涉及到方面怎么办?事实上,引发这个问题的原因是,这个情节中发生的事情实际上是在构面网格的每个构面内发生的。
  • 然后您可以创建一个数据框,其中包含 zp.vals 列以及另一列包含 facet 变量的列,并将其提供给 geom_smooth 并使用适当的子集。然后ggplot 将知道在每个方面绘制哪些回归线。如果您在问题中发布了一个可重现的示例,我会对其进行破解。
  • 那么假设名称相同,ggplot 可以跨不同数据结构匹配美学?如果是这样,那真是太好了!
  • 我已将我原来的问题修改为一个更复杂的带有方面的示例。我很好奇你想出了什么。提前致谢!
猜你喜欢
  • 1970-01-01
  • 2016-09-16
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 1970-01-01
相关资源
最近更新 更多