2

我正在尝试修改如何在使用R 包stat_regline_equation制作的图上显示回归线方程。具体来说,我想显示一致的系数位数,即使某些舍入系数具有尾随零,这些零通常被删除。这是一个例子:ggscatterggpubr

library(tidyverse)
library(ggpubr)

diamonds %>%
  filter(color %in% c("E", "H", "I")) %>%
  ggscatter(x="carat", y="table", add="reg.line") +
    facet_wrap(~color) +
    stat_regline_equation(label.y.npc = 'top')

在此处输入图像描述

图 I 很好,图 H 删除了一个尾随零,图 E 完全删除了斜率,因为它四舍五入到 1.00。基于我在这里得到的一个很好的答案以及一个不同的答案我尝试修改包代码,trace(ggpubr:::.stat_lm, edit = TRUE)用于修改第 13 和 14 行

eq.char <- as.character(signif(polynom::as.polynomial(coefs), 2))

eq.char <- as.character(formatC(polynom::as.polynomial(coefs), format = "f", digits = 2))

这就是问题所在:如果您将一个polynom::polynomial对象传递给signifor round,它们会返回另一个polynom::polynomial对象,但对于formatCorsprintf它们会返回字符:

coefs = diamonds %>%
  filter(color=='E') %>%
  stats::lm(table~carat, .) %>%
  stats::coef()

coefs %>%
  polynom::as.polynomial() %>%
  formatC(format='f', digits=2) %>%
  class() %>%
  print()

coefs %>%
  polynom::as.polynomial() %>%
  signif(digits = 2) %>%
  class() %>%
  print()

[1] "character"
[1] "polynomial"

因此,我在上面使用的尝试formatC不起作用。我猜这个polynom::polynomial类有内置的roundand方法signif,而没有内置方法formatC,所以后者的输出是强制的。我可能会尝试修改 的类定义polynom::polynomial,但在这个阶段,我觉得必须有一种更简单的方法来在我的图表上显示的回归方程上获得尾随零。我希望这是一个足够普遍的愿望,有人有一个更简单的解决方案,或者至少一个答案可能对我以外的更多人有用。

4

2 回答 2

3

编辑:这个答案只能部分解决问题。它仍然只显示56.83 + 1 x而不是1.00 x. 我留下答案,因为其他人可能可以从中构建。

问题的很大一部分是polynom:::print.polynomial,其中包含:

p <- as.character.polynomial(signif(x, digits = digits), decreasing = decreasing)

这将永远不会打印尾随零,因为as.character.polynomial. 所以,我们可以创建一个as.character.polynomial允许这样做的新的。我只是稍微修改了现有代码作为示例,您可以进一步调整它:

as.character.polynomial <- function (x, decreasing = FALSE, digits = 2, nsmall = 2) {
  p <- format(unclass(x), digits = digits, nsmall = nsmall)
  lp <- length(p) - 1
  names(p) <- 0:lp
  p <- p[as.numeric(p) != 0]
  if (length(p) == 0) 
    return("0")
  if (decreasing) 
    p <- rev(p)
  signs <- ifelse(as.numeric(p) < 0, "- ", "+")
  signs[1] <- if (signs[1] == "- ") "-" else ""
  np <- names(p)
  pow <- paste("x^", np, sep = "")
  pow[np == "0"] <- ""
  pow[np == "1"] <- "x"
  stars <- rep.int("*", length(p))
  stars[p == "" | pow == ""] <- ""
  paste0(signs, p, stars, pow, collapse = " ")
}

例子:

coefs %>%
  polynom::as.polynomial() %>%
  as.character.polynomial
# [1] "56.83 + 1.00*x

但是,.stat_lm然后将其输出为italic(y)~`=`~56.83 + 1.00*~italic(x),因此将用作表达式。我不太熟悉,ggplot2无法弄清楚其余部分,所以我将把它留给其他人。

在此处输入图像描述

于 2021-06-13T11:50:31.083 回答
3

作为一个问题,expression()我们使用包'ggtext'和格式化为降价的方程更接近所需的输出。'ggpmisc' 包遵循图形语法,因此比'ggpubr' 有更多的输入,但它保留了'ggplot2' 的所有灵活性和层的概念。它默认将方程格式化为 R 表达式,但它也可以返回 LaTeX 和 markdown 格式的方程。它signif()在内部使用,因此小数点后的位数可能会有所不同。有效位数可以通过参数控制coef.digits

library(tidyverse)
library(ggpmisc)
library(ggtext)

diamonds %>%
  filter(color %in% c("E", "H", "I")) %>%
  ggplot(aes(x=carat, y=table)) +
  geom_point() +
  stat_poly_line() +
  stat_poly_eq(aes(label = after_stat(eq.label)),
               geom = "rich_text", output.type = "markdown",
               label.y = 72, label.x = 0.5, fill = NA, label.size = NA,
               hjust = 0) +
  facet_wrap(~color) +
  theme_bw()

[2021-06-26] 使用“ggpmisc”的当前开发版本(未来版本 0.4.1),我们得到以下情节:

使用更新的 'ggpmisc' 绘图

这些值根据有效位数而不是小数点后的位数保留尾随零,因为多项式的高阶项的小系数很重要。

注意:stat_poly_eq() 'ggpmisc' 包中的统计数据是原始代码,未经确认就被复制并重命名为stat_regline_equation()'ggpubr'。同时,“ggpmisc”包的开发仍在继续,目前stat_poly_eq()有几个新功能和错误修复。'ggtext' 包进入 CRAN 后不久添加的功能之一是支持 markdown 编码方程,我在上面的示例中使用了它。

reprex 包于 2021-06-20 创建 (v2.0.0 )

于 2021-06-20T09:59:02.107 回答