Гістограма з логарифмічною шкалою та спеціальними розривами


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працює, але тоді я не отримую жодної нижньої осі.


Відповіді:


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, я хотів би показати 0 <= 1, 1 <= 2 тощо
Weegee

3
Придушення осі в plot () та явний виклик оси (), даючи 'де' і 'що' дозволяє це зробити.
Dirk Eddelbuettel

53

Іншим варіантом буде використання пакету ggplot2.

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

Це дуже гарна відповідь і автоматизує багато деталей, які завжди можна налаштувати пізніше. Дякую!
Sun Bee

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)

Останній рядок не є обов’язковим, він додає мітки значень безпосередньо вгорі кожного рядка. Це може бути корисно для графіків масштабу журналу, але також може бути опущено.

Я також пройти main, xlabі ylabпараметри , щоб забезпечити назву ділянки, підпис осі Х, і мітку у-осі.


8

Запустіть функцію hist (), не створюючи графік, перетворіть журнал підрахунку, а потім намалюйте рисунок.

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

Вона повинна виглядати так само, як звичайна гістограма, але вісь y буде log2 Частота.


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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.