Как сгенерировать тот же график с джиттером и как дрожать выбранные точки (не все точки)?

Что бы я хотел сделать:

a) должен ли график, созданный кодом ggplot, быть одинаковым каждый раз, когда он запускается [тип понятия set.seed?] и

б) текстовые метки дрожат только для меток с одинаковым значением оси Y - оставьте остальные текстовые метки в покое. Казалось бы, это своего рода условное дрожание, основанное на значении коэффициента для точек.

Вот некоторые данные:

dput(df)
structure(list(Firm = c("a verylongname", "b verylongname", "c verylongname", 
"d verylongname", "e verylongname", "f verylongname", "g verylongname", 
"h verylongname", "i verylongname", "j verylongname"), Sum = c(74, 
77, 79, 82, 85, 85, 88, 90, 90, 92)), .Names = c("Firm", "Sum"
), row.names = c(NA, 10L), class = "data.frame")

Вот ggplot код с использованием df:

ggplot(df, aes(x = reorder(Firm, Sum, mean), y = Sum)) +
  geom_text(aes(label = Firm), size = 3, show.guides = FALSE, position = position_jitter(height = .9)) +
  theme(axis.text.x = element_blank()) +
  scale_x_discrete(expand = c(-1.1, 0)) +   # to show the lower left name fully
  labs(x = "", y = "", title = "")

Обратите внимание, что одна версия графика все еще перекрывает h и i - каждый раз, когда я запускаю приведенный выше код, расположение текстовых меток меняется.

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

Кстати, этот вопрос условный джиттер сдвигает дискретные значения на оси x немного, но я хотел бы сместить точки перекрытия (только) на оси y.


person lawyeR    schedule 11.09.2015    source источник
comment
Если ваша основная цель - избежать дублирования, вам может понравиться этот вопрос stackoverflow.com/questions/30178954/, и это в stats.SE: stats.stackexchange.com/questions/ 16057 /   -  person maj    schedule 11.09.2015


Ответы (1)


Один из вариантов - добавить столбец, чтобы отметить точки перекрытия, а затем построить их отдельно. Лучшим вариантом может быть прямое смещение значений y перекрывающихся точек, чтобы мы получили прямой контроль над их размещением. Я показываю оба варианта ниже.

Вариант 1 (дрожание). Сначала добавьте столбец, чтобы отмечать перекрытия. В этом случае, поскольку точки в значительной степени лежат на линии, мы можем пометить любые точки как перекрывающиеся, если их значения y слишком близки. Вы можете включить более сложные условия, если важно проверить, близки ли значения x.

df$overlap = lapply(1:nrow(df), function(i) {
  if(min(abs(df[i, "Sum"] - df$Sum[-i])) <= 1) "Overlap" else "Ignore"
})

На графике я покрасил дрожащие точки в красный цвет, чтобы было легко определить, какие из них были затронуты.

# Add set.seed() here to make jitter reproducible
ggplot(df, aes(x = reorder(Firm, Sum, mean))) +
  geom_text(data=df[df$overlap=="Overlap",], 
            aes(label = Firm, y = Sum), size = 3,  
            position = position_jitter(width=0, height = 1), colour="red") +
  geom_text(data=df[df$overlap=="Ignore",], 
            aes(label = Firm, y = Sum), size = 3) +
  theme(axis.text.x = element_blank()) +
  scale_x_discrete(expand = c(-1.1, 0)) +   # to show the lower left name fully
  labs(x = "", y = "", title = "")

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

Вариант 2 (прямое размещение). Другой вариант - напрямую контролировать, насколько смещаются ярлыки, вместо того, чтобы брать все, что jitter может дать нам. В этом случае мы знаем, что хотим сдвинуть каждую пару точек с одинаковым значением y. Более сложная логика может потребоваться в случаях, когда нам нужно беспокоиться о значениях x и y, о более чем двух точках в одном и том же перекрытии и / или когда нам нужно сместить близкие, но не совсем одинаковые значения.

library(dplyr)

# Create a new column that shifts pairs of points with the same y-value by +/- 0.25
df = df %>% group_by(Sum) %>%
  mutate(SumNoOverlap = if(n()>1) Sum + c(-0.25,0.25) else Sum)

ggplot(df, aes(x = reorder(Firm, Sum, mean), y = SumNoOverlap)) +
  geom_text(aes(label = Firm), size = 3) +
  theme(axis.text.x = element_blank()) +
  scale_x_discrete(expand = c(-1.1, 0)) +   # to show the lower left name fully
  labs(x = "", y = "", title = "")

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

Примечание. Чтобы сделать джиттер воспроизводимым, добавьте set.seed(153) (или любое другое начальное значение, которое вы хотите) перед кодом измененного графика.

person eipi10    schedule 11.09.2015
comment
FYI - set.seed (123) не воспроизводит джиттер в моих руках с помощью ggplot2 2.2.1. - person milo; 01.08.2018