Switch to unified view

a b/R/differentialexpression.R
1
####
2
# ROI DE Analysis ####
3
####
4
5
#' getDiffExp
6
#'
7
#' Get differential expression with DESeq2
8
#'
9
#' @param object a VoltRon object
10
#' @param assay assay name (exp: Assay1) or assay class (exp: Visium, Xenium), see \link{SampleMetadata}. 
11
#' if NULL, the default assay will be used, see \link{vrMainAssay}.
12
#' @param group.by the categorical variable from metadata to get differentially expressed features across
13
#' @param group.base Optional, the base category in \code{group.by} which is used as control group
14
#' @param covariates the covariate variable for the design formula
15
#' @param method the method for DE analysis, e.g. DESeq2
16
#'
17
#' @export
18
#'
19
getDiffExp <- function(object, assay = NULL, group.by, group.base = NULL, covariates = NULL, method = "DESeq2"){
20
21
  # get data and metadata
22
  data <- vrData(object, assay = assay)
23
  metadata <- Metadata(object, assay = assay)
24
25
  # check groups
26
  if(group.by %in% colnames(metadata)){
27
    if(!is.null(group.base)){
28
      if(!group.base %in% unique(as.vector(metadata[[group.by]])))
29
        stop("Please specify a group that is included in the group.by column of metadata to define the base group!")
30
    } else{
31
      group.base <- levels(factor(as.vector(metadata[[group.by]])))[1]
32
    }
33
  } else {
34
    stop("Column ", group.by, " cannot be found in metadata!")
35
  }
36
37
  # select a method
38
  results <-
39
    switch(method,
40
           DESeq2 = {
41
             getDiffExpDESeq2(data, metadata, group.by = group.by, group.base = group.base, covariates = covariates)
42
           })
43
44
  # return
45
  return(results)
46
}
47
48
#' getDiffExpDESeq2
49
#'
50
#' @param data the raw data set
51
#' @param metadata the metadata
52
#' @param group.by the categorical variable from metadata to get differentially expressed features across
53
#' @param group.base Optional, the base category in \code{group.by} which is used as control group
54
#' @param covariates the covariate variable for the design formula
55
#'
56
#' @importFrom stats as.formula
57
#'
58
#' @noRd
59
getDiffExpDESeq2 <- function(data, metadata, group.by, group.base = NULL, covariates){
60
61
  if (!requireNamespace('DESeq2'))
62
    stop("Please install DESeq2 package to find differentially expressed genes with DESeq2 method")
63
64
  # experimental design for deseq2
65
66
  # make formula
67
  if(is.null(covariates)){
68
    group.by.data <- as.vector(metadata[[group.by]])
69
    uniq_groups <- unique(group.by.data)
70
    if(!is.null(group.base))
71
      uniq_groups <- c(group.base, uniq_groups[!uniq_groups %in% group.base])
72
    group.by.data <- factor(group.by.data, levels = uniq_groups)
73
    colData <- data.frame(group.by.data)
74
    colnames(colData) <- c(group.by, covariates)
75
    deseq2.formula <- stats::as.formula(paste0("~", group.by))
76
  } else {
77
    if(all(covariates %in% colnames(metadata))){
78
      design.data <- metadata[,c(group.by, covariates)]
79
      uniq_groups <- unique(design.data[[group.by]])
80
      if(is.null(group.base))
81
        uniq_groups <- c(group.base, uniq_groups[!uniq_groups %in% group.base])
82
      group.by.data <- factor(design.data[[group.by]], levels = uniq_groups)
83
      design.data[[group.by]] <- group.by.data
84
      colData <- data.frame(design.data)
85
      colnames(colData) <- c(group.by, covariates)
86
      deseq2.formula <- stats::as.formula(paste0("~", group.by, " + ", paste(covariates, collapse = " + ")))
87
    } else {
88
      stop("Columns ", paste(covariates, collapse = ", "), " cannot be found in metadata!")
89
    }
90
  }
91
92
  # run DESeq2
93
  data <- as.matrix(as(data, "dgCMatrix"))
94
  dds <- DESeq2::DESeqDataSetFromMatrix(countData = data, colData = colData, design = deseq2.formula)
95
  dds <- DESeq2::DESeq(dds)
96
97
  all_results <- NULL
98
  for(i in seq_len(length(uniq_groups)-1)){
99
    for(j in (i+1):length(uniq_groups)){
100
      comparison <- c(group.by, uniq_groups[i], uniq_groups[j])
101
      cur_results <- as.data.frame(DESeq2::results(dds, comparison))
102
      cur_results <- data.frame(cur_results, gene = rownames(cur_results), comparison = paste(comparison, collapse = "_"))
103
      all_results <- rbind(all_results, cur_results)
104
    }
105
  }
106
107
  # return
108
  return(all_results)
109
}