Wie wandle ich negative Werte in Logarithmen um?

12

Ich würde gerne wissen, wie man negative Werte umwandelt Log(), da ich heteroskedastische Daten habe. Ich habe gelesen, dass es mit der Formel funktioniert, Log(x+1)aber dies funktioniert nicht mit meiner Datenbank und ich erhalte weiterhin NaNs als Ergebnis. Ich erhalte zB die folgende Warnmeldung (ich habe meine Datenbank nicht vollständig angegeben, weil ich denke, dass einer meiner negativen Werte ausreicht, um ein Beispiel zu zeigen):

> log(-1.27+1)
[1] NaN
Warning message:
In log(-1.27 + 1) : NaNs produced
> 

Danke im Voraus

AKTUALISIEREN:

Hier ist ein Histogramm meiner Daten. Ich arbeite mit paläontologischen Zeitreihen chemischer Messungen. ZB ist der Unterschied zwischen Variablen wie Ca und Zn zu groß, dann brauche ich eine Art Datenstandardisierung. Deshalb teste ich die log()Funktion. Bildbeschreibung hier eingeben

Das sind meine Rohdaten

Darwin PC
quelle
2
Der Logarithmus ist nur für positive Zahlen definiert und wird normalerweise als statistische Transformation für positive Daten verwendet, damit ein Modell diese Positivität beibehält. Der log(x+1)Transformationswille ist nur für definiert x > -1, da er dann x + 1positiv ist. Es wäre gut zu wissen, warum Sie Ihre Daten protokollieren möchten.
Matthew Drury
3
Erzählen Sie uns mehr über die Daten, einschließlich Bereich, Mittelwert, Häufigkeit von negativen, Null- und positiven Werten. Es kann sein, dass ein verallgemeinertes lineares Modell mit Protokollverknüpfung für die Daten am sinnvollsten ist, sofern man davon ausgeht, dass die mittlere Antwort positiv ist. Es könnte sein, dass Sie sich überhaupt nicht verändern sollten.
Nick Cox
6
Vielen Dank für das Hinzufügen von Details. Für solche Daten hat 0 eine Bedeutung (Gleichheit!), Die respektiert, ja erhalten werden sollte . Aus diesem und anderen Gründen würde ich Kubikwurzeln verwenden. In der Praxis müssen Sie einige Änderungen vornehmen sign(x) * (abs(x))^(1/3), deren Details von der Softwaresyntax abhängen. Weitere Informationen zu Kubikwurzeln finden Sie unter stata-journal.com/sjpdf.html?articlenum=st0223 (siehe insbesondere S.152-3). Wir haben Kubikwurzeln verwendet, um die Visualisierung einer Antwortvariablen zu unterstützen, die von Natur aus
Nick Cox
8
Warum transformieren Sie nicht die ursprünglichen Variablen anstelle der Unterschiede?
Whuber
4
Sie haben das mathematische Problem gelöst. @whubers Vorschlag oder Kubikwurzeln wären meiner Meinung nach immer noch einfacher zu bearbeiten, insbesondere wenn die Konstante rein empirisch ist oder zwischen Variablen variiert. Eine gute Regel für die Auswahl von Transformationen besteht darin, nur Transformationen zu verwenden, die für ähnliche Daten funktionieren, die Sie sich vorstellen können. Somit "funktioniert" für x > -Log(x+4) , würde aber fehlschlagen, wenn Ihr nächster Stapel durch - 5 begrenzt würde .x>-4-5
Nick Cox

Antworten:

14

Da der Logarithmus nur für positive Zahlen definiert ist, können Sie den Logarithmus für negative Werte nicht verwenden. Wenn Sie jedoch eine bessere Verteilung Ihrer Daten erreichen möchten, können Sie die folgende Transformation anwenden.

Angenommen, Sie haben negative Daten verzerrt:

x <- rlnorm(n = 1e2, meanlog = 0, sdlog = 1)
x <- x - 5
plot(density(x))

(-1,1)

z <- (x - min(x)) / (max(x) - min(x)) * 2 - 1
z <- z[-min(z)]
z <- z[-max(z)]
min(z); max(z)

und schließlich den inversen hyperbolischen Tangens anwenden:

t <- atanh(z)
plot(density(t))

Jetzt sehen Ihre Daten ungefähr normal verteilt aus. Dies wird auch als Fisher-Transformation bezeichnet.

stochazesthai
quelle
9
atanh[(x-Mindest(x))/(max(x)-Mindest(x))]
2
@ NickCox Sie haben absolut Recht. Wenn das OP weitere Details zu seinem Problem hinzufügt, könnten wir vielleicht eine alternative Lösung finden!
Stochazesthai
Das innere Argument in meinem ersten Kommentar ist nicht das, was verändert wird, aber der Geist meines Kommentars ist meiner Meinung nach unberührt.
Nick Cox
Lieber @stochazesthai, vielen Dank für Ihre detaillierte Erklärung, aber ich kann Ihren Code nicht auf meine Daten anwenden. Ich habe meine Frage mit einem Link meiner Rohdaten am Ende aktualisiert.
Darwin PC
Die Aussagen z <- z[-max(z)] und z <- z[-min(z)]schrumpfen unangemessen zauf einen einzigen Wert. Auch die allgemeine Funktion atanh(((x - min(x)) / (max(x) - min(x))))erzeugt Inffür die Minimal- und Maximalwerte von x.
Max Ghenis
-1

Um es in eine logarithmische Skala umzuwandeln, suchen Sie zuerst das Logbuch der positiven Zahl und multiplizieren Sie es mit dem Vorzeichen. Der folgende Code sollte dies tun.

transform_to_log_scale <- function(x){
    if(x==0){
        y <- 1
    } else {
        y <- (sign(x)) * (log(abs(x)))
    }
        y 
    }

Anhand des obigen Beispiels können wir die folgende schiefe Verteilung zeichnen

x <- rlnorm(n = 1e2, meanlog = 0, sdlog = 1)
x <- x - 5
plot(density(x))

Bildbeschreibung hier eingeben

Nachdem wir die Transformationsfunktion wie folgt verwendet haben, erhalten wir eine Verteilung, die "normaler" aussieht.

plot(density(sapply(x,FUN=transform_logs_scale)))

Bildbeschreibung hier eingeben

yosemite_k
quelle
3
(1) Die meisten Programmiersprachen (im RLieferumfang enthalten) implementieren die Signum- Funktion (die -1 für negative Zahlen, 1 für positive Zahlen und 0 für Null zurückgibt). Die Verwendung wäre ausdrucksvoller und schneller. (2) Ihr Vorschlag ist schlecht für die Analyse von Daten wie den abgebildeten, da es eine große Diskontinuität bei Null gibt!
Whuber
danke für signum, ich wusste nichts darüber, frage mich, wie es implementiert ist
yosemite_k
3
Es gibt verschiedene Möglichkeiten. In vielen Prozessorarchitekturen wird ein Vorzeichenbit nach vielen Operationen gesetzt, so dass es verwendet werden kann. In der Gleitkommadarstellung nach IEEE mit doppelter Genauigkeit kann das Vorzeichen durch Prüfen eines einzelnen Bits (plus eines weiteren Schnelltests für eine wahre Null) ermittelt werden. In Pipeline-Architekturen mit prädiktiver Verzweigung usw. ist es normalerweise viel effizienter, wenn überhaupt nicht verzweigt wird, weshalb die integrierte Version von signum verwendet wird ein erheblicher Rechengewinn sein kann. Übrigens einstellen y <- 1wannx=0sieht willkürlich aus - es könnte wirklich eine statistische Analyse vermasseln.
Whuber