Как исправить нестабильные y-позиции для geom_jitter () для ggplot2 в R?

Я делаю общий график R ggplot2 с помощью boxplot: boxplots дополняет отдельные образцы в виде точек, показанных geom_jitter (), чтобы показать отдельные позиции и числа образцов в каждой группе. Обычно я не замечаю проблем, но с некоторыми недавними данными я заметил существенную неточность и вариацию в позиции y джиттера. Однако блочная диаграмма остается стабильной по отношению к оси Y, как и geom_point (), когда она используется для отображения тех же точек, что и диаграмма джиттера. Ошибка, скорее всего, не заметна, когда у вас много точек данных, но если вам нужно что-то сделать с 5-10 образцами в группе, это может привести к очевидной ошибке, которая создает график, который может ввести вас в заблуждение, если вы не знали о проблеме. .

Сначала я подумал, что это могло происходить всегда, и я не заметил, поэтому я сделал несколько случайных чисел и сделал ggplot с помощью geom_jitter (), но сначала проблема исчезла. Даны некоторые примеры данных и графиков, чтобы показать нормальные и проблемные случаи.

Генерация данных и построение графиков, которые работали, как ожидалось:

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")

Красные и синие точки почти точно выровнены, и вы можете просто посмотреть, как график появится в предварительном просмотре RStudio, если вы повторите код 5 раз и не заметите изменения в позиции y точки дрожания (только по горизонтали вдоль оси X, как и ожидалось). ). В проблемном случае, как показано ниже, вы быстро увидите изменение точки оси Y, особенно потому, что оно иногда смещает диапазон оси Y.

При большем разбросе случайных чисел я обнаружил разницу между красной и синей точками, которая менялась каждый раз при построении одних и тех же данных:

df <- data.frame("X" = rep("X", 5), "Y" = rnorm(5, 100, 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 сохранить тот же ylimit с помощью ylim(-206, 621), но он не смог остановить область с вышеуказанным проблемным случаем. Это дает загадочную, но постоянную ошибку: Предупреждение: удалена 1 строка, содержащая пропущенные значения (geom_point). (На соответствующем графике он потерял красную точку дрожания для значения 610,7, несмотря на то, что в окне предварительного просмотра графика достаточно места в пикселях для еще примерно 10 точек между синей точкой и верхней частью графика. проиграл, потому что дно иногда выходит за нижний предел).

Обходным решением было бы создать случайные точки для группы X, сохраняя все те же Y и идентичность группы, но это неэффективно. Когда на X используются нечисловые группы, я обнаружил, что они будут иметь числовую позицию 1 для любых добавляемых меток. Добавление следующего к последнему фрейму данных дает правильный внешний вид + geom_point(aes(x= rnorm(5, 1, .2), y = Y), col = "yellow") - но это станет довольно громоздким, если есть много групп, если нет какого-либо способа автоматически получить правильное положение X для групп коробчатых диаграмм.

Чтобы решить эту проблему, любое указание на ее причину было бы большим подспорьем.


person jm21    schedule 12.03.2021    source источник


Ответы (1)


Похоже, вам не нужно поведение по умолчанию geom_jitter, которое добавляет равномерно распределенное количество шума отдельно к значениям x и y перед построением графика, по умолчанию 40% разрешения данных: это означает, что значения джиттера будут занимать 80% предполагаемых интервалов.

Для непрерывной переменной, такой как ваша, разрешение - это наименьшее ненулевое расстояние между соседними значениями.

Попробуй это:

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()

введите описание изображения здесь

Мы могли бы добавить любую функцию шума, какую захотим. Здесь без особой причины я делаю пончики вокруг реальных данных и сравниваю это с джиттером по умолчанию:

point_data %>%
  mutate(angle = runif(2000, 0, 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))

введите описание изображения здесь

person Jon Spring    schedule 13.03.2021
comment
Первое решение сработало, и следующий подход к изменению шума также может быть очень полезным, если снова понадобится альтернатива. Интересные пончики. Спасибо за отличный ответ. - person jm21; 13.03.2021