【问题标题】:How to connect grouped points in ggplot within groups?如何在组内连接ggplot中的分组点?
【发布时间】:2022-06-21 13:22:32
【问题描述】:

我有一个包含两组的数据集 - 实验组和控制组。每个参与者每组贡献两个响应,代表不同的学习方式。这些在下面带有抖动的箱形图中表示。我想使用 ggplot 将每个参与者的两个响应与线连接在一起(因此对照组中的每条红线都对应于对照组中的每条绿松石线),但是我不知道如何在条件下做到这一点。有人可以帮忙吗?我是 R 新手,真的需要指导。

然后,如果增加 = TRUE,我需要将条件内线条的颜色更改为黑色,如果增加 = FALSE,我需要将线条的颜色更改为红色。

理想情况下,我需要它看起来像 Jon 的示例,但带有基于 True 或 False 的黑线或红线:Connecting grouped points with lines in ggplot

数据和ggplot是这样的:

d <- data.frame (
  Subject = c("1", "2", "3", "4"),
  Group  = c("Exp", "Exp", "Control", "Control"),
  Tr = c("14", "11", "4", "23"),
  Sr = c("56", "78", "12", "10"),
  Increase = c("TRUE", "TRUE", "TRUE", "FALSE")
)

# put the data in long format
d <- d %>%
  gather(key = "Strategy", value = "raw", Tr, Sr)

d %>%
  ggplot(aes(x = Group, y = raw, color = Strategy)) +
  geom_boxplot(width = 0.5, lwd = 0.5) +
  geom_jitter(width = 0.15) +
  geom_line(aes(group = raw),
            color = "grey",
            arrow = arrow(type = "closed",
                          length = unit(0.075, "inches"))) 

【问题讨论】:

  • 请以有效的 R 语法将示例数据作为复制/粘贴代码共享,而不是作为表格的屏幕截图。 dput() 是一个很好的命令,dput(data[1:12, ]) 将提供前 12 行数据的复制/粘贴版本,包括所有类和结构信息。
  • 从你的数据图片看,不清楚应该连接哪些点。是否有 ID 列或其他内容来指示哪些点对在一起?
  • 谢谢,格雷戈尔。我刚刚添加了一个复制/粘贴代码 - 这样更好吗?
  • 需要连接的点是每个Exp和Ctr组中每个主题的Tr和Sr。所以对于第一个,Exp组内需要连接的点是14和23
  • 这样就清楚多了。 position_jitterdodge 适用于点和箱线图as per this answer,但对于线条,我认为唯一的选择是手动抖动 - 在数据中添加噪声作为列。我现在没有时间写答案,但今晚晚些时候,如果没有其他人回答,我会试着看看。

标签: r ggplot2 plot


【解决方案1】:

灵感来自您链接到的答案 - @Jon's answer

了解解决方案有几个关键点

  1. 由于您需要连接点和线,因此您需要它们都应用完全相同的随机抖动,或者最好在数据进入绘图之前对其进行抖动,这就是我所做的。
  2. 由于要应用抖动的变量不是数字,因此请注意 R 将字符向量 Group 绘制为因子,解释为数字 1、2、3、.. 对应于因子水平。因此,我们创建了一个数值向量 group_jit,其值在 1 和 2 左右,其偏移量基于着色变量 Strategy,以在 1 和 2 左右略微左右移动。
  3. 由于您有两个独立的色标,因此最好将组表示为fill,将行表示为colour,以避免单个图例上包含 4 个东西。

这是代码 -

library(tidyverse)

# Load data
d <- data.frame (
  Subject = c("1", "2", "3", "4"),
  Group  = c("Exp", "Exp", "Control", "Control"),
  Tr = c("14", "11", "4", "23"),
  Sr = c("56", "78", "12", "10"),
  Increase = c("TRUE", "TRUE", "TRUE", "FALSE")
)

width_jitter <- 0.2 # 1 means full width between points

# put the data in long format
d_jit <- d %>%
  gather(key = "Strategy", value = "raw", Tr, Sr) %>% 
  
  # type conversions
  mutate(across(c(Group, Strategy), as_factor)) %>% # convert to factors
  mutate(raw = as.numeric(raw)) %>% # make raw as numbers
  
  # position on x axis is based on combination of Group and jittered Strategy. Mix to taste.
  mutate(group_jit = as.numeric(Group) + jitter(as.numeric(Strategy) - 1.5) * width_jitter * 2,
         grouping = interaction(Subject, Strategy))

# plotting
d_jit %>%
  ggplot(aes(x = Group, y = raw, fill = Strategy)) +
  geom_boxplot(width = 0.5, lwd = 0.5, alpha = 0.05, show.legend = FALSE) +
  geom_point(aes(x = group_jit), size = 3, shape = 21) +
  
  geom_line(aes(x = group_jit,
                group = Subject,
                colour = Increase),
            alpha = 0.5,
            arrow = arrow(type = "closed",
                          length = unit(0.075, "inches"))
            ) + 
  scale_colour_manual(values = c('red', 'black'))

reprex package (v2.0.1) 于 2022-05-14 创建

为了完整起见,处理抖动的另一种更优雅的方法是为geom_pointgeom_line 命令提供position 参数。这个参数是一个像这样添加随机抖动的函数(来源:@erocoar's answer

position = ggplot2::position_jitterdodge(dodge.width = 0.75, jitter.width = 0.3, seed = 1)

这样数据本身不会改变,并且绘图会处理抖动细节

  • jitterdodge 进行闪避(x 轴变量的偏移)和抖动(彩色点的小噪声)
  • 这里的 seed 参数是关键,因为它确保为独立调用它的点和线函数返回相同的随机

【讨论】:

  • 非常感谢,Prashant!这正是我所需要的!这个例子真的很清楚,解释真的帮助我理解了我需要做什么。非常感谢:)
  • 不客气!如果问题得到了满意的回答,您能否accept点击左上角的复选框,以便将问题标记为已解决,以供将来查找此帖子的人使用,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 2018-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多