2012-12-23 17 views
6

voglio tracciare la densità della variabile il cui intervallo è la seguente:Trasformare densità variabile su scala logaritmica con R

Min. :-1214813.0 
1st Qu.:  1.0 
Median :  40.0 
Mean :  303.2 
3rd Qu.:  166.0 
Max. : 1623990.0 

La trama lineare dei risultati di densità in una colonna alta nel range [0,1000] con due code molto lunghe verso l'infinito positivo e l'infinito negativo. Quindi, mi piacerebbe trasformare la variabile in una scala di registro, in modo che io possa vedere cosa sta succedendo attorno alla media. Per esempio, sto pensando a qualcosa di simile:

log_values = c(-log10(-values[values<0]), log10(values[values>0])) 

che si traduce in:

Min. 1st Qu. Median Mean 3rd Qu. Max. 
-6.085 0.699 1.708 1.286 2.272 6.211 

Il problema principale di questo è il fatto che esso non include i valori 0. Ovviamente, posso spostare tutti i valori da 0 con values[values>=0]+1, ma ciò introdurrebbe una certa distorsione nei dati.

Quale sarebbe un modo accettato e scientificamente valido per trasformare questa variabile nella scala del registro?

+0

Come sulla creazione di due lotti? Uno per l'intera gamma, il secondo con solo la sezione centrale. – Andrie

+0

Sì, ci ho pensato, ma mi stavo chiedendo se c'è una trasformazione intelligente :-) – Mulone

+0

Potresti usare 'segno (valori) * log10 (abs (valori))' per ottenere ciò che hai costruito sopra, ma poi tutti i valori zero diventerà '-Inf'. – James

risposta

3

Oltre alla trasformazione, è possibile manipolare l'istogramma stesso per avere un'idea dei dati. Questo ti dà il vantaggio che le trame stesse rimangono leggibili e tu hai un'idea immediata della distribuzione al centro. Supponiamo di simulare i seguenti dati:

Data <- c(rnorm(1000,5,10),sample(-10000:10000,10)) 
> summary(Data) 
    Min. 1st Qu. Median  Mean 3rd Qu.  Max. 
-9669.000 -2.119  5.332 85.430 12.460 9870.000 

Quindi avete alcuni approcci diversi. Il modo più semplice per vedere cosa sta succedendo al centro dei tuoi dati è tracciare il centro dei tuoi dati.In questo caso, dire che sono interessati a quello che succede tra il primo e il terzo quartile, posso tracciare:

hist(Data, 
    xlim=c(-30,30), 
    breaks=c(min(Data),seq(-30,30,by=5),max(Data)) 
    main="Center of Data" 
    ) 

enter image description here

Se si desidera contare le code così, è possibile trasformare il vostro dati al collasso le code e alterare l'asse per riflettere questo, come segue:

  1. di assegnare tutti i valori al di fuori della gamma di interessi di un valore che è appena al di fuori di tale intervallo
  2. si traccia l'istogramma, binnin g tutti i valori estremi in un unico raccoglitore
  3. si costruisce l'asse X con le etichette corrette
  4. si utilizza axis.break() dal pacchetto plotrix per aggiungere alcune pause sul vostro asse X, che indica l'asse discontinua

Per questo si può usare qualcosa come il seguente codice:

require(plotrix) 
# rearrange data 
plotdata <- Data 
id <- plotdata < -30 | plotdata > 30 
plotdata[id] <- sign(plotdata[id])*35 
# plot histogram 
hist(plotdata, 
     xlim=c(-40,40), 
     breaks=c(-40,seq(-30,30,by=5),40), 
     main="Untailed Data", 
     xaxt='n' # leave the X axis away 
    ) 
# Construct the X axis 
axis(1, 
     at=c(-40,seq(-30,30,by=10),40), 
     labels=c(min(Data),seq(-30,30,by=10),max(Data)) 
) 
# add axis breaks 
axis.break(axis=1,breakpos=-35) 
axis.break(axis=1,breakpos=35) 

Questo vi dà:

enter image description here

Si noti che si ottengono le frequenze grezze aggiungendo freq=TRUE alla funzione hist().

4

Quello che hai è essenzialmente ciò che @James suggerisce. Questo è problematico per i valori a (-1,1), specialmente quelli vicino all'origine:

x <- seq(-2, 2, by=.01) 
plot(x, sign(x)*log10(abs(x)), pch='.') 

enter image description here

Qualcosa di simile a questo può aiutare:

y <- c(-log10(-x[x<(-1)])-1, x[x >= -1 & x <= 1], log10(x[x>1])+1) 

plot(x, y, pch='.') 

enter image description here

Questo è continuo. Si può forzare C^1 utilizzando l'intervallo (-1/log (10), 1/log (10)), che si trova risolvendo d/dx log10 (x) = 1:

z <- c(-log10(-x[x<(-1/log(10))]) - 1/log(10)+log10(1/log(10)), 
     x[x >= -1/log(10) & x <= 1/log(10)], 
     log10(x[x>1/log(10)]) + 1/log(10)-log10(1/log(10)) 
     ) 
plot(x, z, pch='.') 

enter image description here

1

Sto aggiungendo questo come un'altra risposta, perché anche se l'idea è simile, la mappatura è fondamentalmente diversa.

Quando piccoli valori (< 1) sono inclusi in un grafico con scalatura del log, è il grafico tipico log(1 + .) anziché log(.).

Riflettere attraverso l'origine, e otteniamo qualcosa di utile:

x <- seq(-2, 2, by=.01) 
w <- c(-log10(1-x[x<0]), x[x==0], log10(1+x[x>0])) 

plot(x, w, pch='.') 

Dovrebbe essere chiaro che la funzione è liscia, come si rifletterà anche le derivate direzionali circa 0. enter image description here

Con valori molto più grandi di x:

x <- seq(-10000, 10000, by=.01) 
w <- c(-log10(1-x[x<0]), x[x==0], log10(1+x[x>0])) 
plot(x, w, pch='.') 

enter image description here

Problemi correlati