2009-08-07 4 views
64

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

+0

Относящиеся старше вопрос: [Сделать ось у логарифмической гистограммы используя R] (https://stackoverflow.com/questions/7828248/make-y-axis-logarithmic-in-histogram-using-r) – smci

ответ

52

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

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

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

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

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

+0

Отлично! Как изменить ось на нижней части? Вместо того, чтобы показывать 1, 2, 3, 4, 5, 6, я хотел бы показать 0 <= 1, 1 <= 2 и т. Д. – Weegee

+3

Подавление оси в графике() и явный вызов оси() «где» и «что» позволяет вам это сделать. –

33

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

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

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

9

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

2

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

4

Запустите функцию hist(), не создавая график, log-transform count и рисуйте рисунок.

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

Он должен быть похож на обычную гистограмму, но ось y будет равна log2.

+0

Чтобы предотвратить -Если вам нужно будет использовать следующее: 'hist.data $ counts [hist.data $ counts> 0] <- log (hist.data $ counts [hist.data $ counts> 0], 2) ' – kory

1

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