Ukryć pudełko i wąsy w geom_boxplot (), gdy N jest mała

głosy
1

I często sprawiają boxplots gdzie niektóre z kategorii są dość małe i inni dane obfite, nałożone z jittered surowych danych punktów. Szukam niezawodny sposób, aby ukryć okno i wąsy dla kategorii, które są bardzo małe (N <5). Celem jest to, że te małe kategorie pokaże tylko surowych danych przy użyciu geom_point () warstwy, ale kategorie, gdzie ma to sens, by uzyskać pomoc pudełko i wąsy. Tym, co wydawało się dla mnie oczywiste, mapowanie alfa w geom_boxplot (warstwy) do zmiennej czynnika na bazie N, nie działa, ponieważ alfa kontroluje tylko wypełnienie i być może odstających w geom_boxplot, a nie pudełko i wąsy.

Znalazłem kludgey rozwiązanie w przeszłości, że pracował tak długo jak będę chciał tracić parametr koloru na ten problem. Jednak często chcę faktycznie korzysta kolor na coś innego, i to dwukrotnie mapowanie prowadzi do wyjścia gnarly. Innym rozwiązaniem, które występuje kludgey mi używa podzbiór danych, z którego małe kategorie zostały usunięte - problem z tym planem jest to, że nie będzie prawidłowo obsługiwać sytuacje, kiedy te kategorie podlegają position_dodge () (jak Dodge będzie „widzieć zbyt mało kategorie).

Minimalny przykład poniżej.

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))
Utwórz 10/10/2019 o 00:44
źródło użytkownik
W innych językach...                            


2 odpowiedzi

głosy
0

Można użyć position_dodge(preserve = "single")w geom_boxplot()celu powiedzieć ggplot aby utrzymać stałą szerokość dla boxplots nawet o brakujące dane.

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

wprowadzić opis obrazu tutaj

Odpowiedział 10/10/2019 o 18:53
źródło użytkownik

głosy
0

Dobra, ja nie myślę w ten sposób zawsze jest lepsza niż dotychczasowe opcje, ale ... Można podzielić df do DFS dla wykresu pudełkowego i rozrzutu i zmodyfikować wartości danych, które mają zostać usunięte z wykresu pudełkowego do być droga poza zakresem (np 1000 tutaj). Następnie wykreślić obu, i wreszcie użyć coord_cartesian, aby powiększyć odpowiedniej sekcji.

Aby utworzyć df_box, mamy grupę, groupi sex, i zmienić wartości każdego z <5 punktów danych do 1000 (tak, że nie mamy do hard-kodu, w której ceni się zmienić).

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

wizerunek

Odpowiedział 10/10/2019 o 01:13
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more