2009-08-07 38 views
64

Estoy tratando de generar un histograma en R con una escala logarítmica para y. Actualmente hago:Histograma con escala logarítmica y saltos personalizados

hist(mydata$V3, breaks=c(0,1,2,3,4,5,25)) 

Esto me da un histograma, pero la densidad entre 0 y 1 es tan grande (alrededor de un millón de diferencia valores) que apenas se puede hacer ninguna de las otras barras.

entonces he intentado hacer:

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") 

Me da sorta lo que quiero, pero el fondo de mí los valores 1-6 en lugar de 0, 1, 2, 3, 4, 5 muestra, 25. También muestra los datos como puntos en lugar de barras. barplot funciona pero no tengo ningún eje inferior.

+0

relacionados pregunta más: [Hacer logarítmica eje y en el histograma usando R] (https://stackoverflow.com/questions/7828248/make-y-axis-logarithmic-in-histogram-using-r) – smci

Respuesta

52

Un histograma es una estimación de la densidad de un hombre pobre. Tenga en cuenta que en su llamada al hist() usando argumentos predeterminados, obtiene frecuencias no probabilidades - agregue ,prob=TRUE a la llamada si desea probabilidades.

En cuanto al problema eje del tronco, no utilice 'x' si no desea que el eje x transformó:

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

le consigue bares en una escala logarítmica y - la Mira- y-feel aún es un poco diferente, pero probablemente pueda ser ajustado.

Por último, también puede hacer hist(log(x), ...) para obtener un histograma del registro de sus datos.

+0

¡Excelente! ¿Cómo puedo modificar el eje en la parte inferior? En lugar de mostrar 1, 2, 3, 4, 5, 6, me gustaría mostrar 0 <= 1, 1 <= 2, etc. – Weegee

+3

Suprimir el eje en la gráfica() y llamar explícitamente al eje() dando la 'dónde' y 'qué' te permite hacer eso. –

33

Otra opción sería usar el paquete ggplot2.

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

No está del todo claro si desea un eje x registrado o un eje y registrado. Un eje y registrado no es una buena idea cuando se utilizan barras porque están ancladas en cero, que se convierte en infinito negativo cuando se registran. Puede solucionar este problema utilizando un polígono de frecuencia o un diagrama de densidad.

9

La respuesta de Dirk es genial. Si desea una apariencia semejante a lo que produce hist, también puede probar esto:

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) 

La última línea es opcional, se añade etiquetas de valor justo debajo de la parte superior de cada barra. Esto puede ser útil para gráficos de escala logarítmica, pero también se puede omitir.

También paso main, xlab y parámetros para proporcionar un título de la gráfica, la etiqueta del eje xy la etiqueta del eje y.

2

He creado una función que se comporta de forma idéntica a hist en el caso predeterminado, pero acepta el argumento de registro. Utiliza varios trucos de otros carteles, pero agrega algunos propios. hist(x) y myhist(x) parecen idénticos.

El problema original se resolverían con:

myhist(mydata$V3, breaks=c(0,1,2,3,4,5,25), log="xy") 

La función:

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) 
} 

ejercicio para el lector: Por desgracia, no todo lo que trabaja con hist trabaja con myhist tal como está. Sin embargo, eso debería ser reparable con un poco más de esfuerzo.

4

Ejecute la función hist() sin hacer un gráfico, log-transform los recuentos, y luego dibuje la figura.

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

Debe tener un aspecto como el histograma regular, pero el eje y será log2 frecuencia.

+0

Para evitar: si tiene que usar lo siguiente: 'hist.data $ counts [hist.data $ counts> 0] <- log (hist.data $ counts [hist.data $ counts> 0], 2) ' – kory

1

he aquí una solución ggplot2 bastante:

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)) 
) 

Tenga en cuenta que para establecer las roturas en geom_histogram, tuvieron que ser transformados para trabajar con scale_x_log10

Cuestiones relacionadas