2009-08-07 21 views
64

Próbuję wygenerować histogram w R ze skalą logarytmiczną dla y. Obecnie robię:Histogram z skalą logarytmiczną i przerwami niestandardowymi

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

To daje mi histogram, ale gęstość od 0 do 1 jest tak wielka (o różnicy mln wartości), że ledwo można dostrzec którykolwiek z pozostałych barach.

Potem próbowałem robić:

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

Daje mi coś w co chcę, ale dolna pokazuje mi wartości 1-6 zamiast 0, 1, 2, 3, 4, 5, 25. Pokazuje także dane jako punkty, a nie pasy. barplot działa, ale nie otrzymuję żadnej dolnej osi.

+0

Podobne starsze pytanie: [Dokonaj oś y logarytmiczny w histogramie za pomocą R] (https://stackoverflow.com/questions/7828248/make-y-axis-logarithmic-in-histogram-using-r) – smci

Odpowiedz

52

Histogram jest oszacowaniem gęstości ubogich człowieka. Zauważ, że w twoim wywołaniu hist() przy użyciu domyślnych argumentów, dostaniesz częstotliwości nie prawdopodobieństwo - dodaj ,prob=TRUE do połączenia, jeśli chcesz prawdopodobieństwa.

Co do problemu osi dziennika, nie używać 'x', jeśli nie chcesz, aby oś x przekształcone:

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

dostaje bary w skali log-y - z patrzenia i czuję się jeszcze trochę inaczej, ale prawdopodobnie można go poprawić.

Wreszcie, można również wykonać hist(log(x), ...), aby uzyskać histogram dziennika danych.

+0

Doskonale! Jak jednak mogę zmienić oś na dole? Zamiast pokazywać 1, 2, 3, 4, 5, 6, chciałbym pokazać 0 <= 1, 1 <= 2, itd. – Weegee

+3

Pomijanie osi na wykresie() i jawne wywoływanie do osi(), podając "gdzie" i "co" pozwala to zrobić. –

33

Inną opcją byłoby użycie pakietu ggplot2.

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

Z twojego pytania nie wynika jednoznacznie, czy chcesz zarejestrować zalogowaną oś X czy zalogować oś Y. Zarejestrowana oś Y nie jest dobrym pomysłem podczas używania prętów, ponieważ są one zakotwiczone w punkcie zerowym, który staje się ujemną nieskończonością po zalogowaniu. Możesz obejść ten problem, używając wieloboku częstotliwości lub wykresu gęstości.

9

Odpowiedź Dirka jest świetna. Jeśli chcesz wygląd jak co hist produkuje, można również spróbować tego:

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) 

Ostatni wiersz jest opcjonalne, dodaje etykiety wartości nieco poniżej górnej części każdego baru. Może to być przydatne w przypadku wykresów skali logarytmicznej, ale można je również pominąć.

Podaj również parametry main, xlab i ylab, aby podać tytuł działki, etykietę osi X i etykietę osi Y.

2

Połączyłem funkcję, która zachowuje się identycznie z histem w domyślnym przypadku, ale akceptuje argument logu. Wykorzystuje kilka sztuczek z innych plakatów, ale dodaje kilka własnych. hist(x) i myhist(x) wyglądają identycznie.

Oryginalny Problem byłby rozwiązany:

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

Funkcja:

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

ćwiczenie dla czytelnika: Niestety, nie wszystko, co działa z hist współpracuje z myhist jak stoi. To powinno być możliwe do naprawy przy odrobinie więcej wysiłku.

4

Uruchom funkcję hist() bez tworzenia wykresu, przekształć logi w liczby, a następnie narysuj rysunek.

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

Powinien wyglądać tak jak zwykły histogram, ale oś Y będzie log2 Częstotliwość.

+0

Aby zapobiec -Należy użyć: 'hist.data $ counts [hist.data $ counts> 0] <- log (hist.data $ counts [hist.data $ counts> 0], 2) ' – kory

1

Oto bardzo rozwiązanie 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)) 
) 

Należy pamiętać, że aby ustawić przerwy w geom_histogram, musieli być przekształcone do pracy z scale_x_log10

Powiązane problemy