## - http://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient#Calculating_a_weighted_correlation
## http://www.mathworks.com/matlabcentral/fileexchange/20846-weighted-correlation-matrix F. Pozzi, T. Di Matteo, T. Aste, 'Exponential
## smoothing weighted correlations', The European Physical Journal B, Vol. 85, No 6, 2012. DOI: 10.1140/epjb/e2012-20697-x TODO:: Give
## this function a more descriptive name
#' GWC Score
#'
#' Calculate the gwc score between two vectors, using either a weighted spearman
#' or pearson correlation
#'
#' @examples
#' data(clevelandSmall_cSet)
#' x <- molecularProfiles(clevelandSmall_cSet,'rna')[,1]
#' y <- molecularProfiles(clevelandSmall_cSet,'rna')[,2]
#' x_p <- rep(0.05, times=length(x))
#' y_p <- rep(0.05, times=length(y))
#' names(x_p) <- names(x)
#' names(y_p) <- names(y)
#' gwc(x,x_p,y,y_p, nperm=100)
#'
#'@param x1 \code{numeric} vector of effect sizes (e.g., fold change or t statitsics) for the first experiment
#'@param p1 \code{numeric} vector of p-values for each corresponding effect size for the first experiment
#'@param x2 \code{numeric} effect size (e.g., fold change or t statitsics) for the second experiment
#'@param p2 \code{numeric} vector of p-values for each corresponding effect size for the second experiment
#'@param method.cor \code{character} string identifying if a \code{pearson} or
#'\code{spearman} correlation should be used
#'@param nperm \code{numeric} how many permutations should be done to determine
#'@param truncate.p \code{numeric} Truncation value for extremely low p-values
#'@param ... Other passed down to internal functions
#'
#'@return \code{numeric} a vector of two values, the correlation and associated p-value.
#'@export
gwc <- function(x1, p1, x2, p2, method.cor = c("pearson", "spearman"), nperm = 10000, truncate.p = 1e-16, ...) {
method.cor <- match.arg(method.cor)
## intersection between x and y
ii <- .intersectList(names(x1), names(p1), names(x2), names(p2))
if (length(ii) < 10) {
stop("Less than 10 probes/genes in common between x and y")
}
x1 <- x1[ii]
p1 <- p1[ii]
x2 <- x2[ii]
p2 <- p2[ii]
## truncate extremely low p-values
p1[!is.na(p1) & p1 < truncate.p] <- truncate.p
p2[!is.na(p2) & p2 < truncate.p] <- truncate.p
## scaled weights
p1 <- -log10(p1)
p1 <- p1/sum(p1, na.rm = TRUE)
p2 <- -log10(p2)
p2 <- p2/sum(p2, na.rm = TRUE)
w <- p1 + p2
## compute genome-wide connectivity score
res <- .corWeighted(x = x1, y = x2, w = w, method = method.cor, nperm = nperm, ...)
return(res)
}
#### Compute a weighted correlation coefficient inspired from package boot - TODO:: Write function documentation?
#' @importFrom stats cov.wt complete.cases
.corWeighted <- function(x, y, w, method = c("pearson", "spearman"), alternative = c("two.sided", "greater", "less"), nperm = 0, nthread = 1,
na.rm = FALSE) {
######################
wcor <- function(d, w, na.rm = TRUE) {
CovM <- cov.wt(d, wt = w)[["cov"]]
res <- CovM[1, 2]/sqrt(CovM[1, 1] * CovM[2, 2])
return(res)
}
######################
if (missing(w)) {
w <- rep(1, length(x))/length(x)
}
if (length(x) != length(y) || length(x) != length(w)) {
stop("x, y, and w must have the same length")
}
method <- match.arg(method)
if (method == "spearman") {
x <- rank(x)
y <- rank(y)
}
alternative <- match.arg(alternative)
res <- c(rho = NA, p = NA)
## remove missing values
ccix <- complete.cases(x, y, w)
if (!all(ccix) && !na.rm) {
warning("Missing values are present")
}
if (sum(ccix) < 3) {
return(res)
}
x <- x[ccix]
y <- y[ccix]
w <- w[ccix]
wc <- wcor(d = cbind(x, y), w = w)
res["rho"] <- wc
if (nperm > 1) {
splitix <- parallel::splitIndices(nx = nperm, ncl = nthread)
if (!is.list(splitix)) {
splitix <- list(splitix)
}
splitix <- splitix[vapply(splitix, length, FUN.VALUE = numeric(1)) > 0]
mcres <- BiocParallel::bplapply(splitix, function(x, xx, yy, ww) {
pres <- vapply(x, function(x, xx, yy, ww) {
## permute the data and the weights
d2 <- cbind(xx[sample(seq_len(length(xx)))], yy[sample(seq_len(length(yy)))])
w2 <- ww[sample(seq_len(length(ww)))]
return(wcor(d = d2, w = w2))
}, xx = xx, yy = yy, ww = ww, FUN.VALUE = double(1))
return(pres)
}, xx = x, yy = y, ww = w)
perms <- do.call(c, mcres)
switch(alternative, two.sided = {
if (res["rho"] < 0) {
p <- sum(perms <= res, na.rm = TRUE)
} else {
p <- sum(perms >= res, na.rm = TRUE)
}
if (p == 0) {
p <- 1/(nperm + 1)
} else {
p <- p/nperm
}
p <- p * 2
}, greater = {
p <- sum(perms >= res, na.rm = TRUE)
if (p == 0) {
p <- 1/(nperm + 1)
} else {
p <- p/nperm
}
}, less = {
p <- sum(perms <= res, na.rm = TRUE)
if (p == 0) {
p <- 1/(nperm + 1)
} else {
p <- p/nperm
}
})
res["p"] <- p
}
return(res)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.