在多面ggplot上注释不同的方程式

时间:2019-08-14 16:19:12

标签: r ggplot2 expression

我正在尝试结合使用this答案将方程式注释到ggplot图和this答案中,以将不同的文本放到不同的方面。

我遇到的问题是我无法在不同的方面使用数学表达式获得不同的公式。

#Required package
library(ggplot2)

#Split the mtcars dataset by the number of cylinders in each engine
cars.split <- split(mtcars, mtcars$cyl)

#Create a linear model to get the equation for the line for each cylinder
cars.mod <- lapply(cars.split, function(x){
  lm(wt ~ mpg, data = x)
})

#Create predicted data set to add a 'geom_line()' in ggplot2
cars.pred <- as.data.frame(do.call(rbind, 
                                   mapply(x = cars.split, y = cars.mod,
                                          FUN = function(x, y){
                                            newdata <- data.frame(mpg = seq(min(x$mpg),
                                                                            max(x$mpg),
                                                                            length.out = 100))
                                            pred <- data.frame(wt = predict(y, newdata),
                                                               mpg = newdata$mpg)
                                          }, SIMPLIFY = F)))
cars.pred$cyl <- rep(c(4,6,8), each = 100)

(cars.coef <- as.data.frame(do.call(rbind, lapply(cars.mod, function(x)x$coefficients))))

#Create a data frame of line equations a 'cyl' variable to facilitate facetting 
#as per second link. I had to MANUALLY take the values 'cars.coef' and put them
#into the data frame.
equation.text <- data.frame(label = c('y = 4.69-0.09x^{1}',
                                      'y = 6.42-0.17x^{1}',
                                      'y = 6.91-0.19x^{1}'),
                            cyl = c(4,6,8))

#Plot it
ggplot(data = mtcars, mapping = aes(x = mpg, y = wt)) +
  geom_point() +
  geom_line(data = cars.pred, mapping = aes(x = mpg, y = wt)) +
  geom_text(data = equation.text, mapping = aes(x = 20, y = 5, label = label)) +
  facet_wrap(.~ cyl)

enter image description here

图中的方程式与我在equation.text数据框中编写的完全相同,这并不奇怪,因为方程式位于''中。但我正在尝试使其以数学符号表示,例如$ y = 4.69–0.09x ^ 1 $

我知道我需要使用first link中所说的expression,但是当我尝试将其放入数据帧时:

equation.text <- data.frame(label = c(expression(y==4.69-0.9*x^{1}), 
                                      expression(y==6.42-0.17*x^{1}), 
                                      expression(y==6.91-0.19*x^{1})),
                            cyl = c(4,6,8))

我收到一条错误消息,说无法将expression放入数据帧:

Error in as.data.frame.default(x[[i]], optional = TRUE) : 
  cannot coerce class '"expression"' to a data.frame

我的问题是:

  1. 如何在不同方面获得不同的数学符号方程式(斜体字母,上标,下标)?
  2. cars.coef数据框中获取值到equations表中(而不是输入所有数字!)的更自动化的方法是什么?
  3. 更新This已经引起了我的注意,但是很多答案似乎都适用于线性模型。例如,对于非线性模型也有办法做到这一点吗?

1 个答案:

答案 0 :(得分:3)

希望这能满足问题的两个部分。我也不太喜欢把表情放在一起。

对于第一部分,您可以从截距和系数的数据框中创建方程文本的数据框,并根据需要对其进行格式设置。我设置了sprintf来匹配您所拥有的小数位数,并标记系数的符号。

library(ggplot2)

# same preparation as in question
# renamed just to have standard column names
names(cars.coef) <- c("intercept", "mpg")

equation.text <- data.frame(
  cyl = unique(cars.pred$cyl),
  label = sprintf("y == %1.2f %+1.2f*x^{1}", cars.coef$intercept, cars.coef$mpg,
  stringsAsFactors = F)
)

标签列如下:

"y == 4.69 -0.09*x^{1}" "y == 6.42 -0.17*x^{1}" "y == 6.91 -0.19*x^{1}"

对于第二部分,您可以仅在parse = T中设置geom_text,类似于annotate中可用的参数。

ggplot(data = mtcars, mapping = aes(x = mpg, y = wt)) +
  geom_point() +
  geom_line(data = cars.pred, mapping = aes(x = mpg, y = wt)) +
  geom_text(data = equation.text, mapping = aes(x = 20, y = 5, label = label), parse = T) +
  facet_wrap(.~ cyl)

关于sprintf的注释:%标记了格式化开始的位置。我正在使用+作为标志,以包括正负号(以显示正或负系数)。 1.2f表示在小数点前加1位,在小数点后加2;可以根据需要进行调整,但可以显示数字,例如4.69。参数按照传递给sprintf的顺序传递给格式字符串。