Подтвердить что ты не робот

Как масштабировать/преобразовывать графики:: plot() оси с любым преобразованием, а не только логарифмическим (для графиков Вейбулла)?

Я создаю пакет R для отображения графиков Вейбулла (используя graphics::plot) в R. Сюжет имеет логарифмированную ось X и преобразованную в Вейбуле ось Y (из-за отсутствия лучшего описания). Таким образом, двухпараметрическое распределение Вейбулла может быть представлено как прямая линия на этом графике.

Логарифмическое преобразование оси x так же просто, как добавление параметра log="x" к plot() или curve(). Как я могу обеспечить преобразование оси y элегантным способом, так что все графические графики будут работать на моем преобразованном по оси графике? Чтобы продемонстрировать, что мне нужно, запустите следующий пример кода:

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

Сначала пример распределения Вейбулла с beta=2 и eta=1000 на регулярном, нетрансформированном графике:

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

plot1

Этот график бесполезен для анализа Вейбулла. Вот мое реализованное в настоящее время решение, которое преобразует данные с помощью функции F0inv() и изменяет ось y графика. Обратите внимание, что я должен использовать F0inv() для всех связанных с осью y данных.

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

Это работает, но это не очень удобно: когда пользователь хочет добавлять аннотации, всегда нужно использовать F0inv():

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

Я обнаружил, что вы можете решить проблему с помощью ggplot2 и масштабирования, но я не хочу менять графический пакет, если это абсолютно необходимо, так как требуется переписать много другого кода.

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

Я думаю, что если бы я мог динамически заменить код для применения логарифмического преобразования с моей собственной, моя проблема была бы решена.

Я попытался найти больше информации по Googling "Преобразование оси R", "R-координаты пользователя", "Масштабирование оси R" без полезных результатов. Почти все, что я нашел, касается логарифмических масштабов.

Я попытался изучить plot(), как работает параметр log="x", но соответствующий код для plot.window написан на C - не самая сильная точка.

4b9b3361

Ответ 1

Хотя это не представляется возможным в базовой графике, вы можете сделать эту функцию так, как вы хотите, чтобы ее можно было просто назвать:

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)