web-dev-qa-db-fra.com

Tracé des comptes cumulatifs dans ggplot2

Il y a quelques articles sur le traçage des densités cumulatives dans ggplot. J'utilise actuellement la réponse acceptée de Un moyen plus simple de tracer la distribution de fréquence cumulée dans ggplot? pour tracer mes comptes cumulatifs. Mais cette solution implique de pré-calculer les valeurs à l’avance.

Ici, je cherche une solution pure de ggplot. Montrons ce que j'ai jusqu'ici:

x <- data.frame(A=replicate(200,sample(c("a","b","c"),1)),X=rnorm(200))

stat_ecdf de ggplot

Je peux utiliser le stat_ecdf de ggplot, mais il ne trace que les densités cumulatives:

ggplot(x,aes(x=X,color=A)) + geom_step(aes(y=..y..),stat="ecdf")

enter image description here

J'aimerais faire quelque chose comme ce qui suit, mais ça ne marche pas:

ggplot(x,aes(x=X,color=A)) + geom_step(aes(y=..y.. * ..count..),stat="ecdf")

cumsum et stat_bin

J'ai trouvé une idée sur l'utilisation de cumsum et stat_bin:

ggplot(x,aes(x=X,color=A)) + stat_bin(aes(y=cumsum(..count..)),geom="step")

enter image description here

Mais comme vous pouvez le constater, la couleur suivante ne commence pas par y=0, mais se termine par la dernière couleur.

Ce que je demande

Ce que j'aimerais avoir du meilleur au pire:

  1. Idéalement, une solution simple au non-fonctionnement

    ggplot(x,aes(x=X,color=A)) + geom_step(aes(y=..y.. * ..count..),stat="ecdf")
    
  2. Une manière plus compliquée d'utiliser stat_ecdf avec des comptes.

  3. Le dernier recours serait d’utiliser l’approche cumsum, car elle donne des résultats pires (ventilés).
27
ziggystar

Cela ne résoudra pas directement le problème de regroupement des lignes mais ce sera une solution de contournement. 

Vous pouvez ajouter trois appels à stat_bin() pour lesquels vous sous-définissez vos données en fonction de niveaux A.

ggplot(x,aes(x=X,color=A)) +
  stat_bin(data=subset(x,A=="a"),aes(y=cumsum(..count..)),geom="step")+
  stat_bin(data=subset(x,A=="b"),aes(y=cumsum(..count..)),geom="step")+
  stat_bin(data=subset(x,A=="c"),aes(y=cumsum(..count..)),geom="step")

enter image description here

UPDATE - solution utilisant geom_step ()

Une autre possibilité consiste à multiplier les valeurs de ..y.. par le nombre d'observations dans chaque niveau. Pour obtenir ce nombre d'observations à ce moment-là, le seul moyen que j'ai trouvé est de les précalculer avant de les tracer et de les ajouter au bloc de données d'origine. J'ai nommé cette colonne len. Ensuite, dans geom_step() dans aes(), vous devrez définir que vous utiliserez la variable len=len, puis définirez les valeurs y comme y=..y.. * len.

set.seed(123)
x <- data.frame(A=replicate(200,sample(c("a","b","c"),1)),X=rnorm(200))
library(plyr)
df <- ddply(x,.(A),transform,len=length(X))
ggplot(df,aes(x=X,color=A)) + geom_step(aes(len=len,y=..y.. * len),stat="ecdf") 

enter image description here

21
Didzis Elferts

Vous pouvez appliquer row_number sur les groupes et l'utiliser comme esthétique Y dans un geom_step ou une autre géométrie. Vous devrez simplement trier par X ou les valeurs apparaîtront telles quelles dans le bloc de données, sans ordre. 

ggplot(x %>% 
         group_by(A) %>% 
         arrange(X) %>% 
         mutate(rn = row_number())) + 
  geom_step(aes(x=X, y=rn, color=A))

 Cumulative count by group

3
jdoubleyou