2010-10-05 15 views
15

Tengo datos que se centran principalmente en un rango pequeño (1-10) pero hay un número significativo de puntos (por ejemplo, 10%) que están en (10-1000). Me gustaría trazar un histograma para esta información que se centrará en (1-10) pero también mostrará los datos (10-1000). Algo así como una escala logarítmica para el histograma.¿Cómo puedo trazar un histograma de datos de cola larga usando R?

Sí, sé que esto no significa que todas las bandejas son de igual tamaño

Un simple hist(x) da alt text mientras 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))) da alt text

ninguno de los cuales es lo que quiero.

actualización siguiendo las respuestas aquí ahora produzco algo que es casi exactamente lo que quiero (fui con una trama continua en lugar de barras de histograma):

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] 

alt text el único problema es que me gustaría hacer coincidir entre la escala y las barras reales trazadas. Hay dos opciones para hacerlo: la una es simplemente usar los márgenes reales de las barras trazadas (¿cómo?) Y luego obtener etiquetas "feas" de eje x como 1.1754,1.2985, etc. La otra, que prefiero, es controlar el real se usan márgenes de contenedores para que coincidan con los descansos.

+0

@Marek mi pregunta para registrar el eje x (o similar), no los valores (eje y) –

+0

@David Mi mal. Rollback;) – Marek

+0

posible duplicado de: http://stackoverflow.com/questions/1245273/histogram-with-logarithmic-scale –

Respuesta

7

El uso de ggplot2 parece ser la opción más fácil.Si desea más control sobre sus ejes y se rompe, se puede hacer algo como lo siguiente:

EDIT: nuevo código proporcionado

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) 

Esto es lo más cerca que puedo llegar a la ggplot2. Poner el fondo gris no es tan sencillo, pero posible si defines un rectángulo con el tamaño de la pantalla de trazado y colocas el fondo como gris.

Compruebe todas las funciones que utilicé, y también ?par. Te permitirá construir tus propios gráficos. Espero que esto ayude.

alt text

+0

breaks define dónde colocar los ticks y las etiquetas, major define dónde colocas las líneas verticales principales. Con un código adicional, puedes agregar ticks y líneas donde quieras. Un eje de comando adicional() con labels = NA el truco, supongo. –

+0

+1 gracias Joris por toda la ayuda! –

9

Los histogramas de escala de registro son más fáciles con ggplot que con gráficos base. Pruebe algo como

library(ggplot2) 
dfr <- data.frame(x = rlnorm(100, sdlog = 3)) 
ggplot(dfr, aes(x)) + geom_histogram() + scale_x_log10() 

Si estás desesperado por gráficos de base, es necesario trazar un histograma log-escala sin ejes, a continuación, añadir manualmente los ejes después.

h <- hist(log10(dfr$x), axes = FALSE) 
Axis(side = 2) 
Axis(at = h$breaks, labels = 10^h$breaks, side = 1) 

Para completar, la solución de celosía sería

library(lattice) 
histogram(~x, dfr, scales = list(x = list(log = TRUE))) 

una explicación de por qué los valores de registro se necesita en el caso base:

Si traza los datos sin registro -transformación, entonces la mayoría de los datos se agrupan en barras a la izquierda.

hist(dfr$x) 

La función hist ignora el argumento log (debido a que interfiere con el cálculo de las pausas), por lo que esto no funciona.

hist(dfr$x, log = "y") 

Tampoco lo hace.

par(xlog = TRUE) 
hist(dfr$x) 

Eso significa que tenemos que entrar transformar los datos antes de sacar la trama.

hist(log10(dfr$x)) 

Desafortunadamente, esto ensucia los ejes, lo que nos lleva a la solución anterior.

+0

Como menciona Joris, en el ajuste del caso base 'xaxt =" n "' es más limpio que 'axes = FALSE', ya que no necesita crear manualmente el eje y. –

+0

No entiendo el ejemplo de gráficos base - ¿toma el registro de los valores ('log10 (dfr $ x)')? ¿Por qué? –

+0

también, consulte la actualización re la buena solución ggplot2 suya (+1) –

1

Un gráfico dinámico también ayudaría en esta parcela. Utilizar el paquete de manipulate rstudio hacer una dinámica varió histograma:

library(manipulate) 
data_distribution <- table(data) 
manipulate(barplot(data_dist[x:y]), x = slider(1,length(data_dist)), y = slider(10, length(data_dist))) 

Entonces usted será capaz de utilizar controles deslizantes para ver la distribución especialmente en un intervalo seleccionado de forma dinámica como esta: enter image description here

Cuestiones relacionadas