Как можно построить гистограмму длиннохвостых данных с помощью R?
У меня есть данные, которые в основном сосредоточены в небольшом диапазоне (1-10), но есть значительное количество точек (например, 10%), которые находятся в (10-1000). Я хотел бы построить гистограмму для этих данных, которая будет сосредоточена на (1-10), но также покажет данные (10-1000). Что-то вроде логарифмической шкалы для гистограммы.
Да, я знаю, это означает, что не все ящики равного размера
Простой hist(x)
дает
в то время как hist(x,breaks=c(0,1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2,3,4,5,7.5,10,15,20,50,100,200,500,1000,10000)))
дает
![alt text]()
ни один из них не является тем, что я хочу.
Обновление
следуя ответам здесь, я сейчас производю то, что почти точно то, что я хочу (я пошел с непрерывным графиком вместо гистограммы):
breaks <- c(0,1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2,4,8)
ggplot(t,aes(x)) + geom_histogram(colour="darkblue", size=1, fill="blue") + scale_x_log10('true size/predicted size', breaks = breaks, labels = breaks)![alt text][3]
единственная проблема заключается в том, что я хотел бы сопоставлять масштаб и фактические графики. Есть два варианта для этого: один просто использует фактические поля на графиках (как?), А затем получает "уродливые" метки оси x, такие как 1.1754,1.2985 и т.д. Другая, что я предпочитаю, - это контролировать фактические полевые поля, чтобы они соответствовали разрывам.
Ответы
Ответ 1
Использование ggplot2 кажется самым простым вариантом. Если вы хотите больше контролировать свои оси и свои перерывы, вы можете сделать что-то вроде следующего:
EDIT: введен новый код
x <- c(rexp(1000,0.5)+0.5,rexp(100,0.5)*100)
breaks<- c(0,0.1,0.2,0.5,1,2,5,10,20,50,100,200,500,1000,10000)
major <- c(0.1,1,10,100,1000,10000)
H <- hist(log10(x),plot=F)
plot(H$mids,H$counts,type="n",
xaxt="n",
xlab="X",ylab="Counts",
main="Histogram of X",
bg="lightgrey"
)
abline(v=log10(breaks),col="lightgrey",lty=2)
abline(v=log10(major),col="lightgrey")
abline(h=pretty(H$counts),col="lightgrey")
plot(H,add=T,freq=T,col="blue")
#Position of ticks
at <- log10(breaks)
#Creation X axis
axis(1,at=at,labels=10^at)
Это как можно ближе к ggplot2. Помещение фона серого не так просто, но выполнимо, если вы определяете прямоугольник с размером экрана вашего экрана и помещаете фон в серый цвет.
Проверьте все функции, которые я использовал, а также ?par
. Это позволит вам создавать собственные графики. Надеюсь, это поможет.
![alt text]()
Ответ 2
Гистограммы в масштабе шкалы проще с ggplot, чем с базовой графикой. Попробуйте что-то вроде
library(ggplot2)
dfr <- data.frame(x = rlnorm(100, sdlog = 3))
ggplot(dfr, aes(x)) + geom_histogram() + scale_x_log10()
Если вы отчаянно нуждаетесь в базовой графике, вам нужно построить гистограмму логарифмической шкалы без осей, а затем вручную добавить оси после.
h <- hist(log10(dfr$x), axes = FALSE)
Axis(side = 2)
Axis(at = h$breaks, labels = 10^h$breaks, side = 1)
Для полноты решение решетки будет
library(lattice)
histogram(~x, dfr, scales = list(x = list(log = TRUE)))
ОБЪЯСНЕНИЕ ПОЧЕМУ ЗНАЧЕНИЕ ЗНАЧЕНИЙ ЛЮДЕЙ В БАЗОВОМ СЛУЧАЕ:
Если вы построите данные без преобразования журнала, то большинство данных сгруппированы в столбцы слева.
hist(dfr$x)
Функция hist
игнорирует аргумент log
(потому что это мешает вычислению разрывов), поэтому это не работает.
hist(dfr$x, log = "y")
Это тоже.
par(xlog = TRUE)
hist(dfr$x)
Это означает, что нам нужно лог преобразовать данные, прежде чем рисовать график.
hist(log10(dfr$x))
К сожалению, это испортит оси, что приводит нас к обходу выше.
Ответ 3
Динамический график также поможет в этом сюжете. Используйте пакет манипулирования из Rstudio для создания динамической гистограммы:
library(manipulate)
data_dist <- table(data)
manipulate(barplot(data_dist[x:y]), x = slider(1,length(data_dist)), y = slider(10, length(data_dist)))
Затем вы сможете использовать ползунки, чтобы увидеть конкретное распределение в динамически выбранном диапазоне, например: ![enter image description here]()