Nothing
#' Create SSIM (Structural Self-Interaction Matrix)
#'
#' Creates an empty SSIM template or converts existing data to SSIM format.
#' SSIM uses V/A/X/O notation to describe pairwise relationships between elements.
#'
#' @param n Number of elements, or a character vector of element names.
#' @param labels Optional character vector of element labels. If \code{n} is
#' a character vector, this parameter is ignored.
#'
#' @return A character matrix of dimension n x n with:
#' \itemize{
#' \item Upper triangle: empty strings (to be filled with V/A/X/O)
#' \item Diagonal: "X" (self-relation)
#' \item Lower triangle: "-" (mirror of upper, not used directly)
#' }
#'
#' @details
#' SSIM (Structural Self-Interaction Matrix) is the standard input format for
#' ISM analysis. For each pair of elements (i, j) where i < j, the relationship
#' is coded as:
#'
#' \describe{
#' \item{V}{Element i influences element j (i -> j)}
#' \item{A}{Element j influences element i (j -> i)}
#' \item{X}{Both elements influence each other (i <-> j)}
#' \item{O}{No relationship between elements}
#' }
#'
#' @seealso
#' \code{\link{ssim_to_matrix}} for converting SSIM to adjacency matrix,
#' \code{\link{create_relation_matrix}} for direct matrix creation.
#'
#' @export
#' @examples
#' # Create empty 4x4 SSIM
#' ssim <- create_ssim(4)
#' print(ssim)
#'
#' # Create with labels
#' ssim <- create_ssim(c("Budget", "Resources", "Quality", "Success"))
#' print(ssim)
#'
#' # Fill in relationships
#' ssim["Budget", "Resources"] <- "V"
#' ssim["Budget", "Quality"] <- "V"
#' ssim["Resources", "Quality"] <- "V"
#' ssim["Quality", "Success"] <- "V"
#' print(ssim)
create_ssim <- function(n, labels = NULL) {
# Handle character vector input
if (is.character(n)) {
labels <- n
n <- length(labels)
}
if (!is.numeric(n) || length(n) != 1 || n < 2) {
stop("n must be a single integer >= 2 or a character vector of labels",
call. = FALSE)
}
n <- as.integer(n)
# Generate labels if not provided
if (is.null(labels)) {
labels <- paste0("E", seq_len(n))
}
if (length(labels) != n) {
stop("Length of labels must equal n", call. = FALSE)
}
# Create empty SSIM matrix
ssim <- matrix("", nrow = n, ncol = n)
rownames(ssim) <- colnames(ssim) <- labels
# Set diagonal to X (self-relation)
diag(ssim) <- "X"
# Set lower triangle to "-" (not used directly)
ssim[lower.tri(ssim)] <- "-"
class(ssim) <- c("ssim_matrix", "matrix")
return(ssim)
}
#' Convert SSIM to Adjacency Matrix
#'
#' Converts a Structural Self-Interaction Matrix (SSIM) with V/A/X/O notation
#' to a binary adjacency matrix suitable for ISM analysis.
#'
#' @param ssim A square character matrix with V/A/X/O values in the upper triangle.
#' Can be created using \code{\link{create_ssim}}.
#' @param validate Logical. If \code{TRUE} (default), validates that all upper
#' triangle entries are valid (V/A/X/O).
#'
#' @return A square numeric adjacency matrix where:
#' \itemize{
#' \item 1 at position (i,j) indicates element i influences element j
#' \item 0 indicates no direct influence
#' }
#'
#' @details
#' The conversion rules are:
#' \describe{
#' \item{V at (i,j)}{Sets adj[i,j] = 1 (i influences j)}
#' \item{A at (i,j)}{Sets adj[j,i] = 1 (j influences i)}
#' \item{X at (i,j)}{Sets adj[i,j] = 1 AND adj[j,i] = 1 (mutual influence)}
#' \item{O at (i,j)}{No edges added}
#' }
#'
#' @seealso
#' \code{\link{create_ssim}} for creating SSIM templates,
#' \code{\link{compute_reachability}} for the next step in ISM analysis.
#'
#' @export
#' @examples
#' # Create and fill SSIM
#' ssim <- create_ssim(c("Budget", "Resources", "Quality", "Success"))
#' ssim["Budget", "Resources"] <- "V"
#' ssim["Budget", "Quality"] <- "V"
#' ssim["Resources", "Quality"] <- "V"
#' ssim["Quality", "Success"] <- "V"
#'
#' # Convert to adjacency matrix
#' adj <- ssim_to_matrix(ssim)
#' print(adj)
#'
#' # Continue with ISM analysis
#' reach <- compute_reachability(adj)
#' levels <- level_partitioning(reach)
ssim_to_matrix <- function(ssim, validate = TRUE) {
# Input validation
if (!is.matrix(ssim)) {
stop("Input must be a matrix", call. = FALSE)
}
if (nrow(ssim) != ncol(ssim)) {
stop("SSIM must be a square matrix", call. = FALSE)
}
n <- nrow(ssim)
labels <- rownames(ssim)
# Convert to uppercase for comparison
ssim_upper <- toupper(ssim)
# Validate entries if requested
if (validate) {
upper_vals <- ssim_upper[upper.tri(ssim_upper)]
valid_codes <- c("V", "A", "X", "O", "")
invalid <- upper_vals[!upper_vals %in% valid_codes]
if (length(invalid) > 0) {
stop("Invalid SSIM codes found: ", paste(unique(invalid), collapse = ", "),
"\nValid codes are: V, A, X, O",
call. = FALSE)
}
}
# Create adjacency matrix
adj <- matrix(0, nrow = n, ncol = n)
if (!is.null(labels)) {
rownames(adj) <- colnames(adj) <- labels
}
# Process upper triangle
for (i in seq_len(n - 1)) {
for (j in (i + 1):n) {
code <- ssim_upper[i, j]
if (code == "V") {
# i influences j
adj[i, j] <- 1
} else if (code == "A") {
# j influences i
adj[j, i] <- 1
} else if (code == "X") {
# Mutual influence
adj[i, j] <- 1
adj[j, i] <- 1
}
# O or empty: no edges
}
}
return(adj)
}
#' Print SSIM Matrix
#'
#' @param x An object of class \code{ssim_matrix}
#' @param ... Additional arguments passed to print.default
#'
#' @return Invisibly returns the input object
#'
#' @export
#' @method print ssim_matrix
print.ssim_matrix <- function(x, ...) {
cat("Structural Self-Interaction Matrix (SSIM)\n")
cat("=========================================\n")
cat("Codes: V = i->j, A = j->i, X = i<->j, O = no relation\n\n")
# Print as regular matrix
class(x) <- "matrix"
print(x, quote = FALSE, ...)
invisible(x)
}
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.