Скрыть поле и усы в geom_boxplot (), когда N мало - PullRequest
2 голосов
/ 10 октября 2019

Я часто делаю коробочные диаграммы, где некоторые категории довольно малы, а другие содержат множество данных, наложенных на разбитые необработанные точки данных. Я ищу надежный способ скрыть коробку и усы для категорий, которые очень малы (N <5). Цель состоит в том, чтобы эти маленькие категории отображали только необработанные данные с использованием слоя geom_point (), а категории, в которых это имеет смысл, получили бы обработку типа «коробочка и усы». То, что мне показалось очевидным, отображение альфа в слое geom_boxplot () на факторную переменную, основанную на N, не работает, потому что альфа контролирует только заливку и, возможно, выбросы в geom_boxplot, а не прямоугольник и усы. </p>

В прошлом я нашел решение, которое работало до тех пор, пока я был готов потратить впустую параметр цвета для этой проблемы. Тем не менее, часто я хочу использовать цвет для чего-то другого, и отображение его дважды приводит к грубому выводу. Другое подходящее мне решение заключается в использовании подмножества данных, из которого были удалены небольшие категории - проблема с этим планом заключается в том, что он не будет правильно обрабатывать ситуации, когда эти категории подчиняются position_dodge () (как будет видеть dodge). "слишком мало категорий).

Минимальный пример ниже.

df <- data.frame(group=factor(sample(c("A","B"), size=110, replace=TRUE)),
                 sex=factor(c(rep("M",50), rep("F", 50), rep("NB", 10))),
                 height=c(rnorm(50, 70, 6), rnorm(50, 63, 6), rnorm(10, 65, 6)))

dfsub <- filter(df, !(sex=="NB" & group=="A"))

ggplot(df, aes(x=group, y=height, colour=sex)) +
  geom_boxplot(data=dfsub) +
  geom_point(position=position_jitterdodge(jitter.width=0.2))

Ответы [ 2 ]

1 голос
/ 10 октября 2019

Я создал второй столбец для ваших данных о высоте, где значения из небольших групп размеров выборки заменяются на NA. При построении данных используйте исходный столбец высоты в качестве эстетики y для точек, а новый столбец со значениями NA для небольших групп в качестве эстетики y для коробочных диаграмм.

Чтобы правильно составить прямоугольники и точки, выстроенные в ряд, используйте geom_boxplot(position_dodge(preserve = "single")), чтобы сообщить ggplot, чтобы поддерживать постоянную ширину для блочных диаграмм даже с отсутствующими данными.

require(tidyverse)

df <- data.frame(group = factor(sample(c("A", "B"), size = 110, replace = TRUE)),
                 sex = factor(c(rep("M", 50), rep("F", 50), rep("NB", 10))),
                 height = c(rnorm(50, 70, 6), rnorm(50, 63, 6), rnorm(10, 65, 6)))

n <- df %>% #calculate sample sizes
  group_by(group, sex) %>%
  summarize(n = n())

df <- left_join(df, n) %>% #join sample sizes to df
  #make second height column to use for boxplots: NA values if n is too small
  mutate(boxplot_height = ifelse(n < 5, NA, height)) 


ggplot(df, aes(x = group, colour = sex)) +
  #use height column that has groups with n < 5 coded as NA to plot boxplots
  geom_boxplot(aes(y = boxplot_height),
               #preserve = "single" maintains constant width of boxes 
               position = position_dodge(preserve = "single")) +
  geom_point(aes(y = height), #use all height data as y variable for points
             position = position_jitterdodge(jitter.width = 0.2))

enter image description here

1 голос
/ 10 октября 2019

Хорошо, я не думаю, что этот способ обязательно будет лучше, чем ваши текущие параметры, но ... Вы можете разделить свой df на dfs для boxplot и scatterplot, и изменить значения данных, которые вы хотите удалить изполе должно быть вне диапазона (например, 1000 здесь). Затем нанесите и то и другое и, наконец, используйте coord_cartesian, чтобы увеличить соответствующий раздел.

Чтобы создать df_box, мы группируем по group и sex и меняем значения групп с <5 точками данных на 1000 (чтобы нам не приходилось жестко задавать код, в которомизменяемые значения). </p>

df <- data.frame(group=factor(sample(c("A","B"), size=110, replace=TRUE)),
                 sex=factor(c(rep("M",50), rep("F", 50), rep("NB", 10))),
                 height=c(rnorm(50, 70, 6), rnorm(50, 63, 6), rnorm(10, 65, 6)))

df_box <- df %>%
    group_by(group, sex) %>%
    mutate(temp = ifelse(n() < 5, 1000, 1)) %>%
    ungroup() %>%
    mutate(height = ifelse(temp == 1000, 1000, height)) %>%
    select(-temp)

ggplot(df, aes(x=group, y=height, colour=sex)) +
    geom_boxplot(data=df_box) +
    geom_point(position=position_jitterdodge(jitter.width=0.2)) +
    coord_cartesian(ylim=c(50,90))

image

...