如何在折线图上添加注释以标记离散x值之间y值的百分比变化

时间:2020-07-23 08:04:17

标签: r ggplot2 lm emmeans

我想可视化线性模型的结果,其中因变量值随离散x值的变化而变化。由于我的x值代表连续的几天,因此我想用百分比来注释每天的更改。如何在线条图中做到这一点?

我的数据

我想衡量人们的心情。每天,我都会从1000个不同的人那里收集他们的感受。因此,我得到了每天的平均情绪,并且我想看看它如何从一天到另一天变化。
library(tidyverse)
library(emmeans)

day_1 <- rnorm(1000, mean = 77, sd = 18)
day_2 <- rnorm(1000, mean = 74, sd = 19)
day_3 <- rnorm(1000, mean = 80, sd = 5)
day_4 <- rnorm(1000, mean = 76, sd = 18)


df <- 
  cbind(day_1, day_2, day_3, day_4) %>%
  as.tibble() %>%
  gather(., key = day, value = mood, day_1:day_4) %>%
  mutate_at(vars(day), factor)

> df

## # A tibble: 4,000 x 2
##   day    mood
##    <fct> <dbl>
##  1 day_1  83.9
##  2 day_1  94.9
##  3 day_1 104. 
##  4 day_1  81.0
##  5 day_1  61.4
##  6 day_1  95.1
##  7 day_1  78.6
##  8 day_1 108. 
##  9 day_1  74.7
## 10 day_1  79.7
## # ... with 3,990 more rows

拟合和绘制

fit <-  lm(formula = mood ~ day, data = df)

emmip(fit, ~ day, CIs = TRUE)

plot


  • 鉴于可以使用ggplot函数编辑绘图对象,如何添加天数之间的变化(以百分比为单位),如下图所示?

  • 是否有一种有效的方法来计算更改并将其放在行的每个部分上方?

enter image description here

1 个答案:

答案 0 :(得分:1)

以下方法利用ggplot_build()(包含在ggplot2中)提取用于创建绘图的基础数据,然后使用geom_label()执行注释本身。

准备工作

如前所述,我们可以使用ggplot_build()从您的数据集中提取数据。

p <- emmip(fit, ~ day, CIs = TRUE)  # save your plot as gg object
plotdata <- ggplot_build(p)$data[[1]]

ggplot_build()函数中发生了很多事情,所以我将进行解释。我们要访问结果的data部分,然后执行此操作,您将获得用于创建每个图层的数据集。在图中,您具有3层:CI的点,线和条。原则上,您可以选择其中任何一个,但我选择的是第一个([[1]])。特别是,我们要访问y值。

要计算百分比变化,我使用diff()为我们编写了一个小函数。由于diff()的第一个索引没有返回“ 0”,因此我们必须添加它。然后,我们将该列添加到plotdata

percent_change <- function(x) {
  p_change <- (diff(x)/x[1:length(x)-1])*100
  return(c(0,p_change))  # add back the 0 for the first index
}

plotdata$change <- percent_change(plotdata$y)

绘图

现在我们可以开始剧情了。我们将在标签p上添加标签几何。其中发生了一些事情:

  • 仅使用plotdata的{​​{1}}部分进行过滤。这是因为我们不想标记没有变化的任何点(即第一个点)。

  • 我需要在plotdata$change != 0的正值之前添加“ +”。标签plotdata$change看起来很不错。

  • 颜色可以在此处动态更改。您也可以通过ifelse()对其进行映射,但是我需要创建另一列,因此在这里使用aes()将颜色控制为红色或绿色是很方便的,因为只有两个选项。您必须在ifelse()之外执行此操作,否则将只获得图例和默认的aes()颜色作为标签“红色”和“绿色”的颜色。我在这里做的方式都没有创建图例。

代码和绘图在这里:

ggplot2

enter image description here