2010-11-22 2 views
19
library(ggplot2) 

orderX <- c("A" = 1, "B" = 2, "C" = 3) 
y <- rnorm(20) 
x <- as.character(1:20) 
group <- c(rep("A", 5), rep("B", 7), rep("C", 5), rep("A", 3)) 
df <- data.frame(x, y, group) 
df$lvls <- as.numeric(orderX[df$group]) 

ggplot(data = df, aes(x=reorder(df$x, df$lvls), y=y)) + 
geom_point(aes(colour = group)) + 
geom_line(stat = "hline", yintercept = "mean", aes(colour = group)) 

Chcę utworzyć wykres takiego: graph with averages for each groupggplot2: dodaj linię do średniej w grupie

To działa, kiedy nie trzeba uporządkować wartości X, jednak kiedy robię użyj zmiany kolejności, to już nie działa.

+0

myślę korzystanie z Reorder myli się tutaj, ponieważ po prostu zmieni kolejność X, a nie grupy lub Y. Spowoduje to wydrukowanie błędnego x z nieprawidłowym y! –

+0

O ile X nie oznacza niczego oprócz indeksu, w takim przypadku nie używaj go na działce (użyj jitter zamiast?) –

+0

Wtedy moje użycie kolejki jest błędne. W moich prawdziwych danych wartości na x są etykietami dla każdego pojedynczego pomiaru, który chcę zobaczyć. Zamawianie tych etykiet w grupach nie ma znaczenia. – wligtenberg

Odpowiedz

3

jako z g gplot2 2.x to podejście jest niestety zepsute.

Poniższy kod zapewnia dokładnie to, co chciałem, z pewnymi dodatkowymi obliczeniami góry przód:

library(ggplot2) 
library(data.table) 

orderX <- c("A" = 1, "B" = 2, "C" = 3) 
y <- rnorm(20) 
x <- as.character(1:20) 
group <- c(rep("A", 5), rep("B", 7), rep("C", 5), rep("A", 3)) 
dt <- data.table(x, y, group) 
dt[, lvls := as.numeric(orderX[group])] 
dt[, average := mean(y), by = group] 
dt[, x := reorder(x, lvls)] 
dt[, xbegin := names(which(attr(dt$x, "scores") == unique(lvls)))[1], by = group] 
dt[, xend := names(which(attr(dt$x, "scores") == unique(lvls)))[length(x)], by = group] 

ggplot(data = dt, aes(x=x, y=y)) + 
    geom_point(aes(colour = group)) + 
    facet_grid(.~group,space="free",scales="free_x") + 
    geom_segment(aes(x = xbegin, xend = xend, y = average, yend = average, group = group, colour = group)) 

Uzyskany obraz:

enter image description here

+3

Nie jestem pewien, czy to pomoże w twojej dokładnej sytuacji, ale nowe rozwiązanie, które znalazłem z ggplot2 v2.1.0 dla podobnego problemu to 'stat_summary (fun.y =" mean ", fun.ymin =" mean ", fun.ymax =" mean ", size = 0.3, geom =" crossbar ") '. –

+0

Próbowałem tego, który tworzy poziome linie na element na osi X. Powodem tego jest to, że oś X jest dyskretna. – wligtenberg

16

Z twojego pytania, nie zgadzam się z df$x w odniesieniu do twoich danych, zwłaszcza jeśli możesz je zamówić ponownie. Jak o tym, przy użyciu group jako X i jitter rzeczywista pozycja X, aby oddzielić elementy:

ggplot(data=df, aes(x=group,y=y,color=group)) + geom_point() + 
geom_jitter(position = position_jitter(width = 0.4)) + 
geom_errorbar(stat = "hline", yintercept = "mean", 
    width=0.8,aes(ymax=..y..,ymin=..y..)) 

I stosuje errorbar zamiast h_line (i zwinięte w ymax i ymin Y) od hline jest złożona. Jeśli ktoś ma lepsze rozwiązanie tej części, chciałbym to zobaczyć.

alt text


aktualizacja

Jeśli chcesz zachować kolejność X, spróbuj tego rozwiązania (ze zmodyfikowanym X)

df$x = factor(df$x) 

ggplot(data = df, aes(x, y, group=group)) + 
facet_grid(.~group,space="free",scales="free_x") + 
geom_point() + 
geom_line(stat = "hline", yintercept = "mean") 

alt text

+0

To jest rzeczywiście prawie to, co chcę, ale chcę, aby móc zobaczyć oryginalne wartości x w skali X. – wligtenberg

+0

Po wykonaniu ponownej zamówienia dane zostaną pomieszane. Powinieneś posortować oryginalną ramkę danych, a nie tylko wartości x. Czy chcesz, aby wartości X przeplecione na wykresie? Jeśli tak, to gdzie chcesz umieścić wartości średnie? –

+0

gdzie znalazłeś dokumentację na geom_line (stat = "hline", yintercept = "mean")? To naprawdę fajne i nie widziałem tego wcześniej. –