2010-07-02 8 views
13

Mithilfe von position_jitter wird ein zufälliger Jitter erzeugt, um eine Überlagerung von Datenpunkten zu verhindern.Ist es möglich, zwei ggplot geoms in der gleichen Weise zu jittern?

Im Folgenden habe ich das Beispiel der Baseball-Statistik verwendet, um mein Problem zu veranschaulichen. Wenn ich die gleichen Daten mit zwei Layern plotte, jittert derselbe Jitter-Aufruf die Geome etwas anders. Dies ist sinnvoll, weil es vermutlich den zufälligen Jitter in den beiden Aufrufen unabhängig erzeugt, aber das Problem, das Sie in meiner Grafik unten sehen können.

p=ggplot(baseball,aes(x=round(year,-1),y=sb,color=factor(lg))) 
p=p+stat_summary(fun.data="mean_cl_normal",position=position_jitter(width=3,height=0))+coord_cartesian(ylim=c(0,40)) 
p+stat_summary(fun.y=mean,geom="line",position=position_jitter(width=3,height=0)) 

Obwohl die Fehlerbalken Punkte und die zu gleichen Daten beziehen Linie, sie sind unzusammenhängend-Linien und Punkte nicht anschließen.

Gibt es dafür einen Workaround? Ich dachte, dass Position Ausweichen die Antwort sein könnte, aber es scheint nicht mit diesen Arten von Plots zu arbeiten. Alternativ dazu gibt es vielleicht eine Möglichkeit, den Aufruf mean_cl_normal dazu zu bringen, auch die Zeilen hinzuzufügen. alt text http://img339.imageshack.us/img339/1807/screenshot20100702at943.png

Antwort

7

Dies ist eine Schwäche in der aktuellen ggplot2-Syntax - es gibt keine Möglichkeit, es zu umgehen, außer den Jitter selbst hinzuzufügen.

Oder man könnte so etwas tun:

ggplot(baseball, aes(round(year,-1) + as.numeric(factor(lg)), sb, color = factor(lg))) + 
    stat_summary(fun.data="mean_cl_normal") + 
    stat_summary(fun.y=mean,geom="line") + 
    coord_cartesian(ylim=c(0,40)) 
+2

hadley: Wurden irgendwelche Aktualisierungen an ggplot2 vorgenommen, seit du darauf geantwortet hast? – gvrocha

8

Ich denke so, indem das Saatgut Einstellung die gleiche in den beiden Fällen zu sein:

p=ggplot(baseball,aes(x=round(year,-1),y=sb,color=factor(lg))) 
myseed = 2010 
set.seed(myseed) 
p=p+stat_summary(fun.data="mean_cl_normal", 
    position=position_jitter(width=3,height=0))+coord_cartesian(ylim=c(0,40)) 
set.seed(myseed) 
p+stat_summary(fun.y=mean,geom="line", 
      position=position_jitter(width=3,height=0)) 

Dies stellt sicher, dass der Zufallszahlengenerator auf die gleiche Ausgangsposition zurückgeschickt wird, wie in der verwendet wurde, erster Anruf. Ich weiß jedoch nicht, wie Sie die zufälligen Inkremente, die den Werten hinzugefügt wurden, extrahieren können.

+0

Gute Idee, aber es hat nicht funktioniert! Ich dachte, es würde funktionieren, weil es so aussieht, als ob position_jitter den Jitter des Basispakets verwendet, von dem ich erwartete, dass er denselben Zufallszahlengenerator verwenden würde, der von set.seed gesetzt wird. Ich nehme an, ein allgemeiner Workaround wäre, meine eigene jittered Version von x zu erstellen, aber hoffentlich gibt es einen besseren Weg. –

+1

Das wird nicht funktionieren, weil das Zittern zur Plot-Zeit erfolgt, nicht zur Erstellungszeit. – hadley

+0

das hat perfekt für mich funktioniert. Vielleicht etwas über eine neue Version seit Hadley kommentiert (vor 4 Jahren). Dies sollte für mich die neue Antwort sein. – rcorty

1

ich am Ende eine gleichmäßige Verteilung zu erzeugen, dieses Problem zu lösen.

Ich musste heute das gleiche zugrunde liegende Problem ansprechen. Ich erstelle einen Plot, jittere die Punkte, und dann erstelle ich einen zweiten Plot, der im Wesentlichen auf einen Teilbereich des ersten zoomt. Es ist dissonant und ablenkend, wenn sich die Punkte bewegen.

Folgendes ist eine Demo des Problems und meiner Lösung. Ich benutze ggplot nicht für diese Handlung, aber das gleiche Konzept trifft zu. Ich mache eine einheitliche Verteilung, einen Wert für jeden Wert, den ich jittern muss. Ich füge es dem Quelldatenrahmen hinzu, so dass jedes Mal, wenn ich eine Teilmenge nehme, der Jitterwert dem gleichen ursprünglichen Datenwert entspricht.

data(airquality) 
someDataset= airquality 
someDataset$color="black" 
someDataset$color[someDataset$Month==8 & someDataset$Wind==9.7]="red" 
## jitter gives different results each time it's run 
for (fZoom in c(TRUE, FALSE)){ 
    if (fZoom) myAirQuality = someDataset[someDataset $Wind >7.5 & someDataset $Wind < 11.5,] 
    else myAirQuality = someDataset[someDataset $Wind >8.5 & someDataset $Wind < 10.5,] 
    quartz("Using Jitter") 
    plot(myAirQuality $Wind ~ jitter(myAirQuality $Month), col= myAirQuality$color) 
    } 

someDataset$MonthJit=runif(nrow(someDataset), min=-0.2, max=0.2) 
for (fZoom in c(TRUE, FALSE)){ 
    if (fZoom) myAirQuality = someDataset[someDataset $Wind >7.5 & someDataset $Wind < 11.5,] 
    else myAirQuality = someDataset[someDataset $Wind >8.5 & someDataset $Wind < 10.5,] 
    quartz("Using runif") 
    plot(myAirQuality $Wind ~ c(myAirQuality $Month + myAirQuality $MonthJit), col= myAirQuality$color) 
    }