Nothing
##################################################################################
# MixmodResults.R ##
##################################################################################
#' @include global.R
#' @include Parameter.R
NULL
#' Constructor of [\code{\linkS4class{MixmodResults}}] class
#'
#' This is a class to contain results from MIXMOD library.
#'
#' \describe{
#' \item{nbCluster}{integer. It indicates the number of components.}
#' \item{model}{character. Name of the model.}
#' \item{criterion}{list of character. This option permits to select the criterion giving the best configuration of
#' an execution.}
#' \item{criterionValue}{numeric. Values of the criterion.}
#' \item{parameters}{a S4 [\code{\linkS4class{Parameter}}] object. The best model parameters.}
#' \item{likelihood}{numeric. The model likelihood.}
#' \item{partition}{vector of integers defining the partition.}
#' \item{proba}{a matrix of probabilities.}
#' \item{error}{a character. The mixmod error.}
#' }
#'
#' @examples
#' getSlots("MixmodResults")
#' @name MixmodResults-class
#' @rdname MixmodResults-class
#' @exportClass MixmodResults
#'
setClass(
Class = "MixmodResults",
representation = representation(
nbCluster = "numeric",
model = "character",
criterion = "character",
criterionValue = "numeric",
parameters = "Parameter",
likelihood = "numeric",
partition = "integer",
proba = "matrix",
error = "character"
),
prototype = prototype(
nbCluster = numeric(0),
model = character(0),
criterion = character(0),
criterionValue = numeric(0),
likelihood = numeric(0),
partition = integer(0),
proba = matrix(nrow = 0, ncol = 0),
error = character(0)
)
)
#' @rdname print-methods
#' @aliases print print,MixmodResults-method
#'
setMethod(
f = "print",
signature = c("MixmodResults"),
function(x, ...) {
cat("* nbCluster = ", x@nbCluster, "\n")
cat("* model name = ", x@model, "\n")
if (x@error == "No error") {
cat("* criterion = ", paste(x@criterion, "(", formatC(x@criterionValue, digits = 4, format = "f"), ")", sep = ""))
cat("\n")
cat("* likelihood = ", formatC(x@likelihood, digits = 4, format = "f"), "\n")
print(x@parameters)
} else {
cat("* No results. MIXMOD library stopped with following error: ", x@error, "!\n")
}
}
)
#' @rdname show-methods
#' @aliases show show,MixmodResults-method
#'
setMethod(
f = "show",
signature = c("MixmodResults"),
function(object) {
cat("* nbCluster = ", object@nbCluster, "\n")
cat("* model name = ", object@model, "\n")
if (object@error == "No error") {
cat("* criterion = ", paste(object@criterion, "(", formatC(object@criterionValue, digits = 4, format = "f"), ")",
sep = ""
))
cat("\n")
cat("* likelihood = ", formatC(object@likelihood, digits = 4, format = "f"), "\n")
show(object@parameters)
} else {
cat("* No results. MIXMOD library stopped with the following error: ", object@error, "!\n")
}
}
)
#' @rdname summary-methods
#' @aliases summary summary,MixmodResults-method
#'
setMethod(
f = "summary",
signature = c("MixmodResults"),
function(object, ...) {
cat("**************************************************************\n")
cat("* Number of cluster = ", object@nbCluster, "\n")
cat("* Model Type = ", object@model, "\n")
if (object@error == "No error") {
cat("* Criterion = ", paste(object@criterion, "(", formatC(object@criterionValue,
digits = 4,
format = "f"
), ")", sep = ""))
cat("\n")
cat("* Parameters = list by cluster\n")
summary(object@parameters)
cat("* Log-likelihood = ", formatC(object@likelihood, digits = 4, format = "f"), "\n")
} else {
cat("* No results. MIXMOD library stopped with the following error: ", object@error, "!\n")
}
cat("**************************************************************\n")
}
)
#' Define function to draw an ellipse
#'
#' @param x an object of class [\code{\linkS4class{MixmodResults}}]
#' @param i an index of one variable from data
#' @param j an index of one variable from data
#'
#' @keywords internal
#'
ellipse <- function(x, i, j) {
parameters <- x@parameters
factor <- NULL
if (is(x@parameters, "CompositeParameter")) {
parameters <- x@parameters@g_parameter
factor <- x@parameters@factor
i <- i - length(which(factor[1:i] > 0))
j <- j - length(which(factor[1:j] > 0))
}
# loop over the cluster
for (k in 1:x@nbCluster) {
angles <- seq(0, 2 * pi, length.out = 200)
ctr <- c(parameters@mean[k, i], parameters@mean[k, j])
A <- matrix(c(
parameters@variance[[k]][i, i], parameters@variance[[k]][j, i], parameters@variance[[k]][i, j],
parameters@variance[[k]][j, j]
), nrow = 2)
eigVal <- eigen(A)$values
eigVec <- eigen(A)$vectors
eigScl <- eigVec %*% diag(sqrt(eigVal)) # scale eigenvectors to length = square-root
xMat <- rbind(ctr[1] + eigScl[1, ], ctr[1] - eigScl[1, ])
yMat <- rbind(ctr[2] + eigScl[2, ], ctr[2] - eigScl[2, ])
ellBase <- cbind(sqrt(eigVal[1]) * cos(angles), sqrt(eigVal[2]) * sin(angles)) # normal ellipse
ellRot <- eigVec %*% t(ellBase) # rotated ellipse
lines((ellRot + ctr)[1, ], (ellRot + ctr)[2, ], asp = 1, type = "l", lwd = 2)
matlines(xMat, yMat, col = 1, lty = 2, lwd = 1)
points(ctr[1], ctr[2], pch = 4, lwd = 3)
}
}
#' Plotting of a class [\code{\linkS4class{MixmodResults}}]
#'
#' Biplot of two variables from a quantitative data set. Use parameters and partition from a
#' [\code{\linkS4class{MixmodResults}}] object to distinguish the different clusters.
#'
#' Ellipsoids (i.e. linear transformations of hyperspheres)
#' centered at the mean can be drawn using the parameters computed by MIXMOD.
#' The directions of the principal axes of the ellipsoids are given by the eigenvectors of the covariance matrix \eqn{\Sigma}.
#' The squared relative lengths of the principal axes are given by the corresponding eigenvalues.
#'
#' @param x an object of class [\code{\linkS4class{MixmodResults}}]
#' @param data a data frame containing a quantitative data set.
#' @param variable1 index or character containing the name of the first variable. First column of data by default.
#' @param variable2 index or character containing the name of the second variable. Second column of data by default.
#' @param col a specification for the default plotting color. By default partition is used to separate clusters with
#' different colors.
#' @param pch either an integer specifying a symbol or a single character to be used as the default in plotting points. By
#' default partition is used to separate clusters with different symbols.
#' @param xlab a title for the x axis. Variable1 by default.
#' @param ylab a title for the y axis. Variable2 by default.
#' @param add.ellipse a boolean. Add ellipses to graph. TRUE by default.
#' @param ... further arguments passed to or from other methods
#'
#' @examples
#' data(geyser)
#' xem1 <- mixmodCluster(geyser, 3)
#' plotCluster(xem1["bestResult"], geyser)
#'
#' data(iris)
#' xem2 <- mixmodCluster(iris[1:4], 2:6)
#' plotCluster(xem2["bestResult"], iris, variable1 = "Sepal.Length", variable2 = "Sepal.Width")
#' plotCluster(xem2["bestResult"], iris, variable1 = 1, variable2 = 4)
#' @seealso \code{\link{plot}}
#' @export
#'
plotCluster <- function(x, data, variable1 = colnames(data)[1], variable2 = colnames(data)[2], col = x@partition + 1,
pch = x@partition, xlab = variable1, ylab = variable2, add.ellipse = TRUE, ...) {
if (!is(x, "MixmodResults")) {
stop("x must be a MixmodResults object!")
}
# if ( !is(x@parameters, "GaussianParameter") )
if (!.is_quantitative_alike2(x, data, c(variable1, variable2))) {
stop("x must contains Gaussian parameters!")
}
if (!is.matrix(data) && !is.data.frame(data)) {
stop("data must be a data.frame or a matrix object!")
}
# get variable1 index
if (is.numeric(variable1)) {
if (variable1 > ncol(data)) {
stop("variable1 index mismatch the data frame dimension")
} else {
index1 <- variable1
xlab <- colnames(data)[variable1]
}
} else {
if (!(variable1 %in% colnames(data))) {
stop("variable1 is unknown!")
} else {
index1 <- which(colnames(data) == variable1)
}
}
# get variable2 index
if (is.numeric(variable2)) {
if (variable2 > ncol(data)) {
stop("variable2 index mismatch the data frame dimension")
} else {
index2 <- variable2
ylab <- colnames(data)[variable2]
}
} else {
if (!(variable2 %in% colnames(data))) {
stop("variable2 is unknown!")
} else {
index2 <- which(colnames(data) == variable2)
}
}
plot(data[, index1], data[, index2], col = col, pch = pch, xlab = xlab, ylab = ylab, ...)
if (add.ellipse) ellipse(x, index1, index2)
}
#' Histogram of a class [\code{\linkS4class{MixmodResults}}]
#'
#' Histograms of data object using parameters from a [\code{\linkS4class{MixmodResults}}]
#' to plot densities.
#'
#' Data with the density of each cluster and the mixture density are drawn for each variable.
#'
#' @param x an object of class [\code{\linkS4class{MixmodResults}}]
#' @param data a vector or data frame containing a quantitative data set.
#' @param variables list of variables names (or indices) to compute a histogram. All variables from data by default.
#' @param xlab a list of title for the x axis. xlab must have the same length than variables.
#' @param main a list of title for the histogram. main must have the same length than variables.
#' @param hist_x_dim Dimension of the histogram (???)
#' @param ... further arguments passed to or from other methods
#'
#' @examples
#' data(geyser)
#' xem1 <- mixmodCluster(geyser, 3)
#' \dontrun{
#' histCluster(xem1["bestResult"], geyser)
#' }
#' histCluster(xem1["bestResult"], geyser, variables = 1)
#' @seealso \code{\link{hist}}
#' @export
#'
histCluster <- function(x, data, variables = colnames(data), xlab = rep("", length(variables)),
main = paste("Histogram of", variables), hist_x_dim = 10000, ...) {
# check the options
if (!is(x, "MixmodResults")) {
stop("'x' must be a MixmodResults object!")
}
if (!is.matrix(data) && !is.data.frame(data) && !is.vector(data)) {
stop("'data' must be a vector or a data.frame or a matrix object!")
}
if ((length(variables) == 0) && (ncol(data) > 1)) {
stop("'variables' is empty!")
}
if (length(variables) > ncol(data)) {
stop("List of variables too long!")
}
if (!missing(main) && (length(main) != length(variables))) {
stop("'main' must be a vector of strings. It's size must be the same as 'variables' size")
}
# get the indices of variables
if (is.numeric(variables)) {
if (max(variables) > ncol(data)) {
stop("At least one variable index mismatch the data frame dimension")
} else {
indices <- variables
if (missing(main)) {
main <- paste("Histogram of", colnames(data)[variables])
}
}
} else {
if (sum(!(variables %in% colnames(data)))) {
stop("At least one variable is unknown!")
} else {
if (ncol(data) == 1) {
indices <- 1
} else {
indices <- which(colnames(data) %in% variables)
}
if (missing(main)) {
main <- paste("Histogram of", variables)
}
}
}
nvar <- length(indices)
# get old par
op <- par(no.readonly = TRUE) # the whole list of settable par's.
# && is.dataType(data.frame(x@data)[y]) == "quantitative"
# if (is(x@parameters, "GaussianParameter") || (is(x@parameters, "CompositeParameter"
# ) && is.dataType(data.frame(data)[variables])=="quantitative")) {
# if (is(x@parameters, "GaussianParameter")) {
if (.is_quantitative_alike2(x, data, variables)) {
# if ( isQualitative(data) )
# stop("data must contain only quantitative variables!")
parameters <- x@parameters
factor <- NULL
if (is(x@parameters, "CompositeParameter")) {
parameters <- x@parameters@g_parameter
factor <- x@parameters@factor
}
# split the layout
if ((nvar < 4) && (nvar > 1)) {
par(mfrow = c(1, nvar))
} else if (nvar >= 4) {
nrow <- round(sqrt(nvar))
if (is.wholenumber(sqrt(nvar))) {
ncol <- sqrt(nvar)
} else {
ncol <- sqrt(nvar) + 1
}
par(mfrow = c(nrow, ncol))
}
i <- 1
# loop over variables
print(indices)
for (j in indices) {
xaxis <- seq(min(data[, j]), max(data[, j]), length = hist_x_dim)
# xaxis<-seq(min(data[,j]),max(data[,j]),by=0.0001)
density <- matrix(nrow = x@nbCluster, ncol = length(xaxis))
# loop over the clusters to generate densities
for (k in 1:x@nbCluster) {
corr_j <- j
if (is(x@parameters, "CompositeParameter")) corr_j <- j - length(which(factor[1:j] > 0))
density[k, ] <- parameters["proportions", k] * dnorm(
xaxis, parameters["mean", k][corr_j],
sqrt(parameters["variance", k][corr_j, corr_j])
)
}
# generate mixture density
# mixture<-apply(density,2,sum)
mixture <- colSums(density)
h <- hist(data[, j], xlab = xlab[i], main = main[i], ...)
ratio <- max(h$counts) / max(mixture)
density <- density * ratio
mixture <- mixture * ratio
lines(xaxis, mixture, col = "azure4", lty = 1, lwd = 4)
for (k in 1:x@nbCluster) {
lines(xaxis, density[k, ], col = k + 1, lty = 2, lwd = 2)
}
i <- i + 1
}
} else if (is(x@parameters, "MultinomialParameter")) {
stop("x must contain Gaussian parameters. See barplot() to plot multinomial parameters.")
} else if (is(x@parameters, "CompositeParameter")) {
stop("x must contain Gaussian parameters. No plot device for composite parameters.")
} else {
stop("Uknown type of parameters!")
}
par(op)
}
#' Barplot of a class [\code{\linkS4class{MixmodResults}}]
#'
#' Barplot of qualitative data object using parameters from a [\code{\linkS4class{MixmodResults}}]
#' to plot probabilities of modalities.
#'
#' Each line corresponds to one variable. A barplot is drawn for each cluster with the probabilities for
#' each modality to be in that cluster.
#'
#' @param x an object of class [\code{\linkS4class{MixmodResults}}]
#' @param data a vector or data frame containing a qualitative data set.
#' @param variables list of variables names (or indices) to compute a barplot. All variables from data by default.
#' @param main a list of title for the barplot. main must have the same length than variables.
#' @param ... further arguments passed to or from other methods
#'
#' @examples
#' data(birds)
#' xem <- mixmodCluster(birds, 2)
#' barplotCluster(xem["bestResult"], birds)
#' barplotCluster(xem["bestResult"], birds, variables = c(2, 3, 4))
#' barplotCluster(xem["bestResult"], birds, variables = c("eyebrow", "collar"))
#' @seealso \code{\link{barplot}}
#' @export
#'
barplotCluster <- function(x, data, variables = colnames(data), main = paste("Barplot of", variables), ...) {
# check the options
if (!is(x, "MixmodResults")) {
stop("'x' must be a MixmodResults object!")
}
if (!is.matrix(data) && !is.data.frame(data) && !is.vector(data)) {
stop("'data' must be a vector, a data.frame or a matrix object!")
}
if ((length(variables) == 0) && (ncol(data) > 1)) {
stop("'variables' is empty!")
}
if (length(variables) > ncol(data)) {
stop("List of variables too long!")
}
# get the indices of variables
if (is.numeric(variables)) {
if (max(variables) > ncol(data)) {
stop("At least one variable index mismatch the data frame dimension")
} else {
indices <- variables
main <- paste("Barplot of", colnames(data)[variables])
}
} else {
if (sum(!(variables %in% colnames(data)))) {
stop("At least one variable is unknown!")
} else {
if (ncol(data) == 1) {
indices <- 1
} else {
indices <- which(colnames(data) %in% variables)
}
}
}
nvar <- length(indices)
# get old par
op <- par(no.readonly = TRUE) # the whole list of settable par's.
if (is(x@parameters, "GaussianParameter")) {
stop("x must contain multinomial parameters. See hist() to plot Gaussian parameters.")
} else if (is(x@parameters, "MultinomialParameter")) {
if (!isQualitative(data)) {
stop("data must contain only qualitative variables!")
}
if (is.factor(data)) {
data <- as.integer(data)
} else if (!is.vector(data)) {
# loop over columns to check whether type is factor
for (j in seq_len(ncol(data))) {
if (is.factor(data[, j])) data[, j] <- as.integer(data[, j])
}
}
# split the layout
# par( mfrow = c( nvar, x@nbCluster+1 ) )
# par(mar = par("mar")*.75)
# split the layout
if ((nvar < 4) && (nvar > 1)) {
par(mfrow = c(1, nvar))
} else if (nvar >= 4) {
nrow <- round(sqrt(nvar))
if (is.wholenumber(sqrt(nvar))) {
ncol <- sqrt(nvar)
} else {
ncol <- sqrt(nvar) + 1
}
par(mfrow = c(nrow, ncol))
}
# get number of observations
nobs <- nrow(data)
i <- 1
# loop over variables
for (j in indices) {
f <- x@parameters@factor[j]
t <- table(data[, j])
if (f != length(t)) {
g <- numeric(f)
g[which(1:f %in% names(t))] <- t
t <- g
}
names(t) <- 1:f
# freq<-barplot(as.vector(t), names.arg=names(t), xlab=xlab[i], main="", ...)
proba <- matrix(0, nrow = x@nbCluster, ncol = f)
for (k in 1:x@nbCluster) {
center_k <- x@parameters@center[k, j]
proba_k <- x@parameters@scatter[[k]][j, ]
proba_k[center_k] <- 1 - proba_k[center_k]
proba[k, ] <- proba_k[1:f]
# prob<-barplot(proba_k[1:f], names.arg=names(t), main="", col=k+1, ylim=c(0,1), ...)
# title(paste("Cluster",k),cex.main=1)
# text(prob,proba_k[1:f]+(max(proba_k)/10),ifelse(proba_k[1:f]<0.01,format(proba_k[1:f],
# scientific=TRUE,digits=2),round(proba_k[1:f],2)),xpd=TRUE,font=2)
}
# Do the barplot and save the bar midpoints
mp <- barplot(proba,
beside = TRUE, axisnames = FALSE, names.arg = names(t), main = "",
ylab = "Conditional frequency", ylim = c(0, 1)
)
# add unconditional frequencies
for (k in 1:f) {
lines(c(min(mp[, k]) - 1, max(mp[, k]) + 1), rep(t[k] / nobs, 2), lty = 2)
}
# add unconditional frequency legend only for the first variable
if (i == 1) {
text(min(mp[, 1]) - .5, t[1] / nobs, labels = "Unconditional frequency", cex = 1, pos = 4, adj = c(0, 0), font = 2)
}
# add title
title(main[i], cex.main = 1)
# Add the individual bar labels
mtext(1, at = mp, text = paste("C", 1:x@nbCluster), line = 0, cex = 0.5)
# Add the group labels for each pair
# mtext(1, at = rbind(mp[1,],colMeans(mp[-1,])), text = rep(c("freq", "proba"), f), line = 1, cex = 0.75)
# Add the labels for each group
mtext(1, at = colMeans(mp), text = names(t), line = 2)
i <- i + 1
}
} else if (is(x@parameters, "CompositeParameter")) {
stop("x must contain multinomial parameters. No plot device for composite parameters.")
} else {
stop("Uknown type of parameters!")
}
par(op)
}
#' @rdname extract-methods
#' @aliases [,MixmodResults-method
#'
setMethod(
f = "[",
signature(x = "MixmodResults"),
definition = function(x, i, j, drop) {
if (missing(j)) {
switch(EXPR = i,
"nbCluster" = {
return(x@nbCluster)
},
"criterion" = {
return(x@criterion)
},
"criterionValue" = {
return(x@criterionValue)
},
"model" = {
return(x@model)
},
"likelihood" = {
return(x@likelihood)
},
"parameters" = {
return(x@parameters)
},
"partition" = {
return(x@partition)
},
"proba" = {
return(x@proba)
},
"error" = {
return(x@error)
},
stop("This attribute doesn't exist !")
)
} else {
switch(EXPR = i,
"criterion" = {
return(x@criterion[j])
},
"criterionValue" = {
return(x@criterionValue[j])
},
stop("This attribute doesn't exist !")
)
}
}
)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.