使用R在对数刻度上转换变量密度

时间:2012-12-23 10:46:39

标签: r scale logarithm

我想绘制范围如下的变量密度:

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

密度的线性图导致在[0,1000]范围内的高柱,具有朝向正无穷大和负无穷大的两个非常长的尾部。 因此,我想将变量转换为对数刻度,以便我可以看到平均值周围发生了什么。 例如,我想的是:

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

导致:

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

这个问题的主要问题是它不包含0值。 当然,我可以使用0将所有值从values[values>=0]+1移开,但这会在数据中引入一些失真。

将此变量转换为对数刻度的可接受且科学可靠的方法是什么?

3 个答案:

答案 0 :(得分:4)

你拥有的基本上是@James所建议的。这对于(-1,1)中的值是有问题的,特别是那些接近原点的值:

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

enter image description here

这样的事情可能有所帮助:

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

这是连续的。可以通过使用间隔(-1 / log(10),1 / log(10))来强制C ^ 1,这是通过求解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 :(得分:3)

除了转换之外,您还可以操纵直方图本身来了解您的数据。这为您提供了这样的优势:图表本身可以读取,您可以立即了解中心的分布情况。假设我们模拟以下数据:

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 

然后你有几种不同的方法。最容易看到数据中心的内容,只是绘制数据的中心。在这种情况下,假设我对第一个和第三个四分位数之间发生的事情感兴趣,我可以绘制:

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

如果您还想计算尾部,您可以转换数据以折叠尾部并更改轴以反映这一点,如下所示:

  1. 您将感兴趣范围之外的所有值分配到该范围之外的值
  2. 您绘制直方图,将一个箱子中的所有极值分类
  3. 使用正确的标签构建X轴
  4. 您使用包axis.break()中的plotrix在X轴上添加一些中断,表示不连续的轴
  5. 为此你可以使用类似下面的代码:

     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)
    

    这会给你:

    enter image description here

    请注意,您可以通过将freq=TRUE添加到hist()功能来获得原始频率。

答案 2 :(得分:1)

我将此添加为另一个答案,因为虽然这个想法很相似,但映射根本不同。

当在对数比例图中包含小值(&lt; 1)时,通常是情节log(1 + .)而不是log(.)

反思原点,我们得到一些有用的东西:

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

应该很清楚,函数是平滑的,因为0的方向导数也会被反映出来。 enter image description here

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