2012-12-23 4 views
6

ich die Dichte der Variablen, dessen Bereich der folgenden plotten möge:Transforming variabler Dichte auf logarithmische Skala mit R

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

Die lineare Darstellung der Dichte führt zu einer hohen Säule in Bereich [0,1000] , mit zwei sehr langen Schwänzen in Richtung positiver Unendlichkeit und negativer Unendlichkeit. Daher möchte ich die Variable in eine logarithmische Skala umwandeln, so dass ich sehen kann, was um den Mittelwert herum läuft. Zum Beispiel, ich denke an so etwas wie:

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

die Ergebnisse:

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

Das Hauptproblem mit dieser Tatsache ist, dass es nicht die 0 Werte enthält. Natürlich kann ich alle Werte weg von 0 mit values[values>=0]+1 verschieben, aber dies würde etwas Verzerrung in den Daten einführen.

Was wäre eine akzeptierte und wissenschaftlich solide Methode zur Umwandlung dieser Variablen in die logarithmische Skala?

+0

Wie etwa zwei Parzellen zu schaffen? Einer für die gesamte Palette, der zweite nur mit dem Mittelteil. – Andrie

+0

Ja, ich habe darüber nachgedacht, aber ich frage mich, ob es eine clevere Umwandlung ist :-) – Mulone

+0

Sie könnten 'sign (values) * log10 (abs (values))' verwenden, um das zu erreichen, was Sie oben konstruiert haben, aber dann alle Nullwerte wird zu "-Inf". – James

Antwort

3

Neben der Umwandlung können Sie das Histogramm selbst manipulieren, um eine Vorstellung von Ihren Daten zu erhalten. Dies gibt Ihnen den Vorteil, dass die Plots selbst lesbar bleiben und Sie sofort eine Vorstellung von der Verteilung im Zentrum bekommen. Angenommen, wir simulieren die folgenden Daten:

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 

Dann haben Sie ein paar verschiedene Ansätze. Am einfachsten zu sehen, was in der Mitte Ihrer Daten vor sich geht, zeichnen Sie einfach die Mitte Ihrer Daten.In diesem Fall sagen, dass ich interessiert bin, was zwischen dem ersten und dem dritten Quartil der Fall ist, kann ich Grundstück:

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

Wenn Sie möchten, als auch die Schwänze zählen, können Sie verwandeln Ihre Daten, die den Schwanz und verändern die Achse zu reflektieren diese, kollabieren, wie folgt:

  1. Sie alle Werte außerhalb des Bereichs von Interesse einen Wert zuweisen, die außerhalb dieses Bereichs gerade sind
  2. Sie das Histogramm plotten, binnin g alle Extremwerte in einem Behälter
  3. Sie die X-Achse mit den richtigen Etiketten
  4. Sie axis.break() aus dem Paket verwenden konstruieren plotrix einige Pausen auf der X-Achse hinzuzufügen,

die diskontinuierliche Achse, die für die Sie können so etwas wie den folgenden Code verwenden:

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) 

Dies gibt Ihnen:

enter image description here

Beachten Sie, dass Sie Rohfrequenzen erhalten, indem Sie freq=TRUE zu der hist() Funktion hinzufügen.

4

Was Sie haben, ist im Wesentlichen was @James vorschlägt. Dies ist problematisch für Werte in (-1,1), insbesondere solche der Nähe des Ursprungs:

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

enter image description here

So etwas kann helfen:

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

Dies ist kontinuierlich. Man kann C^1 erzwingen, indem das Intervall unter Verwendung von (-1/log (10), 1/log (10)), die durch Lösen von d/dx log10 (x) = 1 gefunden wird:

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

Ich füge das als eine andere Antwort hinzu, denn obwohl die Idee ähnlich ist, unterscheidet sich das Mapping grundlegend.

Wenn kleine Werte (< 1) in einem logarithmisch skalierten Diagramm enthalten sind, handelt es sich um das typische Diagramm log(1 + .) anstelle von log(.).

Reflektieren über den Ursprung, und wir bekommen etwas Nützliches:

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='.') 

Es sollte klar sein, dass die Funktion glatt ist, da die Richtungsableitungen um 0 auch reflektiert wird. enter image description here

Mit vielen größeren Werten in 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