具有对数刻度和自定义间隔的直方图


79

我正在尝试用R的对数刻度生成R的直方图。目前,我正在:

hist(mydata$V3, breaks=c(0,1,2,3,4,5,25))

这给了我一个直方图,但是0到1之间的密度是如此之大(相差一百万左右),以至于您几乎无法分辨出其他任何条形。

然后我尝试做:

mydata_hist <- hist(mydata$V3, breaks=c(0,1,2,3,4,5,25), plot=FALSE)
plot(rpd_hist$counts, log="xy", pch=20, col="blue")

它为我提供了所需的内容,但底部显示的是值1-6,而不是0、1、2、3、4、5、25。它还将数据显示为点而不是条。barplot可以,但是我没有任何底轴。


相关的较早的问题:使用R
smci

Answers:


65

直方图是穷人的密度估计值。请注意,在hist()使用默认参数的调用中,您获得的频率不是概率,,prob=TRUE如果需要概率则添加 到调用中。

至于对数轴问题,如果不希望对x轴进行转换,请不要使用'x':

plot(mydata_hist$count, log="y", type='h', lwd=10, lend=2)

使您的柱数达到对数级-外观仍然有些不同,但可以进行调整。

最后,您还 hist(log(x), ...) 可以获取数据日志的直方图。


优秀的!但是,如何修改底部的轴?而不是表示1,2,3,4,5,6,I想显示0 <= 1,1 <= 2,等等
Weegee的

3
抑制plot()中的轴,并显式调用axis(),从而给出“ where”和“ what”即可。
Dirk Eddelbuettel 09年

53

另一种选择是使用包ggplot2

ggplot(mydata, aes(x = V3)) + geom_histogram() + scale_x_log10()

这是一个很好的答案,可以自动执行很多细节,以后可以随时对其进行调整。谢谢!
太阳蜜蜂

10

从您的问题尚不清楚,您是想要记录x轴还是记录y轴。使用条形图时,记录的y轴不是一个好主意,因为它们固定在零处,在记录时变为负无穷大。您可以通过使用频率多边形或密度图来解决此问题。


10

德克的答案是一个很好的答案。如果您想要外观像hist产生的效果,也可以尝试以下操作:

buckets <- c(0,1,2,3,4,5,25)
mydata_hist <- hist(mydata$V3, breaks=buckets, plot=FALSE)
bp <- barplot(mydata_hist$count, log="y", col="white", names.arg=buckets)
text(bp, mydata_hist$counts, labels=mydata_hist$counts, pos=1)

最后一行是可选的,它在每个栏的顶部下方添加值标签。这对于对数刻度图很有用,但也可以省略。

我还传递mainxlabylab参数来提供绘图标题,x轴标签和y轴标签。


8

运行hist()函数而不制作图形,对数进行对数转换,然后绘制图形。

hist.data = hist(my.data, plot=F)
hist.data$counts = log(hist.data$counts, 2)
plot(hist.data)

它的外观应类似于常规直方图,但y轴将为log2 Frequency。


3
为防止-Inf,您必须使用以下代码: hist.data$counts[hist.data$counts>0] <- log(hist.data$counts[hist.data$counts>0], 2)
kory

3

我整理了一个函数,它在默认情况下的行为与hist相同,但是接受log参数。它使用了其他海报的一些技巧,但又增加了一些技巧。hist(x)myhist(x)外观是相同的。

原始问题将通过以下方式解决:

myhist(mydata$V3, breaks=c(0,1,2,3,4,5,25), log="xy")

功能:

myhist <- function(x, ..., breaks="Sturges",
                   main = paste("Histogram of", xname),
                   xlab = xname,
                   ylab = "Frequency") {
  xname = paste(deparse(substitute(x), 500), collapse="\n")
  h = hist(x, breaks=breaks, plot=FALSE)
  plot(h$breaks, c(NA,h$counts), type='S', main=main,
       xlab=xlab, ylab=ylab, axes=FALSE, ...)
  axis(1)
  axis(2)
  lines(h$breaks, c(h$counts,NA), type='s')
  lines(h$breaks, c(NA,h$counts), type='h')
  lines(h$breaks, c(h$counts,NA), type='h')
  lines(h$breaks, rep(0,length(h$breaks)), type='S')
  invisible(h)
}

读者练习:不幸的是,并非所有与历史有关的东西都与myhist兼容。不过,应该可以更轻松地解决此问题。


3

这是一个漂亮的ggplot2解决方案:

library(ggplot2)
library(scales)  # makes pretty labels on the x-axis

breaks=c(0,1,2,3,4,5,25)

ggplot(mydata,aes(x = V3)) + 
  geom_histogram(breaks = log10(breaks)) + 
  scale_x_log10(
    breaks = breaks,
    labels = scales::trans_format("log10", scales::math_format(10^.x))
  )

请注意,要在geom_histogram中设置中断,必须将其转换为与scale_x_log10一起使用

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.