2013-11-29 14 views
6

Sto provando a disegnare un ECDF di alcuni dati con un "intervallo di confidenza" rappresentato tramite un'area ombreggiata utilizzando ggplot2. Ho difficoltà a combinare geom_ribbon() con stat_ecdf() per ottenere l'effetto che sto cercando.Come combinare stat_ecdf con geom_ribbon?

Considerate i seguenti dati esempio:

set.seed(1) 
dat <- data.frame(variable = rlnorm(100) + 2) 
dat <- transform(dat, lower = variable - 2, upper = variable + 2) 

> head(dat) 
    variable  lower upper 
1 2.534484 0.5344838 4.534484 
2 3.201587 1.2015872 5.201587 
3 2.433602 0.4336018 4.433602 
4 6.929713 4.9297132 8.929713 
5 3.390284 1.3902836 5.390284 
6 2.440225 0.4402254 4.440225 

sono in grado di produrre un ECDF di variable usando

library("ggplot2") 
ggplot(dat, aes(x = variable)) + 
    geom_step(stat = "ecdf") 

Tuttavia io sono in grado di utilizzare lower e upper come ymin e ymax estetica geom_ribbon() per sovrapporre l'intervallo di confidenza alla trama come un altro livello. Ho provato:

ggplot(dat, aes(x = variable)) + 
    geom_ribbon(aes(ymin = lower, ymax = upper), stat = "ecdf") + 
    geom_step(stat = "ecdf") 

ma questo solleva il seguente errore

Error: geom_ribbon requires the following missing aesthetics: ymin, ymax 

Esiste un modo di convincere geom_ribbon() a lavorare con stat_ecdf() per produrre un intervallo di confidenza ombreggiata? Oppure, qualcuno può suggerire un mezzo alternativo per aggiungere un poligono ombreggiato definito da lower e upper come livello del grafico ECDF?

risposta

3

Prova questa (un po 'di salto nel buio):

ggplot(dat, aes(x = variable)) + 
    geom_ribbon(aes(x = variable,ymin = ..y..-2,ymax = ..y..+2), stat = "ecdf",alpha=0.2) + 
    geom_step(stat = "ecdf") 

Ok, così che non è la stessa cosa di ciò che si cerca di fare, ma dovrebbe spiegare cosa sta succedendo. stat restituisce un frame di dati con solo la x originale e la y calcolata, quindi penso che sia tutto ciò che devi lavorare. Ad esempio, stat_ecdf calcola solo la funzione di distribuzione cumulativa per una singola x alla volta.

L'unica altra cosa che posso pensare è l'ovvio, il calcolo del qualcosa inferiore e superiore a parte, in questo modo:

l <- ecdf(dat$lower) 
u <- ecdf(dat$upper) 
v <- ecdf(dat$variable) 
dat$lower1 <- l(dat$variable) 
dat$upper1 <- u(dat$variable) 
dat$variable1 <- v(dat$variable) 

ggplot(dat,aes(x = variable)) + 
    geom_step(aes(y = variable1)) + 
    geom_ribbon(aes(ymin = upper1,ymax = lower1),alpha = 0.2) 
+0

Grazie Joran. Potresti espandere la tua ultima frase? Non sono sicuro di seguirlo completamente, ma per quanto posso dire dalla tua risposta, non posso farlo tramite 'stat_ecdf' se' lower' e 'upper' esistono già? Il +/- 2 bit era solo un dato fittizio; le informazioni CI che ho sono il risultato della simulazione posteriore di una statistica derivata calcolata da un modello montato. –

+1

@GavinSimpson Sì, penso che non sia possibile direttamente in ggplot (anche se sarebbe una bella funzionalità da aggiungere, credo). Tutto quello che intendevo con l'ultimo bit era che dovresti calcolare manualmente tutti i valori ECDF e poi tracciarli. – joran

+0

Grazie, capisco cosa intendi, calcola direttamente la proporzione cumulativa. Lo darò a fare. +1 –

2

Non so esattamente come si desidera riflettere il CI, ma ggplot_build() consente di ottenere i dati generati indietro dalla trama, è possibile quindi sovrapporre ciò che ti piace.

Questo grafico mostra:

  • rosso = nastro originale
  • blu = prende i vettori originali CI e vale per la curva ecdf
  • verde = calcola l'ecdf di serie superiore e inferiore e trame

enter image description here

g<-ggplot(dat, aes(x = variable)) + 
     geom_step(stat = "ecdf") + 
     geom_ribbon(aes(ymin = lower, ymax = upper), alpha=0.5, fill="red") 

    inside<-ggplot_build(g) 
    matched<-merge(inside$data[[1]],data.frame(x=dat$variable,dat$lower,dat$upper),by=("x")) 

    g + 
     geom_ribbon(data=matched, aes(x = x, 
             ymin = y + dat.upper-x, 
             ymax = y - x + dat.lower), 
        alpha=0.5, fill="blue") + 
     geom_ribbon(data=matched, aes(x = x, 
             ymin = ecdf(dat.lower)(x), 
             ymax = ecdf(dat.upper)(x)), 
        alpha=0.5, fill="green") 
+0

Grazie Troy; la tua idea finale, una volta realizzato ciò che la trama mostrava, è simile all'idea di @joran, ovvero che si possono calcolare i dati 'y' appropriati per gli elementi della configurazione inferiore e superiore usando' ecdf() '. Il nastro verde è essenzialmente ciò che voglio rappresentare. –