Гистограмма с логарифмической шкалой и пользовательскими разрывами - PullRequest
71 голосов
/ 07 августа 2009

Я пытаюсь сгенерировать гистограмму в 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 работает, но тогда у меня нет нижней оси.

Ответы [ 7 ]

58 голосов
/ 07 августа 2009

Гистограмма - это оценка плотности бедняков. Обратите внимание, что при вызове hist() с использованием аргументов по умолчанию вы получаете частоты не вероятности - добавьте ,prob=TRUE к вызову, если хотите получить вероятности.

Что касается проблемы логарифмической оси, не используйте 'x', если вы не хотите преобразовывать ось x:

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

дает вам бары в лог-масштабе - внешний вид все еще немного отличается, но, вероятно, может быть изменен.

Наконец, вы также можете сделать hist(log(x), ...), чтобы получить гистограмму журнала ваших данных.

45 голосов
/ 09 августа 2009

Другим вариантом будет использование пакета ggplot2.

ggplot(mydata, aes(x = V3)) + geom_histogram() + scale_x_log10()
10 голосов
/ 10 апреля 2011

Отличный ответ Дирка. Если вы хотите внешний вид, подобный тому, который производит 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)

Последняя строка необязательна, она добавляет метки значений непосредственно под верхней частью каждого столбца. Это может быть полезно для графиков масштаба журнала, но также может быть опущено.

Я также передаю параметры main, xlab и ylab, чтобы предоставить заголовок графика, метку оси x и метку оси y.

10 голосов
/ 11 августа 2009

Из вашего вопроса не совсем понятно, хотите ли вы получить зарегистрированную ось X или зарегистрированную ось Y. Зарегистрированная ось Y не является хорошей идеей при использовании стержней, поскольку они привязаны к нулю, который становится отрицательной бесконечностью при регистрации. Вы можете обойти эту проблему, используя частотный полигон или график плотности.

6 голосов
/ 18 июля 2013

Запустите функцию hist () без построения графика, выполните лог-преобразование счетчиков, а затем нарисуйте рисунок.

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

Он должен выглядеть как обычная гистограмма, но по оси Y будет log2 Frequency.

3 голосов
/ 01 октября 2017

Вот довольно симпатичное решение 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

3 голосов
/ 02 декабря 2011

Я собрал функцию, которая в случае по умолчанию ведет себя так же, как 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 в его нынешнем виде. Это должно быть исправлено с небольшим усилием, хотя.

...