use*_*135 13 plot r ggplot2 weibull
我正在构建一个R包来显示R中的Weibull图(使用graphics::plot
).该图具有对数变换的x轴和Weibull变换的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))
Run Code Online (Sandbox Code Playgroud)
首先用威布尔分布的例子beta=2
,并eta=1000
定期,未转换的情节:
## untransformed axes ##
curve(weibull ,xlim=c(100,1e4),ylim=c(0.01,0.99))
abline(h=ticks,col="lightgray")
Run Code Online (Sandbox Code Playgroud)
这个图对Weibull分析没用.这是我目前实现的解决方案,它使用函数转换数据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")
Run Code Online (Sandbox Code Playgroud)
这可行,但这不是非常用户友好:当用户想要添加注释时,必须始终使用F0inv()
:
text(300,F0inv(0.4),"at 40%")
Run Code Online (Sandbox Code Playgroud)
我发现你可以使用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")
Run Code Online (Sandbox Code Playgroud)
我认为如果我能动态地替换用我自己应用对数变换的代码,我的问题就会得到解决.
我试图通过谷歌搜索"R轴转换","R用户坐标","R轴缩放"找到更多信息而没有有用的结果.我发现的几乎所有东西都处理对数尺度.
我试着看看参数plot()
是如何log="x"
工作的,但是相关的代码plot.window
是用C语言编写的 - 而不是我最强的观点.
虽然在基础图形中似乎不可能,但您可以使该函数执行您想要的操作,以便您可以更简单地调用它:
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)
Run Code Online (Sandbox Code Playgroud)