[R] Help resolving issues with generating a chi-squared density plot from scratch
Rolf Turner
r.turner at auckland.ac.nz
Mon Mar 10 08:52:34 CET 2014
I am far too lazy to go through all your rather complicated code, but my
basic impression is that you are re-inventing quite a few wheels.
Just to get a plot of the density function you can simply do, e.g.:
plot(function(x){dchisq(x,1)},0,qchisq(0.999,1))
I can't see why you are fooling about with the ylim values; just let the
plot() function choose ylim.
As to why you can't get things to work when df=1 ... well don't try to
set the upper y limit equal to infinity! You have a finite plotting
region, after all.
I have no idea what you mean by "The y-axis is numbered only
relatively"; this makes no sense at all. What *do* you want? The
y-axis labelling that you get will be/is the appropriate labelling.
The arrows will go where you tell them to go, so if they are "going
diagonal" you are telling them to go diagonal.
cheers,
Rolf Turner
On 10/03/14 13:30, Levi Robinson wrote:
> I wrote the code to graph a chi-squared density function, shade the
> percentile, and point to the CV, but it has a few issues I can't seem to
> resolve
>
> 1. It won't work at all for DF = 1 due to ylim going to infinity, but I
> haven't been able to resolve this still after hours of trying.
> 2) The y-axis is numbered only relatively; I'd prefer they were the actual
> prob densities, but again, I fiddled with a few things, but it just
> wouldn't get me what I wanted.
> 3) For low degrees of freedom and higher percentiles, the arrow pointing to
> CV seems to end up going diagonal instead of straight down
>
> Here's the code below and here's the URL for R fiddle for the code which
> might make it easier to fix:
> http://www.r-fiddle.org/#/fiddle?id=ChFi0dyJ&version=4
>
>
> chi.dens = function(x = NULL, df = NULL, cv = NULL) {
>
> # x = percentile/quantile
> # df = degrees of freedom
> # cv = critical value
>
> if(x>1 ||x<0) stop("Percentile must be between 0 and 1") #
> Error-handling
>
>
> qend = qchisq(x, df)
> perc = x
>
> qt0=qchisq(0.5, df) # Defining for arrows later
> dy0=dchisq(0.45, df) # Defining for arrows later
>
> xrange = qchisq (0.999, df)
> x = seq(0, xrange)
> y = dchisq(x, df)
> yheight = max(dchisq(x, df))
>
> # Creating plot
> plot(x,y,type = "l", ylim=c(0,yheight),axes=FALSE)
>
> title( "Chi-squared Density Curve with")
> mtext(bquote(paste("DF = ", .(df), " and Percentile = ", .(perc))),
> side = 3, line = 0) # Input information
>
> # Shading left tail-region
>
> qt = signif(qend,5)
> x0=seq(0, qt)
> y0=dchisq(x0, df)
> polygon(c(0, x0, qt), c(0, y0, 0), col = "lightblue")
> xtks=signif(seq(0,xrange,length=10),3)
> axis(1, pos=0, at=xtks, labels=xtks)
> y.unit=max(dchisq(x, df))/5
> y.pos=seq(0,5*y.unit, length=5)
> y.lab=c(0, 1, 2, 3, 4) # Y axis numbers only reflect relative
> densities to each other.
> axis(2,pos=0, at=y.pos, labels=y.lab) # set up y-axis
>
> # "Normal" CV less than the 99.9 Percentile:
>
> if(qt <= xrange){
> if(length(cv)==0) text(0.75*xrange,3*y.unit, bquote(paste("CV = ",
> .(qend))), cex=1.2, col = "red",adj=0.5)
> #
> if(length(perc)==1) text(0.35*xrange,3*y.unit, paste("Area = ",
> perc), cex=1.2, col="darkblue", adj=0.5)
> if(perc>0.5){
> arrows(0.35*xrange, 2.5*y.unit, qt0, 0.3*dy0, length=0.1,
> angle=20) # pointing to the shaded region
> }
> if(perc<=0.5){
> arrows(0.35*xrange, 2.5*y.unit, qt/2, 0.3*dy0, length=0.1,
> angle=20) # pointing to the shaded region
> }
> arrows(0.75*xrange, 2.5*y.unit, qt, 0, length=0.1, angle=20)
> points(qt,0,pch=17, col="red")
> }
>
> # When CV is greater than the 99.9 Percentile:
>
> if(qt > xrange){
>
> print("CV may be too far to the right to be shown on graph due to the
> high percentile")
>
> if(length(cv)==0) text(0.75*xrange,3*y.unit, bquote(paste("CV = ",
> .(qend))), cex=1.2, col = "red",adj=0.5)
>
> if(length(perc)==1) text(0.35*xrange,3*y.unit, paste("Area = ",
> perc), cex=1.2, col="darkblue", adj=0.5)
> if(perc>0.5){
> arrows(0.35*xrange, 2.5*y.unit, qt0, 0.3*dy0, length=0.1,
> angle=20) # pointing to the shaded region
> }
> if(perc<=0.5){
> arrows(0.35*xrange, 2.5*y.unit, qt/2, 0.3*dy0, length=0.1,
> angle=20) # pointing to the shaded region
> }
> arrows(0.75*xrange, 2.5*y.unit, qt, 0, length=0.1, angle=20)
> points(qt,0,pch=17, col="red")
> }
>
> }
More information about the R-help
mailing list