如何将负值转换为对数?


12

我想知道如何将负值转换为Log(),因为我有异方差数据。我读到它适用于公式,Log(x+1)但不适用于我的数据库,因此我继续得到NaN。例如,我收到以下警告消息(我没有放入完整的数据库,因为我认为使用负值之一足以显示示例):

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

提前致谢

更新:

这是我的数据的直方图。我正在使用化学测量的古生物学时间序列,例如Ca和Zn之类的变量之间的差异太大,那么我需要某种类型的数据标准化,这就是为什么我要测试log()功能。 在此处输入图片说明

这是我的原始数据


2
对数仅针对正数定义,通常用作对正数据的统计转换,以便模型可以保留此正数。该log(x+1)转型将用于只被定义x > -1,正如当时x + 1是积极的。最好知道您想进行日志记录转换数据的原因。
马修·德鲁里

3
告诉我们更多有关数据的信息,包括范围,平均值,负值,零值和正值的频率。只要合理地认为平均响应为正,则具有对数链接的广义线性模型可能对数据最有意义。可能您根本不应该进行转换。
Nick Cox

6
感谢您添加详细信息。对于此类数据,0具有应被尊重的含义(等于!),实际上是被保留的。由于这个和其他原因,我将使用多维数据集根。实际上,您将需要对进行一些更改sign(x) * (abs(x))^(1/3),具体取决于软件语法。更多关于立方根参见例如stata-journal.com/sjpdf.html?articlenum=st0223(见电除尘器。pp.152-3)。我们使用的立方根的响应可变的可视化的帮助,可以是正的和负的性质.com / nature / journal / v500 / n7464 / full /…
尼克·考克斯

8
为什么不转换原始变量而不是转换变量?
ub

4
您解决了数学问题。我认为,@ whuber的建议或立方根仍然会更容易使用,尤其是当常量纯粹是经验性的或变量之间有所不同时。选择转换的一个好规则是仅使用适用于您可以想象的相似数据的转换。因此 “的作品”为,但如果你的下一个批次被界定会失败 ..x > 4 5log(x+4)x>45
尼克·考克斯

Answers:


14

由于对数仅针对正数定义,因此您不能采用负值的对数。但是,如果您希望获得更好的数据分布,则可以应用以下转换。

假设您歪曲了负面数据:

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)

最后应用反双曲正切值:

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

现在,您的数据看起来大致呈正态分布。这也称为费舍尔变换。


9
您解决了直接的数学问题。但是我认为统计结果的使用者不太可能会轻易想到作为响应量表和建模中,您需要考虑哪种错误结构有意义。该量表对经验的最小值和最大值敏感。atanh[(xmin(x))/(max(x)min(x))]
尼克·考克斯

2
@NickCox你是完全正确的。也许如果OP添加有关他的问题的更多详细信息,我们可以找出替代解决方案!
stochazesthai

我的第一点评论的内在论点不是正在改变的内容,但我认为我的评论的精神不受影响。
Nick Cox

尊敬的@stochazesthai感谢您的详细说明,但我无法将您的代码应用于我的数据。最后,我用原始数据的链接更新了问题。
达尔文PC

该报表z <- z[-max(z)]z <- z[-min(z)]不恰当地收缩z到一个单一的价值。通用函数还会atanh(((x - min(x)) / (max(x) - min(x))))产生Inf的最小值和最大值x
Max Ghenis

-1

要将其转换为对数刻度,请首先找到正数的对数,然后将其乘以它的符号,以下代码应做到这一点。

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

使用以上示例,我们可以绘制以下偏斜分布

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

在此处输入图片说明

在按如下方式使用转换函数后,我们得到一个看起来更“正常”的分布

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

在此处输入图片说明


3
(1)大多数编程语言(R包括在内)都实现了signum函数(对于负数返回-1,对于正数返回1,对于零返回0)。使用它会更具表现力和更快。(2)您的建议对于分析如图所示的数据而言是一个差劲的建议,因为它的零点存在很大的不连续性!
ub

谢谢你的签名,我不知道,不知道它是如何实现的
yosemite_k

3
有多种方法。在许多处理器体系结构中,许多操作后都会设置一个符号位,因此可以使用它。在IEEE双精度浮点表示法中,可以通过检查单个位(再加上另一个对真零的快速测试)来找到符号。在具有预测分支等的流水线架构中,如果可能的话,不分支通常效率更高,这就是为什么使用内置版本的signum可以显着提高计算效率的原因。顺便说一下,设置y <- 1当看起来随心所欲-它可能真的搞砸了统计分析。x=0
ub
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.