在ggplot上添加p值和r值[跟进]

3

这是一个关于问题的后续。当我运行下面给出的代码时,我得到了一个带有两个R2和p值的图,但是p值为0。这可能是由于非常小的p值造成的。我尝试将数字增加到20(这里是signif(..p.value ..,digits = 4)),但没用。我宁愿注明确切的p值或使用星号,例如if (p<0.002) star='**' else if (p>=0.002&p<0.05) star='*' else star=''。此外,我想在图表中列出r值。请看一下,让我知道哪部分需要修改。期待您的回复!

更新

@eipi10提供的添加p值的答案代码有效,但仍然寻求答案关于如何在ggplots中添加相关系数(r)

代码:

library(dplyr) 
library(ggplot2)
library(ggpmisc)

df <- diamonds %>%
  dplyr::filter(cut%in%c("Fair","Ideal")) %>%
  dplyr::filter(clarity%in%c("I1" ,  "SI2" , "SI1" , "VS2" , "VS1",  "VVS2")) %>%
  dplyr::mutate(new_price = ifelse(cut == "Fair", 
                                   price* 0.5, 
                                   price * 1.1))

formula <- y ~ x - 1

p <- ggplot(df, aes(x,y, color=factor(cut))) 
p <- p + stat_smooth(method = "lm", formula = y ~ x-1, size = 1, level=0.95) 
p <- p + geom_point(alpha = 0.3) 
p <- p + stat_poly_eq(aes(label = paste(..rr.label..)),
                      label.x.npc = "right", label.y.npc = 0.15, formula = formula, 
                      parse = TRUE, size = 3) + 
          stat_fit_glance(method = 'lm', method.args = list(formula = formula),
                      geom = 'text', aes(label = paste("P-value = ", 
                      signif(..p.value.., digits = 4), sep = "")),label.x.npc = 'right',
                      label.y.npc = 0.35, size = 3)
print(p)

enter image description here

1个回答

4

这是一个大型数据集,从图表中可以看出拟合几乎完美,这意味着回归的p值将非常小。以下是每个cut级别的回归模型。为了节省空间,仅显示模型摘要的关键部分:

lapply(unique(df$cut), function(g) {
  summary(lm(y ~ x - 1, df %>% filter(cut==g)))
})
cut=="Ideal"
...
Coefficients:
  Estimate Std. Error t value Pr(>|t|)    
x 1.001715   0.000269    3724   <2e-16 ***
...
Residual standard error: 0.2079 on 18291 degrees of freedom
Multiple R-squared:  0.9987,  Adjusted R-squared:  0.9987 
F-statistic: 1.387e+07 on 1 and 18291 DF,  p-value: < 2.2e-16

cut=="Fair"
...
Coefficients:
   Estimate Std. Error t value Pr(>|t|)    
x 0.9895032  0.0004096    2416   <2e-16 ***
...
Residual standard error: 0.1033 on 1583 degrees of freedom
Multiple R-squared:  0.9997,  Adjusted R-squared:  0.9997 
F-statistic: 5.836e+06 on 1 and 1583 DF,  p-value: < 2.2e-16
请注意巨大的F统计量。对于如此大的F统计量,p值基本上为零。
pf(5.836e06, 1, 1583, lower=FALSE)  
[1] 0

任何大于约2,400(给定自由度的情况下)的F统计量都将给出一个小于R可以表示的最小非零数值的p值。

pf(2400, 1, 1583, lower=FALSE)
[1] 1.716433e-319
默认情况下,当 R 进行数字四舍五入时,它不会返回末尾的零(试试 round(1.340000, 5)signif(1.340000,5))。如果需要打印更多的零,可以例如使用 sprintf 格式化输出字符串。以下代码将 p 值格式化为科学计数法。对于十进制数,请将 "%1.4e" 替换为 "%1.4f"。有关格式字符串的更多详细信息,请参见帮助文档:
p <- ggplot(df, aes(x,y, color=cut)) + 
  stat_smooth(method = "lm", formula = y ~ x-1, size = 1, level=0.95) + 
  geom_point(alpha = 0.3) +
  stat_poly_eq(aes(label = paste(..rr.label..)),
               label.x.npc = "right", label.y.npc = 0.15, formula = formula, 
               parse=TRUE, size = 3) + 
  stat_fit_glance(method = 'lm', method.args = list(formula = formula),
                  geom='text', aes(label=paste0("P-value = ", sprintf("%1.4e", ..p.value..))),
                  label.x.npc = 'right',
                  label.y.npc = 0.4, size = 3)

输入图像说明

更新:要添加星号的p值范围,一种选择是使用ifelse语句,并将p值范围作为条件:

p <- ggplot(df, aes(x,y, color=cut)) + 
  stat_smooth(method = "lm", formula = y ~ x-1, size = 1, level=0.95) + 
  geom_point(alpha = 0.3) +
  stat_poly_eq(aes(label = paste(..rr.label..)),
               label.x.npc = "right", label.y.npc = 0.15, formula = formula, 
               parse=TRUE, size = 3) + 
  stat_fit_glance(method = 'lm', method.args = list(formula = formula),
                  geom='text', aes(label=ifelse(..p.value..< 0.001, "p<0.001**", 
                                                ifelse(..p.value..>=0.001 & ..p.value..<0.05, "p<0.05*", "p>0.05"))),
                  label.x.npc = 'right',
                  label.y.npc = 0.4, size = 3)

enter image description here


如果你真的需要,你可以直接在log(10)尺度上得到p值: pf(5.836e06, 1, 1583, lower=FALSE, log.p=TRUE)/log(10) = -2824.782 - Ben Bolker
1
感谢@BenBolker。“如果您确实需要它:”:您的意思是,万一我担心我的p值实际上是1e-2800而不是惊人的更大的1e-315?也许现在是时候链接到这篇文章了。 - eipi10
感谢@eipi10和@BenBolker。我更喜欢使用星号或提及确切的p值。例如,if (p<0.002) star='**' else if (p>=0.002&p<0.05) star='*' else star=''。对于添加相关系数和星号有什么想法吗?Ben,在@eipi10代码中如何/在哪里加入您的log(10)比例代码? - Aby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接