From b4739ba14c5472a23cb3e334d55989f7fbb0afe2 Mon Sep 17 00:00:00 2001 From: Johannes Ranke Date: Mon, 28 Apr 2014 17:59:10 +0200 Subject: Option to add residual plot to plot.mkinfit --- R/mkinresplot.R | 29 ++++++++++++++--------------- R/plot.mkinfit.R | 28 +++++++++++++++++++++++++++- inst/GUI/gmkin.R | 11 ++--------- man/mkinresplot.Rd | 11 +++++++---- man/plot.mkinfit.Rd | 14 ++++++++++++-- 5 files changed, 62 insertions(+), 31 deletions(-) diff --git a/R/mkinresplot.R b/R/mkinresplot.R index 524ba78..07bd7df 100644 --- a/R/mkinresplot.R +++ b/R/mkinresplot.R @@ -1,7 +1,5 @@ -# $Id$ - -# Copyright (C) 2008-2011 Katrin Lindenberger and Johannes Ranke -# Contact: mkin-devel@lists.berlios.de +# Copyright (C) 2008-2014 Johannes Ranke +# Contact: jranke@uni-bremen.de # This file is part of the R package mkin @@ -19,36 +17,37 @@ # this program. If not, see if(getRversion() >= '2.15.1') utils::globalVariables(c("variable", "residual")) -mkinresplot <- function (object, obs_vars = vector(), +mkinresplot <- function (object, + obs_vars = names(object$mkinmod$map), xlab = "Time", ylab = "Residual", maxabs = "auto", legend= TRUE, lpos = "topright", ...) { obs_vars_all <- as.character(unique(object$data$variable)) if (length(obs_vars) > 0){ - vars <- intersect(obs_vars_all, obs_vars) - } else vars <- obs_vars_all + obs_vars <- intersect(obs_vars_all, obs_vars) + } else obs_vars <- obs_vars_all - residuals <- subset(object$data, variable %in% vars, residual) + residuals <- subset(object$data, variable %in% obs_vars, residual) if (maxabs == "auto") maxabs = max(abs(residuals), na.rm = TRUE) - col_obs <- pch_obs <- 1:length(vars) - names(col_obs) <- names(pch_obs) <- vars + col_obs <- pch_obs <- 1:length(obs_vars) + names(col_obs) <- names(pch_obs) <- obs_vars plot(0, xlab = xlab, ylab = ylab, xlim = c(0, 1.1 * max(object$data$time)), ylim = c(-1.2 * maxabs, 1.2 * maxabs), ...) - for(var in vars){ - residuals_plot <- subset(object$data, variable == var, c("time", "residual")) - points(residuals_plot, pch = pch_obs[var], col = col_obs[var]) + for(obs_var in obs_vars){ + residuals_plot <- subset(object$data, variable == obs_var, c("time", "residual")) + points(residuals_plot, pch = pch_obs[obs_var], col = col_obs[obs_var]) } abline(h = 0, lty = 2) if (legend == TRUE) { - legend(lpos, inset = c(0.05, 0.05), legend = vars, - col = col_obs, pch = pch_obs) + legend(lpos, inset = c(0.05, 0.05), legend = obs_vars, + col = col_obs[obs_vars], pch = pch_obs[obs_vars]) } } diff --git a/R/plot.mkinfit.R b/R/plot.mkinfit.R index 80cf45f..23eb30f 100644 --- a/R/plot.mkinfit.R +++ b/R/plot.mkinfit.R @@ -21,13 +21,20 @@ plot.mkinfit <- function(x, fit = x, obs_vars = names(fit$mkinmod$map), xlab = "Time", ylab = "Observed", xlim = range(fit$data$time), - ylim = c(0, max(subset(fit$data, variable %in% obs_vars)$observed, na.rm = TRUE)), + ylim = "default", col_obs = 1:length(fit$mkinmod$map), pch_obs = col_obs, lty_obs = rep(1, length(fit$mkinmod$map)), add = FALSE, legend = !add, + show_residuals = FALSE, maxabs = "auto", lpos = "topright", inset = c(0.05, 0.05), ...) { + if (add && show_residuals) stop("If adding to an existing plot we can not show residuals") + + if (ylim == "default") { + ylim = c(0, max(subset(fit$data, variable %in% obs_vars)$observed, na.rm = TRUE)) + } + solution_type = fit$solution_type parms.all <- c(fit$bparms.optim, fit$bparms.fixed) @@ -52,6 +59,10 @@ plot.mkinfit <- function(x, fit = x, # Set up the plot if not to be added to an existing plot if (add == FALSE) { + if (show_residuals) { + layout(matrix(c(1, 2), 2, 1), heights = c(2, 1.3)) + par(mar = c(3, 4, 4, 2) + 0.1) + } plot(0, type="n", xlim = xlim, ylim = ylim, xlab = xlab, ylab = ylab, ...) @@ -67,4 +78,19 @@ plot.mkinfit <- function(x, fit = x, legend(lpos, inset= inset, legend = obs_vars, col = col_obs[obs_vars], pch = pch_obs[obs_vars], lty = lty_obs[obs_vars]) } + # Show residuals if requested + if (show_residuals) { + par(mar = c(5, 4, 0, 2) + 0.1) + residuals <- subset(fit$data, variable %in% obs_vars, residual) + if (maxabs == "auto") maxabs = max(abs(residuals), na.rm = TRUE) + plot(0, type="n", + xlim = xlim, + ylim = c(-1.2 * maxabs, 1.2 * maxabs), + xlab = xlab, ylab = ylab) + for(obs_var in obs_vars){ + residuals_plot <- subset(fit$data, variable == obs_var, c("time", "residual")) + points(residuals_plot, pch = pch_obs[obs_var], col = col_obs[obs_var]) + } + abline(h = 0, lty = 2) + } } diff --git a/inst/GUI/gmkin.R b/inst/GUI/gmkin.R index 422be57..4d33b35 100644 --- a/inst/GUI/gmkin.R +++ b/inst/GUI/gmkin.R @@ -698,19 +698,12 @@ plot_ftmp_png <- function() { obs_vars_plot = names(ftmp$mkinmod$spec) } png(tf, width = 525, height = 600) - layout(matrix(c(1, 2), 2, 1), heights = c(2, 1.3)) - par(mar = c(3, 4, 4, 2) + 0.1) plot(ftmp, main = ftmp$ds$title, obs_vars = obs_vars_plot, xlab = ifelse(ftmp$ds$time_unit == "", "Time", paste("Time in", ftmp$ds$time_unit)), ylab = ifelse(ds[[ds.i]]$unit == "", "Observed", - paste("Observed in", ftmp$ds$unit))) - par(mar = c(5, 4, 0, 2) + 0.1) - mkinresplot(ftmp, legend = FALSE, obs_vars = obs_vars_plot, - xlab = ifelse(ftmp$ds$time_unit == "", "Time", - paste("Time in", ftmp$ds$time_unit)), - ylab = ifelse(ds[[ds.i]]$unit == "", "Observed", - paste("Residuals in", ftmp$ds$unit))) + paste("Observed in", ftmp$ds$unit)), + show_residuals = TRUE) dev.off() return(tf) } diff --git a/man/mkinresplot.Rd b/man/mkinresplot.Rd index 8e3f18a..3f53dd1 100644 --- a/man/mkinresplot.Rd +++ b/man/mkinresplot.Rd @@ -5,10 +5,13 @@ } \description{ This function plots the residuals for the specified subset of the - observed variables from an mkinfit object. + observed variables from an mkinfit object. A combined plot of the fitted + model and the residuals can be obtained using \code{\link{plot.mkinfit}} + using the argument \code{show_residuals = TRUE}. } \usage{ - mkinresplot(object, obs_vars = vector(), + mkinresplot(object, + obs_vars = names(object$mkinmod$map), xlab = "Time", ylab = "Residual", maxabs = "auto", legend = TRUE, lpos = "topright", ...) } @@ -18,7 +21,7 @@ } \item{obs_vars}{ A character vector of names of the observed variables for which residuals - should be plotted. + should be plotted. Defaults to all observed variables in the model } \item{xlab}{ Label for the x axis. Defaults to "Time [days]". @@ -44,7 +47,7 @@ Nothing is returned by this function, as it is called for its side effect, namely to produce a plot. } \author{ - Katrin Lindenberger and Johannes Ranke + Johannes Ranke } \seealso{ diff --git a/man/plot.mkinfit.Rd b/man/plot.mkinfit.Rd index 4ae82a5..7009e7d 100644 --- a/man/plot.mkinfit.Rd +++ b/man/plot.mkinfit.Rd @@ -12,10 +12,13 @@ \method{plot}{mkinfit}(x, fit = x, obs_vars = names(fit$mkinmod$map), xlab = "Time", ylab = "Observed", - xlim = range(fit$data$time), ylim = c(0, max(fit$data$observed, na.rm = TRUE)), + xlim = range(fit$data$time), + ylim = "default", col_obs = 1:length(fit$mkinmod$map), pch_obs = col_obs, lty_obs = rep(1, length(fit$mkinmod$map)), - add = FALSE, legend = !add, lpos = "topright", inset = c(0.05, 0.05), ...) + add = FALSE, legend = !add, + show_residuals = FALSE, maxabs = "auto", + lpos = "topright", inset = c(0.05, 0.05), \dots) } \arguments{ \item{x}{ @@ -56,6 +59,13 @@ \item{legend}{ should a legend be added to the plot? } + \item{show_residuals}{ + should residuals be shown in the lower third of the plot? + } + \item{maxabs}{ + Maximum absolute value of the residuals. This is used for the scaling of + the y axis and defaults to "auto". + } \item{lpos}{ position of the legend. Passed to \code{\link{legend}} as the first argument. } -- cgit v1.2.1