R/MCResultMethods.r

Defines functions MCResult.plot MCResult.calcBias MCResult.calcResponse MCResult.plotDifference MCResult.calcCUSUM MCResult.getRegmethod MCResult.getFitted MCResult.getResiduals MCResult.getData MCResult.getWeights MCResult.getErrorRatio MCResult.getCoefficients MCResult.initialize newMCResult

Documented in MCResult.calcBias MCResult.calcCUSUM MCResult.calcResponse MCResult.getCoefficients MCResult.getData MCResult.getErrorRatio MCResult.getFitted MCResult.getRegmethod MCResult.getResiduals MCResult.getWeights MCResult.initialize MCResult.plot MCResult.plotDifference newMCResult

###############################################################################
##
## MCResultMethods.r
##
## Definition of methods for class MCResult
## Base class of mcreg result objects.
##
## Copyright (C) 2011 Roche Diagnostics GmbH
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
###############################################################################

###############################################################################
## Constructors
###############################################################################

#' MCResult Object Constructor with Matrix in Wide Format as Input
#'
#' @param wdata measurement data in matrix format. First column reference method (x), second column test method (y).
#' @param para regression parameters in matrix form. Rows: Intercept, Slope. Cols: EST, SE, LCI, UCI.
#' @param sample.names names of individual data points, e.g. barcodes of measured samples.
#' @param method.names names of reference and test method.
#' @param regmeth name of statistical method used for regression.
#' @param cimeth name of statistical method used for computing confidence intervals.
#' @param error.ratio ratio between standard deviation of reference and test method.
#' @param alpha numeric value specifying the 100(1-\code{alpha})\% confidence level of confidence intervals (Default is 0.05).
#' @param weight numeric vector specifying the weights used for each point
#' @return MCResult object containing regression results.
newMCResult <- function(wdata, para, sample.names=NULL, method.names=NULL, regmeth="Unknown", 
                        cimeth, error.ratio, alpha=0.05, weight=rep(1,nrow(wdata))) 
{
	## Check validity of parameters
  	stopifnot(is.matrix(wdata))
	  stopifnot(ncol(wdata)==2)
    stopifnot(is.matrix(para))
    stopifnot(all(dim(para)==c(2,4)))
    stopifnot(is.character(regmeth))
    stopifnot(is.element(regmeth,c("LinReg","WLinReg","Deming","BaPa","WDeming", "PaBaLarge","TS","PBequi")))
    stopifnot(!is.na(alpha))
    stopifnot(is.numeric(alpha))
    stopifnot(length(alpha) > 0)
    stopifnot(alpha > 0 & alpha < 1)
    stopifnot(is.element(cimeth,c("analytical","jackknife","bootstrap","nestedbootstrap")))
    stopifnot(!is.na(error.ratio))
    stopifnot(is.numeric(error.ratio))
    stopifnot(length(error.ratio) > 0)
    stopifnot(error.ratio>=0) 
    stopifnot(is.numeric(weight))
    stopifnot(length(weight) == nrow(wdata)) 
    
	
	## Sample names
	if(is.null(sample.names)) 
        snames <- paste("S",1:nrow(wdata),sep="")
	else 
    {
        stopifnot(length(sample.names)==nrow(wdata))
		    snames <- sample.names
		}
	## Method names
	if(is.null(method.names)) 
        mnames <- paste("Method",1:2,sep="")
	else 
    {
        stopifnot(length(method.names)==2)
		    mnames <- method.names
	}
	## Build object
	data <- data.frame(sid=snames,x=wdata[,1],y=wdata[,2])
	rownames(para) <- c("Intercept","Slope")
	colnames(para) <- c("EST","SE","LCI","UCI")
	names(weight) <- snames
	new(Class="MCResult",data=data,para=para,mnames=mnames,regmeth=regmeth,cimeth=cimeth,error.ratio=error.ratio,alpha=alpha,weight=weight)
}


###############################################################################
## Methods
###############################################################################

#' MCResult Object Initialization
#'
#' @param .Object object of class "MCResult"
#' @param data measurement data in matrix format. First column reference method (x), second column test method (y).
#' @param para regression parameters in matrix form. Rows: Intercept, Slope. Cols: EST, SE, LCI, UCI.
#' @param mnames names of reference and test method.
#' @param regmeth name of statistical method used for regression.
#' @param cimeth name of statistical method used for computing confidence intervals.
#' @param error.ratio ratio between standard deviation of reference and test method.
#' @param alpha numeric value specifying the 100(1-\code{alpha})\% confidence level of confidence intervals (Default is 0.05).
#' @param weight weights to be used for observations
#' @return MCResult object with initialized parameter.
MCResult.initialize <- function(.Object, data=data.frame(X=NA,Y=NA), para=matrix(NA,ncol=4,nrow=2),
		                        mnames=c("unknown","unknown"), regmeth="unknown", cimeth="unknown", 
                                error.ratio=0,alpha=0.05, weight=1) 
{	
	.Object@data <- data
	.Object@para <- para
	.Object@cimeth <- cimeth
	.Object@mnames <- mnames
	.Object@regmeth <- regmeth
	.Object@error.ratio<-error.ratio
	.Object@alpha <- alpha
	.Object@weight <- weight
	return(.Object)
}

#' Get Regression Coefficients
#'
#' @param .Object object of class "MCResult".
#' @return Regression parameters in matrix form. Rows: Intercept, Slope. Cols: EST, SE, LCI, UCI.
#' @aliases getCoefficients coef
#'

MCResult.getCoefficients <- function(.Object)
{
	return(.Object@para)
}


#' Get Error Ratio
#'
#' @param .Object Object of class "MCResult"
#' @return Error ratio. Only relevant for Deming type regressions.
#' @aliases getErrorRatio
MCResult.getErrorRatio <- function(.Object)
{
    return(.Object@error.ratio)
}

#' Get Weights of Data Points
#'
#' @param .Object Object of class "MCResult"
#' @return Weights of data points. 
#' @aliases getWeights
MCResult.getWeights <- function(.Object)
{
    return(.Object@weight)
}

#' Get Data
#'
#' @param .Object object of class "MCResult".
#' @return Measurement data in matrix format. First column contains reference method (X), second column contains test method (Y).
#' @aliases getData
MCResult.getData <- function(.Object)
{
	## Transform data frame to matrix, names could be changed
	rmat <- cbind(X=.Object@data$x,Y=.Object@data$y)
	rownames(rmat) <- .Object@data$sid
	return(rmat)
}

#' Get Regression Residuals
#' 
#' This function returns residuals in x-direction (x-xhat),
#' in y-direction(y-yhat) and optimized residuals.
#' The optimized residuals correspond to distances between 
#' data points and the regression line which were optimized for
#' regression coefficients estimation. In case of Passing-Bablok
#' Regression orthogonal residuals will be returned as optimized residuals .
#' The residuals in x-direction are interesting for regression types which
#' assume errors in both variables  (deming, weighted deming, Passing-Bablok), 
#' particularily for checking of model assumptions.
#' @param .Object object of class "MCResult".
#' @return residuals as data frame.
#' @seealso \code{\link{plotResiduals}} 
#' @aliases getResiduals
MCResult.getResiduals <- function(.Object) 
{
    weight <- getWeights(.Object)
    x <- .Object@data$x
    y <- .Object@data$y
    lmb <-ifelse(.Object@regmeth %in% c("PBequi"),(1/.Object@para["Slope",1])^2, .Object@error.ratio)
    a <- .Object@para["Intercept",1]
    b <- .Object@para["Slope",1]
    d <- y-(a+b*x)
           
    if (.Object@regmeth %in% c("LinReg","WLinReg","TS")){
        xhat <- x
        yhat <- a + b*x
    } else {
        xhat <- x+lmb*b*d/(1+lmb*b^2)
        yhat <- y-d/(1+lmb*b^2)
    }
    xres <- x-xhat
    yres <- y-yhat
 
    if (.Object@regmeth %in% c("LinReg","WLinReg","TS")){
        res <- yres*sqrt(weight)
    } else {
        res <- sign(yres)*sqrt((xres)^2+lmb*(yres)^2)*sqrt(weight)
    }     

    result <- data.frame(x=xres, y=yres, optimized=res)

    return(result)
}


#' Get Fitted Values.
#' 
#' This funcion computes fitted values for a 'MCResult'-object. Depending
#' on the regression method and the error ratio, a projection onto the regression
#' line is performed accordingly. For each point (x_i; y_i) i=1,...,n the projected
#' point(x_hat_i; y_hat_i) is computed.
#' 
#' @param .Object object of class "MCResult".
#' @return fitted values as data frame.
#' @seealso \code{\link{plotResiduals}} \code{\link{getResiduals}} 
#' @aliases getFitted
MCResult.getFitted <- function(.Object)
{
    x <- .Object@data$x
    y <- .Object@data$y
    lmb <-ifelse(.Object@regmeth %in% c("PBequi"),(1/.Object@para["Slope",1])^2, .Object@error.ratio)
    a <- .Object@para["Intercept",1]
    b <- .Object@para["Slope",1]
    
    d <- y-(a+b*x)
        
    if (.Object@regmeth %in% c("LinReg","WLinReg","TS"))
    {
        xhat <- x
        yhat <- a + b*x
    } else {
        xhat <- x+lmb*b*d/(1+lmb*b^2)
        yhat <- y-d/(1+lmb*b^2)
    } 
    
    return(data.frame(x_hat=xhat,y_hat=yhat))
}


#' Get Regression Method
#'
#' @param .Object object of class "MCResult".
#' @return Name of the statistical method used for the regression analysis.
#' @aliases getRegmethod
MCResult.getRegmethod <- function(.Object)
{
	return(.Object@regmeth)
}


###
### Statistics Functions
###

#' Calculate CUSUM Statistics According to Passing & Bablok (1983)
#'
#' @param .Object object of class "MCResult".
#' @return A list containing the following elements:
#' \item{nPos}{sum of positive residuals}
#' \item{nNeg}{sum of negative residuals}
#' \item{cusum}{a cumulative sum of vector with scores ri for each point, sorted increasing by distance of points to regression line.}
#' \item{max.cumsum}{Test statisics of linearity test}
#' @references Passing, H., Bablok, W. (1983) 
#'              A new biometrical procedure for testing the equality of measurements from two different analytical methods. 
#'              Application of linear regression procedures for method comparison studies in clinical chemistry, Part I. 
#'              \emph{J Clin Chem Clin Biochem}.  Nov; \bold{21(11)}:709--20.
#' @aliases calcCUSUM
MCResult.calcCUSUM <- function(.Object)
{
	
  res <- .Object@data[,"y"]-.Object@para["Intercept","EST"]-.Object@data[,"x"]*.Object@para["Slope","EST"]
	nl <- sum(res>0)
	nL <- sum(res<0)
	ri <- ifelse(res>0,sqrt(nL/nl),ifelse(res<0,-sqrt(nl/nL),0))
	Di <- (.Object@data$y+.Object@data$x/.Object@para["Slope",1]-.Object@para["Intercept",1])/sqrt(1+1/(.Object@para["Slope",1]^2))
	cusum <- cumsum(ri[order(Di)])
	max.cusum <- max(abs(cusum),na.rm=TRUE)
	return(list(nPos=nl,nNeg=nL,cusum=cusum,max.cusum=max.cusum))
}

#' Bland-Altman Plot
#' 
#' Draw different Bland-Altman plot modifications (see parameter \code{plot.type}).
#'
#' @param .Object object of class "MCResult".
#' @param xlab label for the x-axis
#' @param ylab label for the y-axis
#' @param digits number of decimal places for the difference of means and standard deviation appearing in the plot. 
#' @param plot.type integer specifying a specific Bland-Altman plot modification (default is 3).
#'  Possible choices are:
#'  1 - difference plot X vs. Y-X with null-line and mean plus confidence intervals.\cr
#'  2 - difference plot X vs. (Y-X)/X (relative differences) with null-line and mean.\cr
#'  3 - difference plot 0.5*(X+Y) vs. Y-X with null-line and mean plus confidence intervals.\cr
#'  4 - difference plot 0.5*(X+Y) vs. (Y-X)/X  (relative differences) with null-line.\cr
#'  5 - difference plot rank(X) vs. Y-X with null-line and mean plus confidence intervals.\cr
#'  6 - difference plot rank(X) vs. (Y-X)/X (relative differences) with null-line and mean.\cr
#'  7 - difference plot sqrt(X*Y) vs. Y/X with null-line and mean plus confidence intervals calculated with help of log-transformation.\cr
#'  8 - difference plot 0.5*(X+Y) vs. (Y-X) / (0.5*(X+Y)) with null-line.\cr
#' @param main plot title.
#' @param ref.line logical value. If \code{ref.line=TRUE} (default), the reference line will be drawn.
#' @param ref.line.col reference line color.
#' @param ref.line.lty reference line type.
#' @param ref.line.lwd reference line width.
#' @param bias.line.lty line type for estimated bias.
#' @param bias.line.lwd line width for estimated bias.
#' @param bias.line.col color of the line for estimated bias.
#' @param bias.text.col color of the label for estimated bias (defaults to the same as \code{bias.line.col}.)
#' @param bias.text.cex The magnification to be used for the label for estimated bias 
#' @param loa.line.lty line type for estimated limits of agreement.
#' @param loa.line.lwd line width for estimated limits of agreement.
#' @param loa.line.col color of the line for estimated limits of agreement.
#' @param loa.text.col color of the label for estimated limits of agreement (defaults to the same as \code{loa.line.col}.)
#' @param add.grid logical value. If \code{add.grid=TRUE} (Default) gridlines will be drawn.
#' @param ylim limits for the y-axis
#' @param cex numeric value specifying the magnification factor used for points
#' @param ... further graphical parameters
#' @references  Bland, J. M., Altman, D. G. (1986)
#'              Statistical methods for assessing agreement between two methods of clinical measurement. 
#'              \emph{Lancet}, \bold{i:} 307--310. 
#' @seealso \code{\link{plot.mcr}}, \code{\link{plotResiduals}}, \code{\link{plotDifference}}, \code{\link{plotBias}}, \code{\link{compareFit}}
#' @aliases plotDifference
#' @return No return value, instead a plot is generated
#' @examples
#'     #library("mcr")
#'     data(creatinine,package="mcr")
#'     x <- creatinine$serum.crea
#'     y <- creatinine$plasma.crea
#' 
#'     # Deming regression fit.
#'     # The confidence intercals for regression coefficients
#'     # are calculated with analytical method
#'     model <- mcreg( x,y,error.ratio=1,method.reg="Deming", method.ci="analytical",
#'                      mref.name = "serum.crea", mtest.name = "plasma.crea", na.rm=TRUE )
#' 
#'     plotDifference( model ) # Default plot.type=3
#'     plotDifference( model, plot.type=5)
#'     plotDifference( model, plot.type=7, ref.line.lty=3, ref.line.col="green3" )

MCResult.plotDifference <- function(.Object,
                                    xlab=NULL,
                                    ylab=NULL,
                                    ref.line=TRUE,
                                    ref.line.col="black",
                                    ref.line.lty=1,
                                    ref.line.lwd=1,
                                    bias.line.lty=1,
                                    bias.line.lwd=1,
                                    bias.line.col="red",
                                    bias.text.col=NULL,
                                    bias.text.cex=0.8,
                                    loa.line.lty=2,
                                    loa.line.lwd=1,
                                    loa.line.col="red",
                                    loa.text.col=NULL, 
                                    plot.type=3,
                                    main=NULL,
                                    cex=0.8, 
                                    digits=2, 
                                    add.grid= TRUE,
                                    ylim=NULL,
                                    ...)
{
	stopifnot(is.element(plot.type,1:8))
	stopifnot(is.numeric(digits))
	stopifnot(digits>0)
	stopifnot(digits==round(digits))
	
	if(is.null(main)) main <- "Difference plot" 
	
	if(plot.type %in% c(1,2))
    {
		X <- .Object@data[,"x"]
		x.lab <- .Object@mnames[1]
	}
		
	if(plot.type %in% c(3,4,8))
    {
		X <- (.Object@data[,"x"]+.Object@data[,"y"])/2
		x.lab <- paste("(",.Object@mnames[1],"+",.Object@mnames[2],")/2")
	}
	
	if(plot.type == 7)
    {
        stopifnot(all(.Object@data[,"x"]*.Object@data[,"y"]>0))
        X <- sqrt(.Object@data[,"x"]*.Object@data[,"y"])
        text1 <-.Object@mnames[1]
        text2 <- .Object@mnames[2]
        text1 <- gsub('[[:punct:]]',".",text1)
        text1 <- gsub('[[:space:]]',".",text1)
        text2 <- gsub('[[:punct:]]',".",text2)
        text2 <- gsub('[[:space:]]',".",text2)
        eval(parse(text=paste("x.lab<-expression(sqrt(paste(",text1,",' * ',",text2,")))",sep="")))
	}
	                                                  
	if(plot.type %in% c(5,6))
    {                     
		X <- rank(.Object@data[,"x"])
		x.lab <- paste("Rank of",.Object@mnames[1])
	}
	
	if(plot.type %in% c(1,3,5))
    {
		Y <- .Object@data[,"y"]-.Object@data[,"x"]
		y.lab <- paste(.Object@mnames[2],"-",.Object@mnames[1])
	}
	
	if(plot.type %in% c(2,4,6))
    {
        stopifnot(all(.Object@data[,"x"]!= 0))
        Y <- (.Object@data[,"y"]-.Object@data[,"x"])/.Object@data[,"x"]
        y.lab<-paste("(",.Object@mnames[2],"-",.Object@mnames[1],")/",.Object@mnames[1])
	}
	
	if(plot.type == 7)
    {
        stopifnot(all(.Object@data[,"x"]!= 0))
        Y <- .Object@data[,"y"]/.Object@data[,"x"]
        y.lab <- paste(text2,"/",text1)
	}
	
    if(plot.type == 8)
    {
        stopifnot(all((.Object@data[,"x"]+.Object@data[,"y"])/2 != 0))
        Y <- (.Object@data[,"y"]-.Object@data[,"x"])/((.Object@data[,"y"]+.Object@data[,"x"])/2 )
        text1 <- .Object@mnames[1]
        text2 <- .Object@mnames[2]
        y.lab <- paste("( ",text2," - ",text1," )"," / mean( ",text1," , ",text2," )", sep="" )
    }
	
	if(plot.type %in% c(1,2,3,4,5,6,8))
    {
        MEAN <- mean(Y,na.rm=TRUE)
        LOW <- MEAN - sd(Y)*2
        UP <- MEAN + sd(Y)*2
        y.low <- min(min(Y,na.rm=TRUE),LOW-0.05*2*sd(Y),na.rm=TRUE)
        y.up <- max(max(Y,na.rm=TRUE),UP+0.05*2*sd(Y),na.rm=TRUE)
        YLim <- c(y.low,y.up)   ## ylim replaced by YLim
	}
	
    if(plot.type == 7)
    {
        XX <- .Object@data[,"x"]
        YY <- .Object@data[,"y"]
        logmean <- mean(log(YY/XX),na.rm=TRUE)
        logLOW <- logmean - 2*sd(log(YY/XX),na.rm=TRUE)
        logUP  <- logmean + 2*sd(log(YY/XX),na.rm=TRUE)
        MEAN <- exp(logmean)
        LOW <- exp(logLOW)
        UP <- exp(logUP)
        y.low <- min(min(Y,na.rm=TRUE),LOW-0.05*2*sd(log(YY/XX),na.rm=TRUE),na.rm=TRUE)
        y.up <- max(max(Y,na.rm=TRUE),UP+0.05*2*sd(log(YY/XX),na.rm=TRUE),na.rm=TRUE)
        YLim <- c(y.low,y.up)   ## ylim replaced by YLim
    }
    
	oldpar <- par(no.readonly = TRUE)
	on.exit(par(oldpar))
	
    par(mar=c(5, 5, 4, 5) + 0.1)
    xlim <- c(range(X, na.rm=TRUE)[1],range(X, na.rm=TRUE)[2]+1/10*(range(X, na.rm=TRUE)[2]-range(X, na.rm=TRUE)[1]))
    
    if(is.null(xlab)) 
        xlab <- x.lab
    if(is.null(ylab)) 
        ylab <- y.lab
    
    if(!is.null(ylim))               # replace Min/Max-'ylim' by user-defined 'ylim' (YLimits)
    {
        if(all(is.numeric(ylim)))
        {
            if(all(!is.na(ylim)))
            {
                if(length(ylim) == 2)
                    YLim <- ylim
            }
        }
    }
    
    plot(X,Y,xlab=xlab,ylab=ylab,main=main,ylim=YLim,cex=cex, ...)
	
    if(add.grid) grid()
	
    if(ref.line==TRUE)
    {
        if(plot.type == 7)
            abline(h=1,
                   col=ref.line.col, 
                   lty=ref.line.lty, 
                   lwd=ref.line.lwd)
        else
            abline(h=0,
                   col=ref.line.col, 
                   lty=ref.line.lty, 
                   lwd=ref.line.lwd)
   }
  
    if(is.null(bias.text.col)) 
        bias.text.col <- bias.line.col
    if(is.null(loa.text.col)) 
        loa.text.col <- loa.line.col
  
    abline(h=MEAN, lty=bias.line.lty,
           lwd=bias.line.lwd,
           col=bias.line.col)
   
	meantext <- ifelse(plot.type %in% paste(c(1:6,8)),paste("MEAN"),paste("MEAN(log)"))
	mtext(at=MEAN+(y.up-y.low)/50,side=4, line=1,text=meantext,cex= bias.text.cex,col=bias.text.col,las=1)
	mtext(at=MEAN-(y.up-y.low)/50, side=4,line=1,text=paste(round(MEAN,digits=digits)),cex= bias.text.cex,col=bias.text.col,las=1)
	
	if(plot.type %in% c(1,3,5,7))
    {
        abline(h=UP,lty=loa.line.lty, 
               lwd=loa.line.lwd, 
               col=loa.line.col)
    	
        uptext <- ifelse(plot.type %in% paste(c(1:6,8)),paste("+ 2 SD"),paste("+ 2 SD(log)"))
        mtext(at=UP+(y.up-y.low)/50,side=4,line=1,text=uptext,cex= bias.text.cex,col=loa.text.col,las=1)
        mtext(at=UP-(y.up-y.low)/50,side=4,line=1,text=paste(round(UP,digits=digits)),cex= bias.text.cex,col=loa.text.col,las=1)
    	
        abline(h=LOW, lty=loa.line.lty, 
               lwd=loa.line.lwd, 
               col=loa.line.col)
    	
        lowtext <- ifelse(plot.type %in% paste(c(1:6,8)),paste("- 2 SD"),paste("- 2 SD(log)"))
        mtext(at=LOW+(y.up-y.low)/50,side=4,line=1,text=lowtext,cex= bias.text.cex,col=loa.text.col,las=1)
        mtext(at=LOW-(y.up-y.low)/50,side=4,line=1,text=paste(round(LOW,digits=digits)),cex= bias.text.cex,col=loa.text.col,las=1)
    }
}

#' Calculate Response with Confidence Interval.
#' 
#' Calculate Response \eqn{Intercept + Slope * Refrencemethod} with Corresponding Confidence Interval
#'
#' @param .Object object of class "MCResult".
#' @param x.levels a numeric vector with points for which response schould be calculated.
#' @param alpha numeric value specifying the 100(1-\code{alpha})\% confidence level of the confidence interval (Default is 0.05).
#' @param ... further parameters
#' @return response and corresponding confidence interval for each point in vector \code{x.levels}.
#' @seealso \code{\link{calcBias}}
#' @aliases calcResponse
#' @examples
#'     #library("mcr")
#'     data(creatinine,package="mcr")
#'     x <- creatinine$serum.crea
#'     y <- creatinine$plasma.crea
#'     # Deming regression fit.
#'     # The confidence intercals for regression coefficients
#'     # are calculated with analytical method
#'     model <- mcreg( x,y,error.ratio=1,method.reg="Deming", method.ci="analytical",
#'                      mref.name = "serum.crea", mtest.name = "plasma.crea", na.rm=TRUE )
#'     calcResponse(model, x.levels=c(1,2,3))
MCResult.calcResponse <- function(.Object,x.levels,alpha,...)
{
    cat("Called virtual basis function: MCResult.calcResponse\n")
}

#' Systematical Bias Between Reference Method and Test Method
#' 
#' Calculate systematical bias between reference and test methods 
#' at the decision point Xc as
#' \eqn{ Bias(Xc) = Intercept + (Slope-1) * Xc}
#' with corresponding confidence intervals.
#'
#' @param .Object object of class "MCResult".
#' @param type One can choose between absolute (default)  and proportional bias (\code{Bias(Xc)/Xc}).
#' @param percent logical value. If \code{percent = TRUE} the proportional bias will be calculated in percent.
#' @param x.levels a numeric vector with decision points for which bias schould be calculated.
#' @param alpha numeric value specifying the 100(1-\code{alpha})\% confidence level of the confidence interval (Default is 0.05).
#' @param ... further parameters
#' @return response and corresponding confidence interval for each decision point from x.levels.
#' @seealso \code{\link{plotBias}}
#' @aliases calcBias
#' @examples
#'     #library("mcr")
#'     data(creatinine,package="mcr")
#'     x <- creatinine$serum.crea
#'     y <- creatinine$plasma.crea
#' 
#'     # Deming regression fit.
#'     # The confidence intervals for regression coefficients
#'     # are calculated with analytical method
#'     model <- mcreg( x,y,error.ratio = 1,method.reg = "Deming", method.ci = "analytical",
#'
#'                      mref.name = "serum.crea", mtest.name = "plasma.crea", na.rm=TRUE )
#'     # Now we calculate the systematical bias
#'     # between the testmethod and the reference method
#'     # at the medical decision points 1, 2 and 3 
#'
#'     calcBias( model, x.levels = c(1,2,3))
#'     calcBias( model, x.levels = c(1,2,3), type = "proportional")
#'     calcBias( model, x.levels = c(1,2,3), type = "proportional", percent = FALSE)
MCResult.calcBias <- function(.Object, x.levels, type = c("absolute", "proportional"), percent=TRUE, alpha=0.05, ...) 
{	
    stopifnot(is.logical(percent))
    stopifnot(!is.na(x.levels))
    stopifnot(is.numeric(x.levels))
    stopifnot(length(x.levels) > 0)
    stopifnot(!is.na(alpha))
    stopifnot(is.numeric(alpha))
    stopifnot(length(alpha) > 0)
    stopifnot(alpha>=0 & alpha<=1)
    type <- match.arg(type)
	  
	## Bias calculation
	bias <- calcResponse(.Object,x.levels,alpha=alpha,...)
	bias[,c("Y","Y.LCI","Y.UCI")] <- bias[,c("Y","Y.LCI","Y.UCI")]-bias[,"X"]
	
	if ( type == "proportional" )
	{
	    stopifnot(all(x.levels != 0))
	    bias[,c("Y","Y.SE","Y.LCI","Y.UCI")] <- bias[,c("Y","Y.SE","Y.LCI","Y.UCI")]/x.levels
	    if (percent == TRUE)
      { 
             bias[,c("Y","Y.SE","Y.LCI","Y.UCI")] <- bias[,c("Y","Y.SE","Y.LCI","Y.UCI")]*100
             colnames(bias) <- c("Level","Prop.bias(%)","SE","LCI","UCI")
      } else colnames(bias) <- c("Level","Prop.bias","SE","LCI","UCI")       
  } else colnames(bias) <- c("Level","Bias","SE","LCI","UCI")
		
	## Return bias object
	rownames(bias) <- paste("X",1:length(x.levels),sep="")
	return(bias)
}

#' Scatter Plot Method X vs. Method Y
#' 
#' Plot method X (reference) vs. method Y (test) with (optional) line of identity,
#' regression line and confidence bounds for response.
#'
#' @param x object of class "MCResult".
#' @param alpha numeric value specifying the 100(1-\code{alpha})\% confidence bounds.
#' @param xn number of points (default 20) for calculation of confidence bounds.
#' @param draw.points logical value. If \code{draw.points=TRUE}, the data points will be drawn. 
#' @param xlim limits of the x-axis. If \code{xlim=NULL} the x-limits will be calculated automatically.
#' @param ylim limits of the y-axis. If \code{ylim=NULL} the y-limits will be calculated automatically.
#' @param xaxp ticks of the x-axis. If \code{xaxp=NULL} the x-ticks will be calculated automatically.
#' @param yaxp ticks of the y-axis. If \code{yaxp=NULL} the y-ticks will be calculated automatically.
#' @param x.lab label of x-axis. Default is the name of reference method.
#' @param y.lab label of y-axis. Default is the name of test method.
#' @param equal.axis logical value. If \code{equal.axis=TRUE} x-axis will be equal to y-axis.
#' @param add logical value. If \code{add=TRUE}, the plot will be drawn in current graphical window.
#' @param points.col Color of data points. 
#' @param points.pch Type of data points (see \code{par()}). 
#' @param points.cex Size of data points (see \code{par()}).
#' @param reg Logical value. If \code{reg=TRUE}, the regression line will be drawn.
#' @param reg.col Color of regression line.
#' @param reg.lty Type of regression line.
#' @param reg.lwd The width of regression line.
#' @param identity logical value. If \code{identity=TRUE} the identity line will be drawn.
#' @param identity.col The color of identity line.
#' @param identity.lty The type of identity line.
#' @param identity.lwd the width of identity line.
#' @param ci.area logical value. If \code{ci.area=TRUE} (default) the confidence area will be drawn.
#' @param ci.area.col the color of confidence area. 
#' @param ci.border logical value. If \code{ci.border=TRUE} the confidence limits will be drawn.
#' @param ci.border.col The color of confidence limits. 
#' @param ci.border.lty The line type of confidence limits. 
#' @param ci.border.lwd The line width of confidence limits. 
#' @param add.legend logical value. If \code{add.legend=FALSE} the plot will not have any legend.
#' @param legend.place The position of legend: "topleft","topright","bottomleft","bottomright". 
#' @param main String value. The main title of plot. If \code{main=NULL} it will include regression name.
#' @param sub String value. The subtitle of plot. If \code{sub=NULL} and \code{ci.border=TRUE} or \code{ci.area=TRUE} it will include the art of confidence bounds calculation.
#' @param add.cor Logical value. If \code{add.cor=TRUE} the correlation coefficient will be shown. 
#' @param cor.method a character string indicating which correlation coefficient is to be computed. One of "pearson" (default), "kendall", or "spearman", can be abbreviated.
#' @param add.grid Logical value. If \code{add.grid=TRUE} (default) the gridlines will be drawn.
#' @param digits list with the number of digits for the regression equation and the correlation coefficient. 
#' @param ... further graphical parameters
#' @seealso \code{\link{plotBias}}, \code{\link{plotResiduals}}, \code{\link{plotDifference}}, \code{\link{compareFit}},\code{\link{includeLegend}}
#' @aliases plot.mcr
#' @aliases plot
#' @return No return value, instead a plot is generated
#' @examples
#'  library(mcr)
#'  data(creatinine,package="mcr")
#'  creatinine <- creatinine[complete.cases(creatinine),]
#'   x <- creatinine$serum.crea
#'   y <- creatinine$plasma.crea
#' 
#'   m1 <- mcreg(x,y,method.reg="Deming",  mref.name="serum.crea",
#'                                         mtest.name="plasma.crea", na.rm=TRUE)
#'   m2 <- mcreg(x,y,method.reg="WDeming", method.ci="jackknife",
#'                                         mref.name="serum.crea",
#'                                         mtest.name="plasma.crea", na.rm=TRUE)
#' 
#'   plot(m1,  xlim=c(0.5,3),ylim=c(0.5,3), add.legend=FALSE,
#'                            main="Deming vs. weighted Deming regression",
#'                            points.pch=19,ci.area=TRUE, ci.area.col=grey(0.9),
#'                            identity=FALSE, add.grid=FALSE, sub="")
#'   plot(m2, ci.area=FALSE, ci.border=TRUE, ci.border.col="red3",
#'                            reg.col="red3", add.legend=FALSE,
#'                            draw.points=FALSE,add=TRUE)
#' 
#'   includeLegend(place="topleft",models=list(m1,m2),
#'                            colors=c("darkblue","red"), design="1", digits=2)
MCResult.plot <- function(x,
		alpha = 0.05 ,
		xn = 20,
		equal.axis=FALSE,
		xlim = NULL,
		ylim = NULL,
		xaxp = NULL,
		yaxp = NULL,
		x.lab = x@mnames[1],
		y.lab = x@mnames[2],
		add = FALSE,
		draw.points = TRUE,
		points.col = "black",
		points.pch =  1,
		points.cex = 0.8,
		reg = TRUE,              # regression line
		reg.col =NULL,  
		reg.lty =1, 
		reg.lwd = 2,
		identity = TRUE,         # bisecting line of an angle
		identity.col = NULL,
		identity.lty = 2,
		identity.lwd = 1,
		ci.area = TRUE,          # confidence bounds as area
		ci.area.col = NULL, 
		ci.border = FALSE, 
		ci.border.col = NULL,    # confidence bounds as lines
		ci.border.lty = 2,
		ci.border.lwd = 1,
		add.legend = TRUE,
		legend.place = c("topleft","topright","bottomleft","bottomright"),
		main = NULL,
		sub = NULL,
		add.cor = TRUE,
		cor.method = c("pearson", "kendall", "spearman"),
		add.grid= TRUE,
		digits = list(coef = 2, cor = 3),
		...) 
{	
	stopifnot(is.logical(reg))
	stopifnot(is.logical(ci.area))
	stopifnot(is.logical(identity))
	stopifnot(is.logical(ci.border))
	stopifnot(is.logical(add.cor))
	stopifnot(is.logical(add.grid))
	stopifnot(is.logical(draw.points))
	stopifnot(is.logical(add.legend))
	stopifnot(is.numeric(alpha))
	stopifnot(alpha>0 & alpha<1)
	
	if(is.null(digits)){
		digits = list(coef = 2, cor = 3)
	}
	stopifnot(sum(names(digits) %in% c("coef", "cor")) >= length(names(digits)))
	if(is.null(digits$coef)){
		digits$coef <- 2
	}
	if(is.null(digits$cor)){
		digits$cor <- 3
	}
	cor.method <- match.arg(cor.method)
	stopifnot(is.element(cor.method, c("pearson", "kendall", "spearman")))
	
	legend.place <- match.arg(legend.place)
	stopifnot(is.element(legend.place, c("topleft","topright","bottomleft","bottomright")))
	if(length(points.col)>1) stopifnot(length(points.col)==nrow(x@data))
	if(length(points.pch)>1) stopifnot(length(points.pch)==nrow(x@data))
	
	if(x@regmeth == "LinReg")
		titname<-"Linear Regression"
	else if(x@regmeth == "WLinReg")
		titname<-"Weighted Linear Regression"
	else if(x@regmeth == "TS")
		titname<-"Theil-Sen Regression"
	else if(x@regmeth == "PBequi")
		titname<-"Equivariant Passing-Bablok Regression"
	else if(x@regmeth == "Deming")
		titname<-"Deming Regression"
	else if(x@regmeth == "WDeming")
		titname<-"Weighted Deming Regression"
	else 
		titname <- "Passing Bablok Regression"
	
	## Colors
	niceblue <- rgb(37/255,52/255,148/255)
	niceor <- rgb(230/255,85/255,13/255)
	niceblue.bounds <- rgb(236/255, 231/255, 242/255)
	
	if(is.null(reg.col)) 
		reg.col <- niceblue 
	if(is.null(identity.col)) 
		identity.col <- niceor
	if(is.null(ci.area.col)) 
		ci.area.col <- niceblue.bounds
	if(is.null(ci.border.col)) 
		ci.border.col <- niceblue
	
	stopifnot(is.numeric(xn))
	stopifnot(round(xn) == xn)                     
	stopifnot(xn>1)
	# In case xlim was not set calculate it from the data
	if(is.null(xlim)) 
		rx <- range(x@data[,"x"],na.rm=TRUE)
	else
		rx <- xlim
	
	tmp.range <- range(as.vector(x@data[,c("x","y")]), na.rm = TRUE)
	
	if(equal.axis == TRUE){
		if(is.null(ylim)){
			yrange <- tmp.range
		}else{
			yrange <- ylim
		}		
	}else{
		if(is.null(ylim)){
			yrange <- range(as.vector(x@data[,"y"]),na.rm=TRUE)
		}else{
			yrange <- ylim
		}
	}
	
	if(!is.null(xlim) && !is.null(ylim) && equal.axis){
		xlim <- c(
				min(c(xlim[1],ylim[1])),
				max(c(xlim[2],ylim[2]))
		)
	}
	
	# In case xaxp was not set
	if(is.null(xaxp)){
		
		# Check if xlim is set
		if(!is.null(xlim)){
			
			# Then get the ticks from xlim
			axis_ticks <- axisTicks( 
					c(
							xlim[1]-0.05*xlim[2],
							ceiling((xlim[2]+0.05*xlim[2])*10^digits$coef)/10^digits$coef
					),
					log=F,
					nint=7
			)
			# If no limits were created get the maximum and minimum
			#  of the data +- 10% as limits
			xaxp <- c(axis_ticks[1],tail(axis_ticks, n=1),length(axis_ticks)-1)
			xlim <- c(axis_ticks[1],tail(axis_ticks, n=1))
		}
	}else{
		if(!is.null(xlim)){
			# If xaxp is set, fit the xlim to xaxp
			# but just in case, it was not delivered and was taken from data
			if((xlim[1]==rx[1] && xlim[2]==rx[2]) | (tmp.range[1]==xlim[1] && tmp.range[2]==xlim[2])){
				xlim <- c(xaxp[1],xaxp[2])
			}
		}else{
			warning("xaxp should never be set without xlim")
			xaxp <- NULL
		}
	}
	
	if(is.null(yaxp)){
		# Check if limits were created
		
		# create an xaxp parameter form axis_ticks
		# If Y-axis limits are given calculate the Y-axis ticks
		# from those
		if(!is.null(ylim) && !equal.axis){
			yaxp <- axis_ticks <- axisTicks( 
					c(
							ylim[1]-0.05*ylim[2],
							ceiling((ylim[2]+0.05*ylim[2])*10^digits$coef)/10^digits$coef
					),
					log=F,
					nint=10
			
			)
			yaxp = c(axis_ticks[1],tail(axis_ticks, n=1),length(axis_ticks)-1)
			ylim <- c(axis_ticks[1],tail(axis_ticks, n=1))
		}else{
			if(equal.axis){
				if(!is.null(xlim)){
					yaxp <- xaxp
					ylim <- xlim
				}
			}
		}
	}else{
		if(!is.null(ylim)){
			# If <axp is set, fit the <lim to xaxp
			# but just in case, it was not delivered and was taken from data
			
			# Check if taken from data
			if((ylim[1]==yrange[1] && ylim[2]==yrange[2]) | (tmp.range[1]==ylim[1] && tmp.range[2]==ylim[2])){
				ylim <- c(yaxp[1],yaxp[2])
			}
		}else{
			warning("yaxp should never be set without ylim")
			yaxp <- NULL
			
		}
	}
	
	if(equal.axis){
		
		if(is.null(ylim)){
			
			yaxp <- xaxp
			ylim <- xlim
		}
		if(is.null(xlim)){
			xaxp<-yaxp
			xlim <- ylim
		}
	}
	# Fit Ranges to limits
	if(!is.null(xlim)){
		
		if(xlim[1]<tmp.range[1]){
			tmp.range[1] <- xlim[1]
		}
		if(xlim[2]>tmp.range[2]){
			tmp.range[2] <- xlim[2]
		}
	}
	
	if(!is.null(ylim)){
		
		if(ylim[1]<yrange[1]){
			yrange[1] <- ylim[1]
		}
		
		if(ylim[2]>yrange[2]){
			yrange[2] <- ylim[2]
		}
	}
	
	xd <- seq(rx[1],rx[2],length.out=xn)
	xd <- union(xd, rx)
	
	## additional points outer range for nice bounds
	delta <- abs(rx[1]-rx[2])/xn
	xd <- xd[order(xd)]
	xd.add <- c(xd[1]-delta*1:10, xd, xd[length(xd)]+delta*1:10)
	
	if(is.null(xlim)) xlim <- rx
	
	# Paint the confidence interval area
	if(ci.area == TRUE | ci.border == TRUE){
		bounds <- calcResponse(x, alpha=alpha, x.levels=xd)
		bounds.add <- calcResponse(x, alpha=alpha, x.levels=xd.add)
		
		if(equal.axis == TRUE){
			xd <- seq(tmp.range[1], tmp.range[2], length.out=xn)
			xd <- union(xd, tmp.range)
			
			## additional points outer range for nice bounds
			delta <- abs(rx[1]-rx[2])/xn
			xd <- xd[order(xd)]
			xd.add <- c(xd[1]-delta*1:10, xd, xd[length(xd)]+delta*1:10)
			
			bounds <- calcResponse(x, alpha=alpha, x.levels=xd)
			bounds.add <- calcResponse(x, alpha=alpha, x.levels=xd.add)
			
			yrange <- range(c(as.vector(x@data[,c("x","y")]),
							as.vector(bounds[,c("X","Y","Y.LCI","Y.UCI")])),
					na.rm=TRUE)		
		}else{
			yrange <- range(c(as.vector(x@data[,"y"]),
							as.vector(bounds[,c("Y","Y.LCI","Y.UCI")])),
					na.rm=TRUE)
		}
	}else{
		if(equal.axis == TRUE){
			yrange <- tmp.range
		}else{
			yrange <- range(as.vector(x@data[,"y"]),na.rm=TRUE)
		}
	}    
	
	if(equal.axis){
		if(is.null(ylim)){
			xlim <- ylim <- tmp.range
		}else{
			xlim <- ylim
		}
	}else{
		if(is.null(xlim)) xlim <- rx
		if(is.null(ylim)) ylim <- yrange
	}		
	
	
	if(is.null(main)) 
		main <- paste(titname,"Fit")
	
	
	if(!add){
		plot(0, 0, cex=0, ylim=ylim, xlim=xlim, xlab=x.lab, ylab=y.lab, main = main, sub="", xaxp=xaxp, yaxp=yaxp, bty="n", ...)
		
	}else{
		sub <- ""
		add.legend <- FALSE
		add.grid <- FALSE
	}
	if(add.legend == TRUE){
		if(identity == TRUE & reg == TRUE)
		{
			text2 <- "identity"
			text1 <- paste(formatC(round(x@para["Intercept","EST"], digits = digits$coef), digits = digits$coef, format="f"),
					" + ", 
					formatC(round(x@para["Slope","EST"], digits = digits$coef), digits = digits$coef, format="f"),
					" * ",x@mnames[1],sep="")
			legend(legend.place, lwd=c(reg.lwd,identity.lwd), 
					lty=c(reg.lty,identity.lty), col=c(reg.col,identity.col),
					title = paste(titname,"Fit (n=",dim(x@data)[1],")", sep=""),
					legend = c(text1,text2), box.lty="blank", cex=0.8, bg="white", inset=c(0.01,0.01))
		}
		
		if(identity == TRUE & reg == FALSE){
			text2 <- "identity"
			legend(legend.place, lwd=identity.lwd, lty=identity.lty, col=identity.col,
					title=paste(titname,"Fit (n=",dim(x@data)[1],")", sep=""),
					legend=text2, box.lty="blank", cex=0.8, bg="white", inset=c(0.01,0.01))
		}
		
		if(identity==FALSE & reg==TRUE){
			text1 <- paste(formatC(round(x@para["Intercept","EST"], digits = digits$coef), digits = digits$coef, format="f"),"+",
					formatC(round(x@para["Slope","EST"], digits = digits$coef), digits = digits$coef, format="f"),
					"*", x@mnames[1], sep="")
			legend(legend.place, lwd=c(2), col=c(reg.col),
					title=paste(titname,"Fit (n=",dim(x@data)[1],")", sep=""),
					legend=c(text1), box.lty="blank", cex=0.8, bg="white", inset=c(0.01,0.01))
		}
	}
	
	
	if(ci.area == TRUE | ci.border == TRUE){
		if(ci.area == TRUE){
			xxx <- c(xd.add,xd.add[order(xd.add,decreasing = TRUE)])
			yy1 <- c(as.vector(bounds.add[,"Y.LCI"]))
			yy2 <- c(as.vector(bounds.add[,"Y.UCI"]))
			yyy <- c(yy1,yy2[order(xd.add, decreasing=TRUE)])
			polygon(xxx, yyy, col=ci.area.col, border="white", lty=0)
		} 
		
		if(add.grid) grid()
		
		if(ci.border == TRUE){
			points(xd.add, bounds.add[,"Y.LCI"], lty=ci.border.lty, lwd=ci.border.lwd, type="l", col=ci.border.col)
			points(xd.add, bounds.add[,"Y.UCI"], lty=ci.border.lty, lwd=ci.border.lwd, type="l", col=ci.border.col)
		}
		
		if(is.null(sub)){
			if(x@cimeth %in% c("bootstrap","nestedbootstrap"))
				subtext <- paste("The ", 1-x@alpha,"-confidence bounds are calculated with the ",x@cimeth,"(",x@bootcimeth,") method.",sep="")
			else if((x@regmeth=="PaBa")&(x@cimeth=="analytical"))
				subtext <- ""
			else 
				subtext <- paste("The ", 1-x@alpha,"-confidence bounds are calculated with the ",x@cimeth," method.",sep="")
		}
		else subtext <- sub
	}else{
		if(add.grid) grid()
		subtext <- ifelse(is.null(sub), "", sub)
	}
	if(add.cor == TRUE){
		cor.coef <- paste(formatC(round(cor(x@data[,"x"],x@data[,"y"],use="pairwise.complete.obs", method=cor.method), digits = digits$cor), digits = digits$cor, format="f"))
		if (cor.method == "pearson") cortext<- paste("Pearson's r = ",cor.coef, sep="")
		if (cor.method == "kendall") cortext<- bquote(paste("Kendall's ", tau, " = ", .(cor.coef) , sep=""))
		if (cor.method == "spearman") cortext <- bquote(paste("Spearman's ", rho, " = ",.(cor.coef), sep=""))
		mtext(side=1, line=-2, cortext, adj=0.9, font=1)
	}
	
	if(draw.points == TRUE){
		points(x@data[,2:3], col=points.col, pch=points.pch, cex=points.cex, ...)
	}
	title(sub = subtext)
	
#-
	
	if(reg == TRUE){
		b0 <- x@para["Intercept","EST"]
		b1 <- x@para["Slope","EST"]
		abline(b0, b1, lty=reg.lty, lwd=reg.lwd, col=reg.col )
	}
	
	if(identity == TRUE){
		abline(0, 1, lty=identity.lty, lwd=identity.lwd, col=identity.col)
	}
	
	box()
}                                                     


#' Plot Estimated Systematical Bias with Confidence Bounds
#' 
#' This function plots the estimated systematical bias 
#' \eqn{( Intercept + Slope * Refrencemethod ) - Referencemethod}
#' with confidence bounds, covering the whole range of reference method X 
#' or only part of it.
#'
#' @param x object of class "MCResult".
#' @param xn # number of poits for drawing of confidence bounds/area. 
#' @param add logical value. If \code{add=TRUE}, the grafic will be drawn in current grafical window.
#' @param prop a logical value. If \code{prop=TRUE} the proportional bias \eqn{ \%bias(Xc) = [ Intercept + (Slope-1) * Xc ] / Xc} will be drawn.
#' @param xlim limits of the x-axis. If \code{xlim=NULL} the x-limits will be calculated automatically.
#' @param ylim limits of the y-axis. If \code{ylim=NULL} the y-limits will be calculated automatically.
#' @param bias logical value. If \code{identity=TRUE} the bias line will be drawn. If ci.bounds=FALSE and ci.area=FALSE the bias line will be drawn always.
#' @param bias.col color of the bias line.
#' @param bias.lty type of the bias line.
#' @param bias.lwd width of the bias line.
#' @param zeroline logical value. If \code{zeroline=TRUE} the zero-line will be drawn.
#' @param zeroline.col color of the zero-line.
#' @param zeroline.lty type of the zero-line.
#' @param zeroline.lwd width of the zero-line.
#' @param ci.area logical value. If \code{ci.area=TRUE} (default) the confidence area will be drawn.
#' @param ci.border logical value. If ci.border=TRUE  the confidence limits will be drawn.
#' @param ci.area.col color of the confidence area.  
#' @param ci.border.col color of the confidence limits. 
#' @param ci.border.lty line type of confidence limits. 
#' @param ci.border.lwd line width of confidence limits.
#' @param cut.point  numeric value. Decision level of interest.
#' @param cut.point.col color of the confidence bounds at the required decision level.
#' @param cut.point.lty line type of the confidence bounds at the required decision level.
#' @param cut.point.lwd line width of the confidence bounds at the required decision level.
#' @param main character string. The main title of plot. If \code{main = NULL} it will include regression name.
#' @param sub character string. The subtitle of plot. If \code{sub=NULL} and \code{ci.border=TRUE} or \code{ci.area=TRUE} it will include the art of confidence bounds calculation.
#' @param add.grid logical value. If \code{grid=TRUE} (default) the gridlines will be drawn.  
#' @param xlab label for the x-axis
#' @param ylab label for the y-axis
#' @param alpha numeric value specifying the 100(1-\code{alpha})\% confidence level of confidence intervals (Default is 0.05).
#' @param ... further graphical parameters
#' @seealso \code{\link{calcBias}}, \code{\link{plot.mcr}}, \code{\link{plotResiduals}}, \code{\link{plotDifference}}, \code{\link{compareFit}}
#' @aliases plotBias
#' @return No return value, instead a plot is generated
#' @examples
#' #library("mcr")
#' data(creatinine,package="mcr")
#' 
#' creatinine <- creatinine[complete.cases(creatinine),]
#' x <- creatinine$serum.crea
#' y <- creatinine$plasma.crea
#' 
#' # Calculation of models
#' m1 <- mcreg(x,y,method.reg="WDeming", method.ci="jackknife",
#'                 mref.name="serum.crea",mtest.name="plasma.crea", na.rm=TRUE)
#' m2 <- mcreg(x,y,method.reg="WDeming", method.ci="bootstrap",
#'                 method.bootstrap.ci="BCa",mref.name="serum.crea",
#'                 mtest.name="plasma.crea", na.rm=TRUE)
#' 
#' # Grafical comparison of systematical Bias of two models
#' plotBias(m1, zeroline=TRUE,zeroline.col="black",zeroline.lty=1,
#'                 ci.area=TRUE,ci.border=FALSE, ci.area.col=grey(0.9),
#'                 main = "Bias between serum and plasma creatinine",
#'                 sub="Comparison of Jackknife and BCa-Bootstrap confidence bounds ")
#' plotBias(m2, ci.area=FALSE, ci.border=TRUE, ci.border.lwd=2,
#'                 ci.border.col="red",bias=FALSE ,add=TRUE)
#' includeLegend(place="topleft",models=list(m1,m2), lwd=c(10,2),
#'                 lty=c(2,1),colors=c(grey(0.9),"red"), bias=TRUE,
#'                 design="1", digits=4)
#' 
#' # Drawing of proportional bias
#' plotBias(m1, ci.area=FALSE, ci.border=TRUE)
#' plotBias(m1, ci.area=FALSE, ci.border=TRUE, prop=TRUE)
#' plotBias(m1, ci.area=FALSE, ci.border=TRUE, prop=TRUE, cut.point=0.6)
#' plotBias(m1, ci.area=FALSE, ci.border=TRUE, prop=TRUE, cut.point=0.6,
#'              xlim=c(0.4,0.8),cut.point.col="orange", cut.point.lwd=3, main ="")
MCResult.plotBias<-function(x, 
                            xn = 100, 
                            alpha = 0.05, 
                            add = FALSE,
                            prop = FALSE,
                            xlim =NULL, 
                            ylim=NULL,
                            bias = TRUE,
                            bias.lty = 1,
                            bias.lwd = 2,
                            bias.col = NULL,
                            ci.area = TRUE, 
                            ci.area.col = NULL,
                            ci.border = FALSE, 
                            ci.border.col = NULL, 
                            ci.border.lwd = 1,
                            ci.border.lty = 2,
                            zeroline = TRUE,
                            zeroline.col = NULL,
                            zeroline.lty = 2,
                            zeroline.lwd = 1,
                            main = NULL,
                            sub = NULL,
                            add.grid= TRUE,
                            xlab = NULL,
                            ylab = NULL,
                            cut.point = NULL,
                            cut.point.col = "red",
                            cut.point.lwd = 2,
                            cut.point.lty = 1,
                            ...)
{                  
	stopifnot(is.logical(ci.area))
	stopifnot(is.logical(bias))
	stopifnot(is.logical(add))
	stopifnot(is.logical(ci.border))
	stopifnot(is.logical(add.grid))
	stopifnot(is.numeric(alpha))
	stopifnot(is.logical(prop))
	stopifnot(alpha>0 & alpha<1)
	if (!is.null(cut.point)) 
    {
       stopifnot(is.numeric(cut.point))
	    }
    stopifnot(is.numeric(xn))
    stopifnot(round(xn) == xn)
    stopifnot(xn>2)
    if(x@regmeth == "LinReg")
    {
        titname<-"Linear Regression"
	} else if(x@regmeth == "WLinReg")
    {
        titname<-"Weighted Linear Regression"
   	} else if(x@regmeth == "TS")
    {
        titname<-"Theil-Sen Regression"
	} else if(x@regmeth == "PBequi")
    {
        titname<-"Equivariant Passing-Bablok Regression"
    } else if(x@regmeth == "Deming")
    {
        titname<-"Deming Regression"
    } else if(x@regmeth == "WDeming")
    {
        titname<-"Weighted Deming Regression"
    } else   titname <- "Passing Bablok Regression"
    
	if(x@regmeth %in% c("WDeming","PaBa", "PaBaLarge") & x@cimeth== "analytical" & (ci.area==TRUE | ci.border==TRUE))
    {
        ci.area <- FALSE
        ci.border <- FALSE
        cat("Calculation of confidence bounds with analytical method\n is not available for this regression type.\n")
    }
 
    if(is.null(xlab))  xlab <- x@mnames[1]
  	if(is.null(ylab))  if ( prop == FALSE ) ylab <- "Bias" else ylab <- "% Bias"
  	if (!is.null(xlim) & !is.null(cut.point)) 
    {
          cut.point <- cut.point[cut.point<=xlim[2] & cut.point>=xlim[1] ]
          if (length(cut.point)==0) cut.point <- NULL
	}
    
    b0<-x@para["Intercept","EST"]
    b1<-x@para["Slope","EST"]
    b0.low <- x@para["Intercept","LCI"]
    
    stopifnot( b0.low < b0 )
   
    niceblue <- rgb(37/255,52/255,148/255)
    niceor <- rgb(230/255,85/255,13/255)
    niceblue.bounds <- rgb(236/255, 231/255, 242/255)
    
    if(is.null(bias.col)) 
          bias.col <- niceblue  
  	if(is.null(ci.area.col)) 
          ci.area.col <- niceblue.bounds
  	if(is.null(ci.border.col)) 
          ci.border.col <- niceblue
  	if(is.null(zeroline.col)) 
          zeroline.col <- "black"
          
    if(is.null(sub))
    {
        if(x@cimeth %in% c("bootstrap","nestedbootstrap"))
            subtext <- paste("The ", 1-x@alpha,"-confidence bounds are calculated with the ",x@cimeth,"(",x@bootcimeth,") method.",sep="")
        else if((x@regmeth %in% c("PaBa", "PaBaLarge"))&(x@cimeth=="analytical"))
            subtext <- ""
        else 
            subtext <- paste("The ", 1-x@alpha,"-confidence bounds are calculated with the ",x@cimeth," method.",sep="") 
    } else subtext <- sub
           
  #---------- ordinar bias -----------------------------------------------------
          
    if (prop == FALSE)
    {
        if(is.null(main)) main <- paste("Bias plot \n",titname,"Fit")
        if (is.null(xlim))
        {
            xlim <-  range(x@data[,"x"],na.rm=TRUE)
            if (!is.null(cut.point))
            {
                if ( min(cut.point) <=xlim[1] & min(cut.point) < 0 ) xlim[1] <- 1.1* min(cut.point)
                if ( min(cut.point) <=xlim[1] &  min(cut.point) > 0 ) xlim[1] <- 0.9* min(cut.point)
                if ( max(cut.point) >=xlim[2] & max(cut.point) < 0 ) xlim[2] <- 0.9*max(cut.point)
                if ( max(cut.point) >=xlim[2] & max(cut.point)> 0 ) xlim[2] <- 1.1*max(cut.point)
                if ( max(cut.point)>=xlim[2] & max(cut.point) == 0 ) xlim[2] <- max(cut.point)+0.1*abs(xlim[2]-xlim[1])
                if ( min(cut.point)<=xlim[1] &  min(cut.point) == 0 ) xlim[1] <-  min(cut.point)-0.1*abs(xlim[2]-xlim[1])
            }    
        }
        
        ## points for drawing of confidence bounds/area:
        xd <- seq(xlim[1],xlim[2],length.out=xn)
        #if (xlim[1]==0) xd <- seq(0,xlim[2]+0.05*(xlim[2]-xlim[1]),length.out=xn)
        xd <- union(union(xd, xlim), cut.point)
        xd <- xd[order(xd)]
       
    
        bounds<-calcBias(x,x.levels=xd,alpha=alpha, type="absolute")
    
        if(ci.area == TRUE | ci.border == TRUE)
        {	
            if(is.null(ylim)==FALSE & add==FALSE)
            {
                yrange <- ylim
            } else  yrange<-range(bounds[,c("Bias","LCI","UCI")],na.rm=TRUE)
	
    	    if(add == FALSE) 
            {
                plot(0,0,cex=0, xlim=range(xd), ylim=yrange, xlab=xlab, 
                     ylab=ylab, main = main, sub="", bty="n", ...)
            } 
            else
            {
                subtext <- ""
                legend <- FALSE
                grid <- FALSE
                zeroline <- FALSE
            }
            if(ci.area == TRUE)
            {
                xxx <- c(xd,xd[order(xd,decreasing=TRUE)])
                yy1<-c(as.vector(bounds[,"LCI"]))
                yy2<-c(as.vector(bounds[,"UCI"]))
                yyy <-c(yy1,yy2[order(xd,decreasing=TRUE)])
                polygon(xxx,yyy,col=ci.area.col,border="white")
                if(add.grid== TRUE) grid() 
            } #end if(ci.area == TRUE)
            
            if(ci.border == TRUE)
            {
                points(xd, bounds[,"LCI"], lty=ci.border.lty,lwd=ci.border.lwd, col=ci.border.col, type="l")
          	    points(xd, bounds[,"UCI"], lty=ci.border.lty,lwd=ci.border.lwd, col=ci.border.col, type="l")
            } #end if(ci.border == TRUE)
            if(bias == TRUE) points(xd, bounds[,"Bias"], col=bias.col, type="l", lwd=bias.lwd, lty=bias.lty)
            if(zeroline == TRUE) abline(h=0,lty=zeroline.lty, col=zeroline.col, lwd=zeroline.lwd)
            title(sub = subtext)  
        } else {
            if(zeroline == TRUE & is.null(ylim) & is.null(cut.point))   ylim <- range(c(b0+b1*xd-xd, 0),na.rm=T) 
            if(zeroline == TRUE & is.null(ylim) & !is.null(cut.point))  ylim <- range(c(b0+b1*xd-xd, 0,
                                                                           calcBias(x, x.levels=cut.point, alpha=alpha)[,c("Bias","LCI","UCI")]),na.rm=T) 
            if(zeroline == FALSE & is.null(ylim) & is.null(cut.point))  ylim <- range(c(b0+b1*xd-xd),na.rm=T) 
            if(zeroline == FALSE & is.null(ylim) & !is.null(cut.point)) ylim <- range(c(b0+b1*xd-xd, 
                                                                           calcBias(x, x.levels=cut.point, alpha=alpha)[,c("Bias","LCI","UCI")]),na.rm=T) 
      
            if (add == FALSE)
            {
                plot(xd,b0+b1*xd-xd, main=main, col=bias.col, lty=bias.lty, ylim=ylim, 
                     lwd=bias.lwd, type="l",xlab=xlab,ylab=ylab,sub="",...)
            } else {
                main <- ""
                subtext <- ""
                add.grid<- FALSE
                zeroline <- FALSE
                points(xd,b0+b1*xd-xd, main=main, col=bias.col, lty=bias.lty, ylim=ylim, 
                       lwd=bias.lwd, type="l",xlab=xlab,ylab=ylab,sub="",...)
            } #end if (add=FALSE)
        }#end if(ci.area == TRUE | ci.border == TRUE)
    
        title(sub = subtext)       
        if(add.grid== TRUE) grid() 
        if(zeroline == TRUE) abline(h=0,lty=zeroline.lty, col=zeroline.col, lwd=zeroline.lwd)    
        if (!is.null(cut.point))
        {
            cut.point.y <- calcBias(x,x.levels=cut.point,alpha=alpha)
            for (ii in seq_along(cut.point)){
                     segments(cut.point[ii], cut.point.y[ii,"LCI"],cut.point[ii], cut.point.y[ii,"UCI"],
                     col=cut.point.col, lty=cut.point.lty,lwd=cut.point.lwd)
                     }
        }
    }
    
    # --------  proportional bias ------------------------------------------------
    if (prop == TRUE)
    {   
        ## This function calculates x-points for drawing of confidence bounds/area
        golden.seq <- function(x.low, x.up,xn, result)
        {
            delta <- abs(x.up-x.low)/1000000
            p <- abs(1-(delta/(x.up-x.low))^(1/xn))
            
            temp <- function(x.low, x.up,p,xn,tresh, result)
            {
                if (abs(x.up-x.low)>tresh)
                {
                    x.up <-(1-p)*x.up+p*x.low
                    result <-temp(x.low, x.up,p,xn,tresh, result)
                    return(c(result,x.up))
                }
            }
            return(temp(x.low, x.up,p,xn,tresh=delta, result))
        } # end golden.seq
    
     
        if(is.null(main))   main <- paste("Proportional bias plot \n",titname,"Fit")
        if (!is.null(cut.point) )
        {
            if (any(cut.point == 0))
            { 
                warning("The proportional bias  at 0 is infinite.")
                cut.point <- NULL
            }
        } 
     
        c <- 0.4   # This coefficient controls the default x-limits of the graph.
      
        if (b0==0)
        {
            lowlimit <- c*sqrt(abs(b0.low))
        } else {
            lowlimit <- c*sqrt(abs(b0))
        }  
     
        if (is.null(xlim))
        {
            xlim <- range(x@data[,"x"])
            if (!is.null(cut.point))
            {
                if ( min(cut.point) <=xlim[1] & min(cut.point) < 0 ) xlim[1] <- 1.1* min(cut.point)
                if ( min(cut.point) <=xlim[1] &  min(cut.point) > 0 ) xlim[1] <- 0.9* min(cut.point)
                if ( max(cut.point) >=xlim[2] & max(cut.point) < 0 ) xlim[2] <- 0.9*max(cut.point)
                if ( max(cut.point) >=xlim[2] & max(cut.point)> 0 ) xlim[2] <- 1.1*max(cut.point)
            }    
        }   
   
        xlim.new <- xlim
    
        if ( xlim[1]==0 )  xlim.new[1] <- min(lowlimit,xlim[2],na.rm=TRUE)/2
        if ( xlim[2]==0 )  xlim.new[2] <- -1*min(lowlimit,abs(xlim[1]),na.rm=TRUE)/2
    
        ## in this case the positive and negative part of the graph 
        ## must be drawn separately
        if (xlim.new[1]<0 & xlim.new[2]>0)
        {
            lowlimit <-min(abs(xlim.new[1])/5,abs(xlim.new[2])/5,lowlimit/5)       
            xlim.neg <- c(xlim.new[1], -lowlimit)
            xd.neg <- -1*golden.seq(x.low=min(abs(xlim.neg[1]),abs(xlim.neg[2])), x.up=max(abs(xlim.neg[1]),abs(xlim.neg[2])),
                                    xn=xn-1,result=max(abs(xlim.neg[1]),abs(xlim.neg[2]))) 
            xd.neg <- union(union(xd.neg, xlim.neg), cut.point[cut.point<0])
            xd.neg <-xd.neg[order(xd.neg)]
            xd.neg<- xd.neg[xd.neg!=0]
            bounds.neg<-calcBias(x,x.levels=xd.neg,alpha=alpha, type="proportional", percent=TRUE) 
          
            xlim.pos <- c( lowlimit , xlim.new[2] )
            xd.pos <- golden.seq(x.low=min(abs(xlim.pos[1]),abs(xlim.pos[2])), x.up=max(abs(xlim.pos[1]),abs(xlim.pos[2])),
                                 xn=xn-1, result=max(abs(xlim.pos[1]),abs(xlim.pos[2])))  
            xd.pos <- union(union(xd.pos, xlim.pos), cut.point[cut.point>0])
            xd.pos<- xd.pos[order(xd.pos)]
            xd.pos<- xd.pos[xd.pos!=0]
            bounds.pos<-calcBias(x,x.levels=xd.pos,alpha=alpha, type="proportional", percent=TRUE) 
            xd <- c(xd.neg, xd.pos)
       
        }
        else
        {
            xd <- golden.seq(x.low=min(abs(xlim.new[1]),abs(xlim.new[2])), x.up=max(abs(xlim.new[1]),abs(xlim.new[2])),
                             xn=xn-1, result=max(abs(xlim.new[1]),abs(xlim.new[2]))) 
            xd <- xd*sign(xlim.new[2])
            xd <-  union(union(xd, xlim.new), cut.point)
                 
            xd<- xd[xd!=0]
            xd<- xd[order(xd)]
        }
    
        bounds <- calcBias(x,x.levels=xd,alpha=alpha, type="proportional", percent=TRUE)  
     
        if(ci.area == TRUE | ci.border == TRUE)
        {	  
            if(is.null(ylim)==FALSE & add==FALSE)
            {
                yrange <- ylim
            } else  yrange<-range(bounds[,c("Prop.bias(%)","LCI","UCI")],na.rm=TRUE)
	
    	    if(add == FALSE) 
            {
                plot(0,0,cex=0, xlim=range(xd), ylim=yrange, xlab=xlab, 
                     ylab=ylab, main = main, sub="", bty="n", ...)
            } 
            else
            {
                subtext <- ""
                legend <- FALSE
                grid <- FALSE
                zeroline <- FALSE
            }
            
        #--
    
            if(ci.area == TRUE)
            {
                if (xlim.new[1]<0 & xlim.new[2]>0)
                {  
                    xxx.pos <- c(xd.pos,xd.pos[order(xd.pos,decreasing=TRUE)])
                    yy1.pos<-c(as.vector(bounds.pos[,"LCI"]))
                    yy2.pos<-c(as.vector(bounds.pos[,"UCI"]))
                    yyy.pos <-c(yy1.pos,yy2.pos[order(xd.pos,decreasing=TRUE)])
                    polygon(xxx.pos,yyy.pos,col=ci.area.col,border="white")

                    xxx.neg <- c(xd.neg,xd.neg[order(xd.neg,decreasing=TRUE)])
                    yy1.neg<-c(as.vector(bounds.neg[,"LCI"]))
                    yy2.neg<-c(as.vector(bounds.neg[,"UCI"]))
                    yyy.neg <-c(yy1.neg,yy2.neg[order(xd.neg,decreasing=TRUE)])
                    polygon(xxx.neg,yyy.neg,col=ci.area.col,border="white")      
                }
                else
                {                    
                    xxx <- c(xd,xd[order(xd,decreasing=TRUE)])
                    yy1<-c(as.vector(bounds[,"LCI"]))
                    yy2<-c(as.vector(bounds[,"UCI"]))
                    yyy <-c(yy1,yy2[order(xd,decreasing=TRUE)])
                    polygon(xxx,yyy,col=ci.area.col,border="white")
                } # end if (range(xd,rm.na)[1]<0 & range(xd,rm.na)[2]>0)
    
                if(add.grid== TRUE)  grid() 
            } #end if(ci.area == TRUE)
        
            if(ci.border == TRUE)
            {
                if (xlim.new[1]<0 & xlim.new[2]>0)
                {
                    points(xd.pos, bounds.pos[,"LCI"], lty=ci.border.lty,lwd=ci.border.lwd, col=ci.border.col, type="l")
      	            points(xd.neg, bounds.neg[,"UCI"], lty=ci.border.lty,lwd=ci.border.lwd, col=ci.border.col, type="l")
                    points(xd.pos, bounds.pos[,"UCI"], lty=ci.border.lty,lwd=ci.border.lwd, col=ci.border.col, type="l")
      	            points(xd.neg, bounds.neg[,"LCI"], lty=ci.border.lty,lwd=ci.border.lwd, col=ci.border.col, type="l")
                }
                else
                {
                    points(xd, bounds[,"LCI"], lty=ci.border.lty,lwd=ci.border.lwd, col=ci.border.col, type="l")
                    points(xd, bounds[,"UCI"], lty=ci.border.lty,lwd=ci.border.lwd, col=ci.border.col, type="l")
                } #end if (range(xd,rm.na)[1]<0 & range(xd,rm.na)[2]>0)
            } #end if(ci.border == TRUE)
            
            if(bias == TRUE) 
            {
                if (xlim.new[1]<0 & xlim.new[2]>0)
                {
                    points(xd.pos, bounds.pos[,"Prop.bias(%)"], col=bias.col, type="l", lwd=bias.lwd, lty=bias.lty)
                    points(xd.neg, bounds.neg[,"Prop.bias(%)"], col=bias.col, type="l", lwd=bias.lwd, lty=bias.lty)
                }
                else  points(xd, bounds[,"Prop.bias(%)"], col=bias.col, type="l", lwd=bias.lwd, lty=bias.lty)   
            } # end  if(bias == TRUE)
            
        }
        else
        { 
            if(zeroline == TRUE & is.null(ylim) & is.null(cut.point))   ylim <- range(c(100*(b0+b1*xd-xd)/xd, 0),na.rm=T) 
            if(zeroline == TRUE & is.null(ylim) & !is.null(cut.point))  ylim <- range(c(100*(b0+b1*xd-xd)/xd, 0,
                                                                           calcBias(x, x.levels=cut.point, 
                                                                           alpha=alpha, type="proportional", 
                                                                           percent=TRUE)[,c("Prop.bias(%)","LCI","UCI")]),na.rm=T) 
            if(zeroline == FALSE & is.null(ylim) & is.null(cut.point))  ylim <- range(100*(b0+b1*xd-xd)/xd) 
            if(zeroline == FALSE & is.null(ylim) & !is.null(cut.point)) ylim <- range(c(100*(b0+b1*xd-xd)/xd,
                                                                           calcBias(x, x.levels=cut.point, 
                                                                           alpha=alpha, type="proportional", 
                                                                           percent=TRUE)[,c("Prop.bias(%)","LCI","UCI")]),na.rm=T)
            if (add == FALSE)
            {
                if (xlim.new[1]<0 & xlim.new[2]>0)
                {
                    plot(xd.pos,100*(b0+b1*xd.pos-xd.pos)/xd.pos, main=main, col=bias.col, lty=bias.lty, ylim=ylim, 
                         lwd=bias.lwd, type="l",xlab=xlab,ylab=ylab,sub="",xlim=xlim.new,...)
                    points(xd.neg,100*(b0+b1*xd.neg-xd.neg)/xd.neg,col=bias.col, lty=bias.lty,  
                           lwd=bias.lwd, type="l")
                }
                else  plot(xd,100*(b0+b1*xd-xd)/xd, main=main, col=bias.col, lty=bias.lty, ylim=ylim, 
                           lwd=bias.lwd, type="l",xlab=xlab,ylab=ylab,sub="",...)
            }
            else
            {
                main <- ""
                subtext <- ""
                add.grid<- FALSE
                zeroline <- FALSE
                if (xlim[1]<0 & xlim[2]>0)
                {
                    points(xd.pos,100*(b0+b1*xd.pos-xd.pos)/xd.pos, main=main, col=bias.col, 
                    lty=bias.lty, ylim=ylim,lwd=bias.lwd, type="l",xlab=xlab,ylab=ylab,sub="",...)
                    points(xd.neg,100*(b0+b1*xd.neg-xd.neg)/xd.neg, main=main, col=bias.col, 
                    lty=bias.lty, ylim=ylim, lwd=bias.lwd, type="l",xlab=xlab,ylab=ylab,sub="",...)
                }
                else points(xd,100*(b0+b1*xd-xd)/xd, main=main, col=bias.col, 
                     lty=bias.lty, ylim=ylim,lwd=bias.lwd, type="l",xlab=xlab,ylab=ylab,sub="",...)
            }#end if (add=FALSE)
        } #end if(ci.area == TRUE | ci.border == TRUE)
                                 
        title(sub = subtext)       
        if(add.grid== TRUE) grid() 
        if(zeroline == TRUE) abline(h=0,lty=zeroline.lty, col=zeroline.col, lwd=zeroline.lwd)   
        if (!is.null(cut.point))
        {
            cut.point.y <- calcBias(x,x.levels=cut.point,alpha=alpha, type="proportional", percent=TRUE)
            for (ii in seq_along(cut.point)){
                     segments(cut.point[ii], cut.point.y[ii,"LCI"],cut.point[ii], cut.point.y[ii,"UCI"],
                     col=cut.point.col, lty=cut.point.lty,lwd=cut.point.lwd)
                     }
        }          
        if (xlim[1]<0 & xlim[2]>0) abline(v=0, lty=zeroline.lty, col=zeroline.col)
    } # end if (prop == TRUE)
    
    box()
}       


#' Print Summary of a Regression Analysis
#'
#' @param .Object object of type "MCResult".
#' @seealso \code{\link{getCoefficients}}, \code{\link{getRegmethod}}
#' @aliases printSummary summary
#' @return No return value
#' 
MCResult.printSummary <- function(.Object)
{
    print("MCResult virtual function")
    return(NULL)
}

#' Plot Residuals of an MCResult Object
#'
#' @param .Object object of type "MCResult".
#' @param res.type If res.type="y" the difference between the test method and it's prediction will be drawn. 
#' If res.type="x" the reference method and it's prediction will be drawn. 
#' In case ordinary and weighted ordinary linear regression 
#' this difference will be zero.  
#' @param xaxis Values on the x-axis. One can choose from estimated values of x (xaxis=\code{"xhat"}), 
#' y (xaxis=\code{"xhat"}) or the mean of estimated values of x and y (\code{xaxis="both"}).
#' If res.type="optimized" the proper type of residuals for each regression will be drawn. 
#' @param ref.line logical value. If \code{ref.line = TRUE} (default), the reference line will be drawn.
#' @param ref.line.col reference line color.
#' @param ref.line.lty reference line type.
#' @param ref.line.lwd reference line width.
#' @param xlab label for the x-axis
#' @param ylab label for the y-axis
#' @param add.grid logical value. If \code{add.grid = TRUE} (default) the gridlines will be drawn.
#' @param main character string specifying the main title of the plot
#' @param ... further graphical parameters
#' @seealso \code{\link{getResiduals}}, \code{\link{plot.mcr}}, \code{\link{plotDifference}}, \code{\link{plotBias}}, \code{\link{compareFit}}
#' @aliases plotResiduals
#' @return No return value, instead a plot is generated
#' @examples
#'     data(creatinine,package="mcr")
#'     x <- creatinine$serum.crea
#'     y <- creatinine$plasma.crea
#' 
#'     # Deming regression fit.
#'     # The confidence intercals for regression coefficients
#'     # are calculated with analytical method
#'     model <- mcreg( x,y,error.ratio=1,method.reg="WDeming", method.ci="jackknife",
#'                      mref.name = "serum.crea", mtest.name = "plasma.crea", na.rm=TRUE )
#'     plotResiduals(model, res.type="optimized", xaxis="both" )
#'     plotResiduals(model, res.type="y", xaxis="yhat")
MCResult.plotResiduals<-function(.Object, res.type=c("optimized", "y", "x"),
                                    xaxis=c("yhat","both","xhat"),
                                    ref.line=TRUE,
                                    ref.line.col="red",
                                    ref.line.lty=2,
                                    ref.line.lwd=1,
                                    main=NULL,
                                    xlab=NULL,
                                    ylab=NULL,
                                    add.grid=TRUE,
                                    ...)
{    
    res.type <- match.arg(res.type)
    xaxis <- match.arg(xaxis)
    res <- getResiduals(.Object)
    r <- res[,res.type]
    if (xaxis=="yhat") est <- getData(.Object)[,"Y"]- res[,"y"]
    if (xaxis=="xhat") est <- getData(.Object)[,"X"]- res[,"x"]
    if (xaxis=="both") est <- ((getData(.Object)[,"X"]- res[,"x"])+(getData(.Object)[,"Y"]- res[,"y"]))/2
    
    if(is.null(main))
    {
        if(.Object@regmeth == "LinReg")
		    titname <- "Linear Regression"
        else if(.Object@regmeth == "WLinReg")
		    titname <- "Weighted Linear Regression"
        else if(.Object@regmeth == "Deming")
		    titname <- "Deming Regression"
  	    else if(.Object@regmeth == "TS")
            titname<-"Theil-Sen Regression"
	    else if(.Object@regmeth == "PBequi")
            titname<-"Equivariant Passing-Bablok Regression"
        else if(.Object@regmeth == "WDeming")
            titname <- "Weighted Deming Regression"
        else
            titname <- "Passing Bablok Regression"

        main <- paste("Residual plot for", titname,"Fit"  ) 
    }
    if(is.null(ylab)) 
    {
        if ( res.type=="x") ylab <- paste("Residuals (",.Object@mnames[1],")", sep="")
        if ( res.type=="y") ylab <- paste("Residuals (",.Object@mnames[2],")", sep="")
        if ( res.type=="optimized") ylab <- "Optimized residuals"
    } else{}    
    if(is.null(xlab))
    {     
        if (xaxis=="yhat") xlab <- paste("Estimated values of",.Object@mnames[2])
        if (xaxis=="xhat") xlab <- paste("Estimated values of",.Object@mnames[1])
        if (xaxis=="both") xlab <- paste("Mean of estimated values of both methods")   
    }
    plot(est,r,main=main,xlab=xlab,ylab=ylab, ...)
    
    if(add.grid == TRUE) 
        grid()
    if(ref.line == TRUE) 
        abline(h=0, col=ref.line.col, lty=ref.line.lty, lwd=ref.line.lwd)
}

Try the mcr package in your browser

Any scripts or data that you put into this service are public.

mcr documentation built on Sept. 23, 2024, 5:10 p.m.