R/populationMeansInAdmixture.R

Defines functions populationMeansInAdmixture

populationMeansInAdmixture <- function(
                                       datProportions,
                                       datE.Admixture,
                                       scaleProportionsTo1 = TRUE,
                                       scaleProportionsInCelltype = TRUE,
                                       setMissingProportionsToZero = FALSE) {
  datProportions <- as.matrix(datProportions)
  if (dim(datE.Admixture)[[1]] != dim(as.matrix(datProportions))[[1]]) {
    stop("Input error. The numbers of samples are not congruent: dim(datE.Admixture)[[1]] is unequal to dim(datProportions)[[1]]. Hint: Consider transposing one of the matrices.")
  }
  noMissing <- apply(is.na(datProportions), 1, sum)
  if (max(noMissing) > 0) {
    warning(paste(
      "Urgent Warning: datProportions contains missing proportions in the following row(s):",
      paste(which(noMissing > 0), collapse = ","), "\nCheck these rows in datProportions. But for your convenience, I will proceed"
    ))
  }
  if (setMissingProportionsToZero) {
    datProportions[is.na(datProportions)] <- 0
  }
  noNegative <- apply((datProportions) < 0, 1, sum, na.rm = T)
  if (max(noNegative) > 0) {
    stop(paste(
      "datProportions contains negative numbers. Negative proportions can be found in the following row(s):",
      paste(which(noNegative > 0), collapse = ","), "\nCheck these rows in datProportions."
    ))
  }
  sumsTo1 <- TRUE
  sumProp <- apply(datProportions, 1, sum, na.rm = TRUE)
  if (max(sumProp, na.rm = T) > 1.0000001) {
    sumsTo1 <- FALSE
    if (scaleProportionsTo1) {
      warning(paste(
        "The sum of proportions is larger than 1 for some rows including:",
        paste(which(sumProp > 1.0000001)[1:5], collapse = ","),
        "\nCheck these rows in datProportions. By default, I will scale them so that they sum to 1.\nBut if you do not want this scaling, please set scaleProportionsTo1=FALSE .\n"
      ))
    }
  }
  if (min(sumProp, na.rm = T) < 0.99999) {
    sumsTo1 <- FALSE
    if (scaleProportionsTo1) {
      warning(paste(
        "The sum of proportions is smaller than 1 for some rows including:",
        paste(which(sumProp < 0.99999)[1:5], collapse = ","),
        "\n Check these rows in datProportions. By default, I will scale them so that they sum to 1.\nBut if you do not want this scaling, please set scaleProportionsTo1=FALSE .\n"
      ))
    }
  }
  if (scaleProportionsTo1) {
    sumsTo1 <- TRUE
    for (i in 1:dim(datProportions)[1]) {
      datProportions[i, ] <- datProportions[i, ] / sum(datProportions[i, ], na.rm = T)
    }
  }
  if (sumsTo1) {
    if (scaleProportionsInCelltype) {
      for (ci in dim(datProportions)[2]) {
        datProportions[, ci] <- datProportions[, ci] - mean(datProportions[, ci])
      }
    }

    fit1 <- lm(as.matrix(datE.Admixture) ~ . - 1, data = data.frame(datProportions))
    datPredictedMeans <- t(as.matrix(fit1$coefficients))
  }
  if (!sumsTo1) {
    if (scaleProportionsInCelltype) {
      for (ci in dim(datProportions)[2]) {
        datProportions[, ci] <- datProportions[, ci] - mean(datProportions[, ci])
      }
    }
    fit1 <- lm(as.matrix(datE.Admixture) ~ ., data = data.frame(datProportions))
    if (dim(as.matrix(datProportions))[[2]] == 1) {
      datPredictedMeans <- (matrix(fit1$coefficients[-1, ], ncol = 1))
    }
    else {
      datPredictedMeans <- t(as.matrix(fit1$coefficients[-1, ]))
    }
  }
  dimnames(datPredictedMeans)[[1]] <- dimnames(datE.Admixture)[[2]]
  if (is.null(dimnames(datPredictedMeans)[[2]])) {
    dimnames(datPredictedMeans)[[2]] <- paste("Mean", 1:dim(datPredictedMeans)[[2]],
      sep = "."
    )
  }
  else {
    dimnames(datPredictedMeans)[[2]] <- paste("Mean", dimnames(datPredictedMeans)[[2]],
      sep = "."
    )
  }
  datPredictedMeans
}
milescsmith/WGCNA documentation built on April 11, 2024, 1:26 a.m.