【问题标题】:How can I plot a histogram of a long-tailed data using R?如何使用 R 绘制长尾数据的直方图?
【发布时间】:2011-04-21 05:12:20
【问题描述】:

我的数据大多集中在一个小范围 (1-10) 中,但有大量的点 (例如 10%) 在 (10-1000) 中。我想为这些数据绘制一个直方图,该直方图将集中在 (1-10) 上,但也会显示 (10-1000) 数据。类似于直方图的对数刻度。

是的,我知道这意味着并非所有垃圾箱的大小都相同

一个简单的hist(x) 给出 而hist(x,breaks=c(0,1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2,3,4,5,7.5,10,15,20,50,100,200,500,1000,10000))) 给出

这些都不是我想要的。

更新 按照这里的答案,我现在产生的东西几乎正是我想要的(我使用连续图而不是条形直方图):

breaks <- c(0,1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2,4,8)
ggplot(t,aes(x)) + geom_histogram(colour="darkblue", size=1, fill="blue") + scale_x_log10('true size/predicted size', breaks = breaks, labels = breaks)![alt text][3]

唯一的问题是我想在比例和绘制的实际条形之间进行匹配。有两种选择:一种是简单地使用绘制条的实际边距(如何?)然后获得“丑陋”的 x 轴标签,如 1.1754、1.2985 等。我更喜欢的另一种是控制实际使用的 bin 边距,以便它们匹配中断。

【问题讨论】:

  • @Marek 我的问题是记录 x 轴(或类似),而不是值(y 轴)
  • @Joris Meys 与 Marek 的评论相同:我正在寻找日志 x 轴,而不是值 (y) 的日志。
  • @David:我的解决方案为您提供了一个表示原始值的 x 轴,但具有对数刻度。我什至保留你定义的休息时间。怎么不是你问的?
  • @David :您的要求并非易事。 ggplot2 在对数刻度上制作直方图时会忽略中断。您可以设置 binwidth,但这是一个值。因此,所有条形图的大小都相同。如果您不希望这种情况发生,请使用基础绘图。

标签: r histogram


【解决方案1】:

使用 ggplot 比使用基本图形更容易绘制对数刻度直方图。尝试类似

library(ggplot2)
dfr <- data.frame(x = rlnorm(100, sdlog = 3))
ggplot(dfr, aes(x)) + geom_histogram() + scale_x_log10()

如果您迫切需要基本图形,则需要绘制一个不带坐标轴的对数刻度直方图,然后手动添加坐标轴。

h <- hist(log10(dfr$x), axes = FALSE) 
Axis(side = 2)
Axis(at = h$breaks, labels = 10^h$breaks, side = 1)

为了完整起见,格子解是

library(lattice)
histogram(~x, dfr, scales = list(x = list(log = TRUE)))

解释为什么在基本情况下需要对数值:

如果您在没有对数转换的情况下绘制数据,则大部分数据都会聚集在左侧的条形中。

hist(dfr$x)

hist 函数忽略了log 参数(因为它会干扰中断的计算),所以这不起作用。

hist(dfr$x, log = "y")

这个也不行。

par(xlog = TRUE)
hist(dfr$x)

这意味着我们需要在绘制绘图之前记录转换数据。

    hist(log10(dfr$x))

不幸的是,这弄乱了坐标轴,这使我们需要解决上述问题。

【讨论】:

  • 正如 Joris 所提到的,在基本情况下,xaxt = "n"axes = FALSE 更干净,因为您不需要手动创建 y 轴。
  • 我不理解基本图形示例 - 您是否记录了值 (log10(dfr$x))?为什么?
  • 另外,请参阅更新。你漂亮的 ggplot2 解决方案(+1)
【解决方案2】:

使用 ggplot2 似乎是最简单的选择。如果您想更好地控制轴和休息时间,可以执行以下操作:

编辑:提供新代码

x <- c(rexp(1000,0.5)+0.5,rexp(100,0.5)*100)

breaks<- c(0,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000,10000)
major <- c(0.1,1,10,100,1000,10000)


H <- hist(log10(x),plot=F)


plot(H$mids,H$counts,type="n",
      xaxt="n",
      xlab="X",ylab="Counts",
      main="Histogram of X",
      bg="lightgrey"
)
abline(v=log10(breaks),col="lightgrey",lty=2)
abline(v=log10(major),col="lightgrey")
abline(h=pretty(H$counts),col="lightgrey")
plot(H,add=T,freq=T,col="blue")
#Position of ticks
at <- log10(breaks)

#Creation X axis
axis(1,at=at,labels=10^at)

这是尽可能接近 ggplot2。将背景设置为灰色并不是那么简单,但如果您使用绘图屏幕的大小定义一个矩形并将背景设置为灰色,则可行。

检查我使用的所有功能,还有?par。它将允许您构建自己的图表。希望这会有所帮助。

【讨论】:

  • breaks 定义了你放置刻度和标签的位置,major 定义了你放置主要垂直线的位置。使用一些额外的代码,您可以在需要的位置添加刻度和线条。我猜一个带有标签=NA的额外命令axis()可以解决问题。
【解决方案3】:

动态图也有助于绘制此图。使用来自 Rstudio 的 manipulate 包做一个动态范围直方图:

library(manipulate)
data_dist <- table(data)
manipulate(barplot(data_dist[x:y]), x = slider(1,length(data_dist)), y = slider(10, length(data_dist)))

然后您将能够使用滑块查看动态选择范围内的特定分布,如下所示:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    相关资源
    最近更新 更多