Author: Yi Tang
Date: 2026-03-09

# Introduction to ISMtools

#### Yi Tang

#### 2026-03-09

## Overview

ISMtools is a comprehensive R package for Interpretive Structural Modelling (ISM) analysis. ISM is a well-established methodology for identifying and summarizing relationships among specific elements which define an issue or problem (Warfield, 1974).

This vignette provides a step-by-step guide to using ISMtools for ISM analysis.

## Installation

    # Install from CRAN (once available)
    install.packages("ISMtools")

    # Or install development version from GitHub
    # devtools::install_github("tangyi/ISMtools")

## Loading the Package

    library(ISMtools)

## ISM Analysis Workflow

A typical ISM analysis follows these steps:

1. Define elements: Identify the factors/variables to be analyzed
2. Create adjacency matrix: Establish pairwise relationships
3. Compute reachability matrix: Calculate transitive closure
4. Level partitioning: Determine hierarchical structure
5. Visualization: Create ISM diagrams

## Step 1: Creating an Adjacency Matrix

### Method 1: Direct Matrix Creation

    # Create a 5x5 adjacency matrix directly
    # 1 indicates element i influences element j
    adj_matrix <- matrix(c(
      0, 1, 0, 0, 0,
      0, 0, 1, 0, 0,
      0, 0, 0, 1, 1,
      0, 0, 0, 0, 0,
      0, 0, 0, 0, 0
    ), nrow = 5, byrow = TRUE)

    # Add row and column names
    rownames(adj_matrix) <- colnames(adj_matrix) <- paste0("F", 1:5)
    print(adj_matrix)
    #>    F1 F2 F3 F4 F5
    #> F1  0  1  0  0  0
    #> F2  0  0  1  0  0
    #> F3  0  0  0  1  1
    #> F4  0  0  0  0  0
    #> F5  0  0  0  0  0

### Method 2: Using create_relation_matrix()

    # Create an empty matrix of specified size
    empty_matrix <- create_relation_matrix(4)
    print(empty_matrix)
    #>   1 2 3 4
    #> 1 0 0 0 0
    #> 2 0 0 0 0
    #> 3 0 0 0 0
    #> 4 0 0 0 0

### Method 3: Converting from Edge List

    # From a data frame
    edge_df <- data.frame(
      source = c("A", "A", "B", "C"),
      target = c("B", "C", "D", "D")
    )

    adj_from_df <- convert_to_matrix(edge_df, from = "source", to = "target")
    print(adj_from_df)
    #>   A B C D
    #> A 0 1 1 0
    #> B 0 0 0 1
    #> C 0 0 0 1
    #> D 0 0 0 0

    # From a matrix edge list
    edge_mat <- matrix(c(
      "X", "Y",
      "Y", "Z",
      "X", "Z"
    ), ncol = 2, byrow = TRUE)

    adj_from_mat <- convert_to_matrix(edge_mat)
    print(adj_from_mat)
    #>   X Y Z
    #> X 0 1 1
    #> Y 0 0 1
    #> Z 0 0 0

## Step 2: Computing the Reachability Matrix

The reachability matrix shows all direct and indirect relationships between elements. ISMtools uses Warshall’s algorithm for efficient computation.

    # Using our 5x5 adjacency matrix
    reach_matrix <- compute_reachability(adj_matrix)
    print(reach_matrix)
    #>    F1 F2 F3 F4 F5
    #> F1  1  1  1  1  1
    #> F2  0  1  1  1  1
    #> F3  0  0  1  1  1
    #> F4  0  0  0  1  0
    #> F5  0  0  0  0  1

In the reachability matrix: - `reach_matrix[i,j] = 1` means element i can reach element j (directly or indirectly) - The diagonal represents self-reachability

## Step 3: Level Partitioning

Level partitioning determines the hierarchical structure of elements based on their reachability and antecedent sets.

    levels <- level_partitioning(reach_matrix)
    print(levels)
    #> ISM Hierarchical Levels
    #> =======================
    #> (Level 1 = Top/Outcomes, Higher levels = Drivers)
    #>
    #> Level 1: F4, F5
    #> Level 2: F3
    #> Level 3: F2
    #> Level 4: F1
    #>
    #> Total: 4 levels, 5 elements

Elements at higher levels (e.g., Level 1) are outcomes/effects, while elements at lower levels are root causes/drivers.

## Step 4: Visualization

### Static ISM Diagram

    plot_ism(reach_matrix)

### Interactive ISM Diagram

The interactive visualization allows you to: - Drag nodes to reposition them - Zoom in/out - Highlight connected nodes on hover - Filter by level

    # Interactive visualization (requires browser)
    plot_interactive_ism(reach_matrix,
                         node_labels = paste0("Factor ", 1:5),
                         level_result = levels)

## Complete Example: Project Risk Analysis

Let’s walk through a complete example analyzing project risk factors.

    # Define risk factors
    factors <- c(
      "Budget Constraints",      # F1

      "Resource Shortage",       # F2
      "Technical Complexity",    # F3
      "Poor Communication",      # F4
      "Schedule Pressure",       # F5
      "Quality Issues",          # F6
      "Project Failure"          # F7
    )

    # Create adjacency matrix based on expert judgment
    # F1 -> F2, F5
    # F2 -> F3, F6
    # F3 -> F6
    # F4 -> F2, F3, F6
    # F5 -> F4, F6
    # F6 -> F7

    risk_adj <- matrix(0, nrow = 7, ncol = 7)
    rownames(risk_adj) <- colnames(risk_adj) <- paste0("F", 1:7)

    # Define relationships
    risk_adj["F1", c("F2", "F5")] <- 1
    risk_adj["F2", c("F3", "F6")] <- 1
    risk_adj["F3", "F6"] <- 1
    risk_adj["F4", c("F2", "F3", "F6")] <- 1
    risk_adj["F5", c("F4", "F6")] <- 1
    risk_adj["F6", "F7"] <- 1

    print("Adjacency Matrix:")
    #> [1] "Adjacency Matrix:"
    print(risk_adj)
    #>    F1 F2 F3 F4 F5 F6 F7
    #> F1  0  1  0  0  1  0  0
    #> F2  0  0  1  0  0  1  0
    #> F3  0  0  0  0  0  1  0
    #> F4  0  1  1  0  0  1  0
    #> F5  0  0  0  1  0  1  0
    #> F6  0  0  0  0  0  0  1
    #> F7  0  0  0  0  0  0  0

    # Compute reachability
    risk_reach <- compute_reachability(risk_adj)
    print("Reachability Matrix:")
    #> [1] "Reachability Matrix:"
    print(risk_reach)
    #>    F1 F2 F3 F4 F5 F6 F7
    #> F1  1  1  1  1  1  1  1
    #> F2  0  1  1  0  0  1  1
    #> F3  0  0  1  0  0  1  1
    #> F4  0  1  1  1  0  1  1
    #> F5  0  1  1  1  1  1  1
    #> F6  0  0  0  0  0  1  1
    #> F7  0  0  0  0  0  0  1

    # Level partitioning
    risk_levels <- level_partitioning(risk_reach)
    print("Hierarchical Levels:")
    #> [1] "Hierarchical Levels:"
    print(risk_levels)
    #> ISM Hierarchical Levels
    #> =======================
    #> (Level 1 = Top/Outcomes, Higher levels = Drivers)
    #>
    #> Level 1: F7
    #> Level 2: F6
    #> Level 3: F3
    #> Level 4: F2
    #> Level 5: F4
    #> Level 6: F5
    #> Level 7: F1
    #>
    #> Total: 7 levels, 7 elements

    # Visualize
    plot_ism(risk_reach)

## Interpretation

From this analysis: - Level 1 (Top): F7 (Project Failure) - the ultimate outcome - Level 2: F6 (Quality Issues) - direct cause of failure - Level 3: F3 (Technical Complexity) - intermediate factor - Level 4: F2 (Resource Shortage), F4 (Poor Communication) - Level 5: F5 (Schedule Pressure) - Level 6 (Bottom): F1 (Budget Constraints) - root cause

This hierarchical structure suggests that addressing budget constraints (F1) could have cascading positive effects throughout the project.

## References

Warfield, J. N. (1974). Developing interconnection matrices in structural modeling. IEEE Transactions on Systems, Man, and Cybernetics, SMC-4(1), 81-87.

## Session Info

    sessionInfo()
    #> R version 4.4.2 (2024-10-31 ucrt)
    #> Platform: x86_64-w64-mingw32/x64
    #> Running under: Windows 11 x64 (build 26100)
    #>
    #> Matrix products: default
    #>
    #>
    #> locale:
    #> [1] LC_COLLATE=C
    #> [2] LC_CTYPE=Chinese (Simplified)_China.utf8
    #> [3] LC_MONETARY=Chinese (Simplified)_China.utf8
    #> [4] LC_NUMERIC=C
    #> [5] LC_TIME=Chinese (Simplified)_China.utf8
    #>
    #> time zone: Asia/Shanghai
    #> tzcode source: internal
    #>
    #> attached base packages:
    #> [1] stats     graphics  grDevices utils     datasets  methods   base
    #>
    #> other attached packages:
    #> [1] ISMtools_0.1.0
    #>
    #> loaded via a namespace (and not attached):
    #>  [1] digest_0.6.37     R6_2.5.1          fastmap_1.2.0     xfun_0.49
    #>  [5] cachem_1.1.0      knitr_1.49        htmltools_0.5.8.1 rmarkdown_2.29
    #>  [9] lifecycle_1.0.4   cli_3.6.3         sass_0.4.9        jquerylib_0.1.4
    #> [13] compiler_4.4.2    rstudioapi_0.17.1 tools_4.4.2       evaluate_1.0.1
    #> [17] bslib_0.8.0       yaml_2.3.10       rlang_1.1.4       jsonlite_1.8.9