79

我正在尝试在 R 中生成一个直方图,其中 y 为对数刻度。目前我做:

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工作,但我没有得到任何底轴。

4

7 回答 7

68

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

至于对数轴问题,如果您不想转换 x 轴,请不要使用“x”:

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

让你在 log-y 尺度上得到酒吧——外观和感觉仍然有点不同,但可能可以调整。

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

于 2009-08-07T15:14:13.183 回答
53

另一种选择是使用 package ggplot2

ggplot(mydata, aes(x = V3)) + geom_histogram() + scale_x_log10()
于 2009-08-09T11:50:11.890 回答
11

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

于 2009-08-10T23:55:52.537 回答
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 轴标签。

于 2011-04-10T04:56:47.000 回答
9

在不制作图表的情况下运行 hist() 函数,对计数进行对数转换,然后绘制图形。

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

它应该看起来就像常规直方图,但 y 轴将是 log2 频率。

于 2013-07-18T15:11:33.467 回答
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)
}

读者练习:不幸的是,并非所有适用于 hist 的东西都适用于 myhist。不过,这应该可以通过更多的努力来解决。

于 2011-12-02T13:15:09.780 回答
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 一起使用

于 2017-09-30T22:07:45.490 回答