Como transformar valores negativos em logaritmos?

12

Gostaria de saber como transformar valores negativos Log(), pois tenho dados heterocedásticos. Eu li que ele funciona com a fórmula, Log(x+1)mas isso não funciona com meu banco de dados e continuo recebendo NaNs como resultado. Por exemplo, recebo esta mensagem de aviso (não coloquei meu banco de dados completo porque acho que com um dos meus valores negativos é suficiente para mostrar um exemplo):

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

desde já, obrigado

ATUALIZAR:

Aqui está um histograma dos meus dados. Estou trabalhando com séries temporais paleontológicas de medições químicas. Por exemplo, a diferença entre variáveis ​​como Ca e Zn é muito grande, então preciso de algum tipo de padronização de dados, por isso estou testando a log()função. insira a descrição da imagem aqui

Estes são meus dados brutos

Darwin PC
fonte
2
O logaritmo é definido apenas para números positivos e geralmente é usado como uma transformação estatística em dados positivos, para que um modelo preserve essa positividade. A log(x+1)vontade de transformação é definida apenas para x > -1, como então x + 1é positiva. Seria bom saber seu motivo para querer fazer logon e transformar seus dados.
Matthew Drury
3
Conte-nos mais sobre os dados, incluindo faixa, média, frequências de valores negativos, zero e positivos. Pode ser que um modelo linear generalizado com link de log faça mais sentido para os dados, desde que seja razoável pensar que a resposta média seja positiva. Pode ser que você não deva estar se transformando.
Nick Cox
6
Obrigado por adicionar detalhes. Para esses dados, 0 tem um significado (igualdade!) Que deve ser respeitado, de fato preservado . Por essa e outras razões, eu usaria raízes de cubo. Na prática, você precisará de algumas variações sign(x) * (abs(x))^(1/3), os detalhes dependendo da sintaxe do software. Para obter mais informações sobre raízes de cubos, consulte, por exemplo, stata-journal.com/sjpdf.html?articlenum=st0223 (consulte esp. Pp.152-3). Utilizamos raízes de cubo para ajudar na visualização de uma variável de resposta de natureza
Nick Cox
8
Por que você não está transformando as variáveis originais em vez das diferenças?
whuber
4
Você resolveu o problema matemático. A sugestão de @ whuber ou as raízes do cubo ainda seriam, acho, mais fáceis de trabalhar, especialmente se a constante for puramente empírica ou variar entre variáveis. Uma boa regra para a escolha de transformações é apenas usar transformações que funcionem para dados semelhantes que você possa imaginar. Assim, o "funciona" para x > - 4, mas falharia se o próximo lote fosse limitado por - 5registro(x+4)x>-4-5 ..
Nick Cox

Respostas:

14

Como o logaritmo é definido apenas para números positivos, você não pode usar o logaritmo de valores negativos. No entanto, se você deseja obter uma melhor distribuição para seus dados, pode aplicar a transformação a seguir.

Suponha que você tenha inclinado dados negativos:

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

então você pode aplicar uma primeira transformação para fazer com que seus dados se encontrem (-1,1)

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

e, finalmente, aplique a tangente hiperbólica inversa:

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

Agora, seus dados parecem distribuídos aproximadamente normalmente. Isso também é chamado de transformação de Fisher.

stochazesthai
fonte
9
atanh[(x-min(x))/(max(x)-min(x))]
2
@NickCox Você está absolutamente certo. Talvez se o OP adicionar mais detalhes sobre o problema dele, poderíamos descobrir uma solução alternativa!
precisa saber é o seguinte
O argumento interno do meu primeiro comentário não é o que está sendo transformado, mas acho que o espírito do meu comentário não é afetado.
Nick Cox
Caro @stochazesthai, obrigado por sua explicação detalhada, mas não posso aplicar seu código aos meus dados. Atualizei minha pergunta com um link dos meus dados brutos no final.
Darwin PC
As declarações z <- z[-max(z)]e se reduzem z <- z[-min(z)]inadequadamente za um único valor. Além disso, a função geral atanh(((x - min(x)) / (max(x) - min(x))))produz Infpara os valores mínimo e máximo de x.
precisa saber é o seguinte
-1

Para transformá-lo em uma escala de log, primeiro encontre o log do número positivo e depois multiplique-o por seu sinal; o código a seguir deve fazer isso.

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

Usando o exemplo acima, podemos plotar a seguinte distribuição distorcida

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

insira a descrição da imagem aqui

Depois de usar a função de transformação da seguinte forma, obtemos uma distribuição que parece mais 'normal'

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

insira a descrição da imagem aqui

yosemite_k
fonte
3
(1) A maioria das linguagens de programação ( Rincluídas) implementa a função signum (que retorna -1 para números negativos, 1 para números positivos e 0 para zero). Usá-lo seria mais expressivo e mais rápido. (2) Sua proposta é ruim para analisar dados como os ilustrados, porque possui uma enorme descontinuidade em zero!
whuber
obrigado por signum, eu não sabia sobre isso, maravilha como ele é implementado
yosemite_k
3
y <- 1x=0 0