如何修复 R 中 ggplot2 的 geom_jitter() 不稳定的 y 位置?

问题描述

我正在用 boxplot 制作一个常见的 R ggplot2 图:boxplots 将单个样本补充为 geom_jitter() 显示的点,以显示每个组中的单个样本位置和数量。通常我没有注意到问题,但是根据最近的一些数据,我注意到抖动的 y 位置存在很大的不准确性和变化。但是,箱线图相对于 Y 保持稳定,geom_point() 在用于显示与抖动绘制相同的点时也是如此。当您有很多数据点时,错误可能并不明显,但是如果需要对一组中的 5-10 个样本进行某些操作,则可能会产生明显的错误,从而绘制出可能误导您的图,如果您不知道该问题的话.

我一开始以为这可能一直发生而我没有注意到,所以我做了一些随机数并用geom_jitter()做了一个ggplot,但一开始问题就消失了。给出了一些示例数据和图表以显示正常和有问题的情况。

按预期工作的数据生成和绘图:

df <- data.frame("X" = rep("X",5),"Y" = rnorm(5,100,30))

检查情节:

library(ggplot2)
ggplot(df,aes(X,Y)) + geom_boxplot() + geom_jitter(col = "red") + geom_point(col = "blue")

红色和蓝色点几乎完全对齐,如果您重复代码 5 次并且没有注意到抖动点 y 位置的变化(仅沿 X 轴水平方向),您可以在 RStudio 预览中观看绘图,正如预期的那样)。在像下面这样的有问题的情况下,您很快就会看到 y 轴的点变化,特别是因为它有时会移动 y 轴的范围。

随着随机数的更多变化,我发现红点和蓝点之间存在明显的差异,每次绘制相同的数据时都会有所不同:

df <- data.frame("X" = rep("X",400))

解决这个问题的实际数字是:

  X          Y
1 X  610.78026
2 X  -38.58905
3 X -196.00943
4 X   94.37797
5 X  415.58417

在我的结果中,最低点 -196,有时约为 -170,有时约为 -250。 y 轴的范围每次都会发生变化。这类似于我在真实数据中遇到的问题。 我发现其他具有更大方差或点之间更大范围的数据测试并不能解释抖动 y 位置的发生变异性。在一些差异更大的情况下, geom_jitter() 再次产生接近完美的 y 位置。所以我想知道它是否可能与 ggplot2 使用的某些绘图区域的映射问题有关。我想通过强制 ggplot 使用 ylim(-206,621) 保持相同的 ylimit 来测试它,但它未能在上述有问题的情况下停止该区域。它给出了一个神秘但一致的错误:“警告消息:删除了包含缺失值的 1 行(geom_point)。” (在相应的绘图中,它丢失了 610.7 值的红色抖动点,尽管绘图预览窗口中有足够的像素空间在蓝色点和图形顶部之间还有大约 10 个点。在另一次尝试中,2 个抖动点得到输了,因为底部有时会超过下限)。

一个迂回的解决方案是为 X 组制作随机点,所有点都保持相同的 Y 和组标识,但效率不高。当在 X 上使用非数字组时,我发现对于添加的任何标签,它的数字位置都是 1。将以下内容添加到最后一个数据帧会给出正确的外观 + geom_point(aes(x= rnorm(5,1,.2),y = Y),col = "yellow") - 但如果有很多组,如果没有某种方法可以自动获取箱线图组的正确 X 位置,这将变得非常麻烦。

要解决问题,任何有关问题原因的输入都会有很大帮助。

解决方法

听起来您不想要默认的 geom_jitter 行为,默认情况下,该行为会在绘图前分别向 x 和 y 值添加均匀分布的噪声量 "40% of the resolution of the data: this means the jitter values will occupy 80% of the implied bins."

对于像你这样的连续变量,“分辨率”是 "the smallest non-zero distance between adjacent values."

试试这个:

geom_jitter(col = "red",height = 0) + 

这会告诉 ggplot 在绘图之前不要对 y 值应用噪声。

另一种方法是在绘图步骤之前自己添加噪声,使您能够具体控制其分布和范围。

例如而不是让抖动填充一个统一的矩形:...

library(dplyr)
tibble(x = rep(1:2,each = 1000),y = rep(3:4,each = 1000)) -> point_data
  ggplot(point_data,aes(x,y)) + geom_jitter()

enter image description here

我们可以添加任何我们想要的噪声函数。在这里,没有特别的原因,我围绕真实数据制作了甜甜圈,并将其与默认抖动进行了比较:

point_data %>%
  mutate(angle = runif(2000,2*pi),dist  = rnorm(2000,0.3,0.05),x2    = x + dist*cos(angle),y2    = y + dist*sin(angle)) %>%
  ggplot() + 
    geom_jitter(aes(x,y),color = "red",alpha = 0.2) +
    geom_point(aes(x2,y2))

enter image description here

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...