2013-04-08 12 views
13

buduję pakiet R, aby wyświetlić wykresy Weibulla (używając graphics::plot) w R. Działka posiada logarytmicznej x -działający i Weibulla przekształconych y -działający (dla braku lepszego opisu). Dwuparametrowy rozkład Weibulla może zatem być przedstawiony jako linia prosta na tym wykresie.Jak skalować/przekształcać osie grafiki :: działka() z dowolną transformacją, a nie tylko logarytmiczną (dla działek Weibulla)?

logarytmiczna transformacja x -osiowy jest proste dodanie parametru log="x" do plot() lub curve(). W jaki sposób mogę dostarczyć transformację osiową w elegancki sposób, aby wszystkie wykresy związane z grafiką działały na moim wykresie przekształconym w osi? W celu wykazania, co muszę, uruchomić kod poniższym przykładzie:

## initialisation ## 
beta  <- 2;eta <- 1000 
ticks <- c(seq(0.01,0.09,0.01),(1:9)/10,seq(0.91,0.99,0.01)) 
F0inv <- function (p) log(qweibull(p, 1, 1)) 
    # this is the transformation function 
F0  <- function (q) exp(-exp(q)) 
    # this is the inverse of the transformation function 
weibull <- function(x)pweibull(x,beta,eta) 
    # the curve of this function represents the weibull distribution 
    # as a straight line on weibull paper 
weibull2 <- function(x)F0inv(weibull(x)) 

Pierwszy przykład rozkładu Weibulla z beta=2 i eta=1000 w sposób regularny, nietransformowanych działki:

## untransformed axes ## 
curve(weibull ,xlim=c(100,1e4),ylim=c(0.01,0.99)) 
abline(h=ticks,col="lightgray") 

plot1

Ten wykres jest bezużyteczny do analizy Weibulla. Oto moje obecnie zaimplementowane rozwiązanie, które przekształca dane za pomocą funkcji F0inv() i modyfikuje wartość osi wykresu. Zauważ, że muszę używać F0inv() dla wszystkich powiązanych danych.

## transformed axis with F0inv() ## 
curve(weibull2,xlim=c(100,1e4),ylim=F0inv(c(0.01,0.99)),log="x",axes=F) 
axis(1);axis(2,at=F0inv(ticks),labels=ticks) 
abline(h=F0inv(ticks),col="lightgray") 

plot2

To działa, ale to nie jest bardzo przyjazny dla użytkownika: gdy użytkownik chce dodać adnotacje, należy zawsze używać F0inv():

text(300,F0inv(0.4),"at 40%") 

I odkryłem, że możesz osiągnąć rozwiązanie mojego problemu za pomocą ggplot2 i skal, ale nie chcę zmieniać pakietu graficznego, chyba że ab koniecznie konieczne, ponieważ trzeba przepisać wiele innych kodów.

## with ggplot2 and scales ## 
library(ggplot2) 
library(scales) 
weibull_trans <- function()trans_new("weibull", F0inv, F0) 
qplot(c(100,1e4),xlim=c(100,1e4),ylim=c(0.01,0.99), 
    stat="function",geom="line",fun=weibull) + 
    coord_trans(x="log10",y = "weibull") 

plot3

myślę, że gdybym mógł dynamicznie zastąpić kod stosując transformację logarytmiczną z własną rękę, mój problem zostanie rozwiązany.

Próbowałem znaleźć więcej informacji, korzystając z Googling "Transformacja osi R", "R współrzędne użytkownika", "skalowanie osi R" bez użytecznych wyników. Niemal wszystko, co znalazłem, zajmowało się skalami logarytmicznymi.

Próbowałem zajrzeć do plot() pod kątem działania parametru log="x", ale odpowiedni kod dla plot.window został napisany w C - nie w moim najmocniejszym punkcie.

+4

będę zainteresowany, jeśli ktoś przychodzi z lepsze rozwiązanie, ale myślę, że udało ci się znaleźć odpowiednią podstawę; Nie sądzę, że zrobisz coś lepszego niż to - poza 'ggplot2' nie znam żadnego systemu ogólnej transformacji osi. –

+0

Dzięki za poświęcenie czasu na odpowiedź. W międzyczasie doszedłem do tego samego wniosku, wygląda na to, że będę zmuszony użyć ggplot2. – user2257135

Odpowiedz

1

Choć nie wydaje się być możliwe w grafice bazowych, można dokonać tej funkcji, co chcesz zrobić tak, że można go nazwać prościej:

F0inv <- function (p) log(qweibull(p, 1, 1)) 
## this is the transformation function 
F0  <- function (q) exp(-exp(q)) 

weibullplot <- function(eta, beta, 
         ticks=c(seq(0.01,0.09,0.01),(1:9)/10,seq(0.91,0.99,0.01)), 
         ...) { 
    ## the curve of this function represents the weibull distribution 
    ## as a straight line on weibull paper 
    weibull2 <- function(x) 
    F0inv(pweibull(x, beta, eta)) 
    curve(weibull2, xlim=c(100, 1e4), ylim=F0inv(c(0.01, 0.99)), log="x", axes=FALSE) 
    axis(1); 
    axis(2, at=F0inv(ticks), labels=ticks) 
    abline(h=F0inv(ticks),col="lightgray") 
} 

weibullplot(eta=1000, beta=2) 
Powiązane problemy