R/conformityDecomposition.R

Defines functions conformityDecomposition

#

conformityDecomposition <- function(adj, Cl = NULL) {
  if (is.null(dim(adj))) stop("Input adj is not a matrix or data frame. ")
  if (dim(adj)[[1]] < 3) stop("The adjacency matrix has fewer than 3 rows. This network is trivial and will not be evaluated.")
  if (!.is.adjmat(adj)) {
    stop("The input matrix is not a valid adjacency matrix!")
  }
  diag(adj) <- 0
  if (!is.null(Cl)) {
    if (length(Cl) != dim(adj)[[1]]) {
      stop(paste(
        "The length of the class assignment Cl does not equal the number",
        "of rows of the adjcency matrix. length(Cl) != dim(adj)[[1]]. \n",
        "Something is wrong with your input"
      ))
    }
    if (sum(is.na(Cl)) > 0) stop("Cl must not contain missing values (NA).")
  }

  A.CF <- matrix(0, nrow = dim(adj)[[1]], ncol = dim(adj)[[2]])
  diag(A.CF) <- 1
  if (is.null(Cl)) {
    Conformity <- .NPC.iterate(adj)$v1
    if (sum(adj^2, na.rm = T) == 0) {
      Factorizability <- NA
    } else {
      A.CF <- outer(Conformity, Conformity) - diag(Conformity^2)
      Factorizability <- 1 - sum((adj - A.CF)^2) / sum(adj^2)
    }
    diag(A.CF) <- 1
    output <- list(A.CF = A.CF, Conformity = data.frame(Conformity), IntermodularAdjacency = 1, Factorizability = Factorizability)
  }

  if (!is.null(Cl)) {
    Cl <- factor(Cl)
    Cl.level <- levels(Cl)
    if (length(Cl.level) > 100) warning(paste("Your class assignment variable Cl contains", length(Cl.level), "different classes. I assume this is a proper class assignment variable. But if not, stop the calculation, e.g. by using the Esc key on your keybord."))

    Conformity <- rep(NA, length(Cl))
    listConformity <- list()
    IntramodularFactorizability <- rep(NA, length(Cl.level))
    IntermodularAdjacency <- matrix(0, nrow = length(Cl.level), ncol = length(Cl.level))
    diag(IntermodularAdjacency) <- 1
    IntermodularAdjacency <- data.frame(IntermodularAdjacency)
    dimnames(IntermodularAdjacency)[[1]] <- as.character(Cl.level)
    dimnames(IntermodularAdjacency)[[2]] <- as.character(Cl.level)

    numeratorFactorizability <- 0
    for (i in 1:length(Cl.level)) {
      restclass <- Cl == Cl.level[i]
      if (sum(restclass) == 1) {
        A.help <- 0
        CF.help <- 0
        Conformity[restclass] <- CF.help
        A.CF[restclass, restclass] <- CF.help * CF.help - CF.help^2
      }
      if (sum(restclass) == 2) {
        A.help <- adj[restclass, restclass]
        diag(A.help) <- 0
        CFvalue <- sqrt(adj[restclass, restclass][1, 2])
        CF.help <- c(CFvalue, CFvalue)
        Conformity[restclass] <- CF.help
        A.CF[restclass, restclass] <- outer(CF.help, CF.help) - diag(CF.help^2)
      }

      if (sum(restclass) > 2) {
        A.help <- adj[restclass, restclass]
        diag(A.help) <- 0
        CF.help <- .NPC.iterate(A.help)$v1
        Conformity[restclass] <- CF.help
        A.CF[restclass, restclass] <- outer(CF.help, CF.help) - diag(CF.help^2)
      }
      if (length(CF.help) > 1) {
        numeratorFactorizability <- numeratorFactorizability + sum((A.help - outer(CF.help, CF.help) + diag(CF.help^2))^2)
      }

      listConformity[[i]] <- CF.help
      if (sum(A.help^2, na.rm = T) == 0 | length(CF.help) == 1) {
        IntramodularFactorizability[i] <- NA
      } else {
        IntramodularFactorizability[i] <- 1 - sum((A.help - outer(CF.help, CF.help) +
          diag(CF.help^2))^2) / sum(A.help^2, na.rm = T)
      }
    } # end of for loop over i

    if (length(Cl.level) == 1) {
      IntermodularAdjacency[1, 1] <- 1
    } else {
      for (i in 1:(length(Cl.level) - 1)) {
        for (j in (i + 1):length(Cl.level)) {
          restclass1 <- Cl == Cl.level[i]
          restclass2 <- Cl == Cl.level[j]
          A.inter <- adj[restclass1, restclass2]
          mean.CF1 <- mean(listConformity[[i]], na.rm = T)
          mean.CF2 <- mean(listConformity[[j]], na.rm = T)
          if (mean.CF1 * mean.CF2 != 0) {
            IntermodularAdjacency[i, j] <- mean(A.inter, na.rm = T) / (mean.CF1 * mean.CF2)
            IntermodularAdjacency[j, i] <- IntermodularAdjacency[i, j]
          }

          if (length(listConformity[[i]]) == 1 | length(listConformity[[j]]) == 1) {
            numeratorFactorizability <- numeratorFactorizability + 2 * sum((A.inter - IntermodularAdjacency[i, j] * listConformity[[i]] * listConformity[[j]])^2)
            A.CF[restclass1, restclass2] <- IntermodularAdjacency[i, j] * listConformity[[i]] * listConformity[[j]]
            A.CF[restclass2, restclass1] <- IntermodularAdjacency[j, i] * listConformity[[j]] * listConformity[[i]]
          } else {
            numeratorFactorizability <- numeratorFactorizability + 2 * sum((A.inter - IntermodularAdjacency[i, j] * outer(listConformity[[i]], listConformity[[j]]))^2)
            A.CF[restclass1, restclass2] <- IntermodularAdjacency[i, j] * outer(listConformity[[i]], listConformity[[j]])
            A.CF[restclass2, restclass1] <- IntermodularAdjacency[j, i] * outer(listConformity[[j]], listConformity[[i]])
          } # end of else
        } # end of for (i in
      } # end of for (j in
      diag(adj) <- NA
      Factorizability <- 1 - numeratorFactorizability / sum(adj^2, na.rm = T)
    } # end of if else statement

    diag(A.CF) <- 1
    output <- list(A.CF = A.CF, Conformity = Conformity, IntermodularAdjacency = IntermodularAdjacency, Factorizability = Factorizability, Cl.level = Cl.level, IntramodularFactorizability = IntramodularFactorizability, listConformity = listConformity)
  } # end of   if ( !is.null(Cl) )
  output
}
milescsmith/WGCNA documentation built on April 11, 2024, 1:26 a.m.