2016-07-13 8 views
1

Ich möchte die Breite von Violin-Plots, die ich mit dem ggplot2-Paket konstruiere, verändern.R - Ändern der Breite von (ggplot) Violin-Plots als eine Funktion der y-Variablen

Der Hintergrund folgt: Ich erhalte einen Datensatz, der eine Anzahl von Beobachtungen für eine bestimmte Größe eines Partikels zählt. Diese Größe wird meine y-Variable sein, die Anzahl der Vorfälle, die ich "Vorfälle" nennen werde.

Ich vereinfachte die Daten, so dass ich nur zwei verschiedene Sätze (angezeigt durch "id"), in 1 Datenrahmen geschmolzen.

library(ggplot2) 
library(data.table) 
dt1 <- data.frame(id=c("A","A","A","A","A","B","B","B","B","B"),y=c(10,20,30,40,50,10,20,30,40,50),incidents=c(3,1,5,9,2,4,2,7,1,5)) 

Soweit ich weiß, ein Violinstück ist die Berechnung der Breite der Violine auf der Grundlage der Anzahl der Auftritte eines bestimmten Wertes. Da die y-Achse des Plots die Größe haben soll, muss ich einen Datenrahmen haben, der keine "Incidents" -Spalte mehr enthält, sondern mit neuen Zeilen, abhängig vom Wert von "Incidents".

Ich konnte nicht herausfinden, wie das einfacher zu gestalten ist, also führe ich eine for-Schleife mit einer Zählervariablen und einer if-Klausel aus, um zu überprüfen, welche Art von Zeile die aktuelle Iteration dem neuen Datenrahmen hinzufügen soll (dt2) .

Dann plotte ich mit dem ggplot-Paket mit geom_violin().

library(ggplot2) 
library(data.table) 
dt1 <- data.frame(id=c("A","A","A","A","A","B","B","B","B","B"),y=c(10,20,30,40,50,10,20,30,40,50),incidents=c(3,1,5,9,2,4,2,7,1,5)) 

newlength <- sum(dt1$incidents) #This is the length of the new data table 
dt2 <- data.table(id=rep(as.character(0),newlength),size=rep(0,newlength)) 
counter <- 1 #initialize 
for (i in 1:newlength){ #iterate through all rows of new data table 
if (i > sum(dt1$incidents[1:counter])){ #check if current iteration number is larger than the accumulated number of all incidents that have been checked so far in dt1 
counter <- counter+1 #if so, increase counter 
} 
dt2[i,1:2 :=dt1[counter,c(1,2)]] #add the id and size information that is stored in dt1 at the row currently looked at 
} 

p <- ggplot(dt2, aes(x=1,y=size,color=id)) 
p + geom_violin() 

So weit so gut, aber das ist nicht genau das, was ich will. Anstelle der Anzahl von Partikeln mit bestimmten Größen möchte ich, dass das Violett-Diagramm mir das Gesamtvolumen aller Partikel mit dieser spezifischen Größe gibt. I.e. die Breite der Violinen sollte eine Funktion der Zählung (also des "Vorfall" -Wertes von dt1 oder der Anzahl von Reihen mit einem bestimmten Parameter von dt2) und der Größe selbst sein. Das heißt, ich möchte, dass die Violine mit höheren y-Werten breiter wird.

Betrachtet werden z.B. eine sphärische Form von Teilchen, ein "Vorfall" -Wert von 7 für eine Größe von 10 sollte eine Breite von 7 * (4/3 * pi * (10/2)^3) ergeben. Für ein Teilchen der Größe 50 sollte jedoch der gleiche "Zwischenfall" -Wert zu einer berechneten Breite von 7 * (4/3 * pi * (50/2)^3) führen.

Gibt es eine Möglichkeit, die Breitenberechnung der geom_violin-Plots als Funktion der y-Variablen zu ändern? Leider kann ich den Datenrahmen nicht wirklich ändern, um die mathematische Formel für das Volumen zu berücksichtigen (dh die "Zwischenfälle" mit der sphärischen Volumenformel zu multiplizieren), da die Anzahl der Reihen für Partikel mit Größen> 100 und "Incidents" -Werte> 1000 erreicht astronomische Höhen (würde zu einem Datenrahmen mit ~ 10.000.000.000 Zeilen für meine Daten führen).

Alle Ideen werden sehr geschätzt.

Vielen Dank im Voraus!

Antwort

1

Zuerst berechnen Sie die neue Variable:

dt1$total_particle_size<-dt1$incidents * (4/3 * pi * (dt1$y/2)^3) 

Dann Grundstück:

ggplot(dt1, aes(x=id,y=y,fill=id,width=total_particle_size))+ 
geom_violin() 

enter image description here

ich tun, um eine Warnung, die Sie vielleicht prüfen.

+0

Das funktioniert gut! Und es ist so einfach, es ist Genie! Warum habe ich nicht daran gedacht? Vielen Dank. Ich weiß allerdings nicht wirklich, was ich mit der Fehlermeldung machen soll: In density.default (x, gewichte = w, bw = bw, anpassen = anpassen, ...: summe (gewichte)! = 1 - wird nicht wahr dichte – Christian

+0

Ich habe versucht, mehr Informationen über die Warnung (kein Fehler), konnte aber nicht viel finden. Ich ermutige Sie, visuell zu überprüfen, ob die Breite korrekt mit der 'total_particle_size'-Variable korreliert und wenn ja, wird es Ihnen gut gehen. Wenn Sie eine Lösung finden, lassen Sie es mich bitte wissen. –

Verwandte Themen