Browse code

Edits to decontX, doubletCells, and mergeSCEColData to allow function to run even if column has 0 counts

Yusuke Koga authored on 21/12/2020 23:50:30
Showing 4 changed files

... ...
@@ -84,6 +84,13 @@ runDecontX <- function(inSCE,
84 84
 
85 85
   message(paste0(date(), " ... Running 'DecontX'"))
86 86
 
87
+  rm.ix <- which(colSums(assay(inSCE, useAssay)) == 0)
88
+  if(length(rm.ix) > 0){
89
+    inSCEOrig <- inSCE
90
+    inSCE <- inSCE[,-rm.ix]
91
+    sample <- sample[-rm.ix]
92
+  }
93
+
87 94
   inSCE <- celda::decontX(x = inSCE,
88 95
                           batch = sample,
89 96
                           assayName = useAssay,
... ...
@@ -101,6 +108,9 @@ runDecontX <- function(inSCE,
101 108
 
102 109
   #argsList <- argsList[!names(argsList) %in% ("...")]
103 110
 
111
+  if(length(rm.ix) > 0){
112
+    inSCE <- mergeSCEColData(inSCE1 = inSCEOrig, inSCE2 = inSCE)
113
+  }
104 114
   inSCE@metadata$runDecontX <- argsList[-1]
105 115
   inSCE@metadata$runDecontX$packageVersion <- utils::packageDescription("celda")$Version
106 116
 
... ...
@@ -1,16 +1,16 @@
1 1
 #' @title Merging colData from two singleCellExperiment objects
2
-#' @description Merges colData of the singleCellExperiment objects 
3
-#'  obtained from the same dataset which contain differing colData. 
4
-#'  (i.e. raw data and filtered data)  
2
+#' @description Merges colData of the singleCellExperiment objects
3
+#'  obtained from the same dataset which contain differing colData.
4
+#'  (i.e. raw data and filtered data)
5 5
 #' @param inSCE1 Input SingleCellExperiment object. The function will output this
6 6
 #'  singleCellExperiment object with a combined colData from inSCE1 and inSCE2.
7 7
 #' @param inSCE2 Input SingleCellExperiment object. colData from this object
8 8
 #'  will be merged with colData from inSCE1 and loaded into inSCE1.
9
-#' @param id1 Character vector. Column in colData of inSCE1 that will be 
10
-#'  used to combine inSCE1 and inSCE2. Default "column_name" 
9
+#' @param id1 Character vector. Column in colData of inSCE1 that will be
10
+#'  used to combine inSCE1 and inSCE2. Default "column_name"
11 11
 #' @param id2 Character vector. Column in colData of inSCE2 that will be
12 12
 #'  used to combine inSCE1 and inSCE2. Default "column_name"
13
-#' @return SingleCellExperiment object containing combined colData from  
13
+#' @return SingleCellExperiment object containing combined colData from
14 14
 #'  both singleCellExperiment for samples in inSCE1.
15 15
 #' @examples
16 16
 #' sce1 <- importCellRanger(
... ...
@@ -22,48 +22,70 @@
22 22
 #' sce2 <- sce
23 23
 #' sce <- mergeSCEColData(inSCE1 = sce1, inSCE2 = sce2, id1 = "column_name", id2 = "column_name")
24 24
 #' @export
25
-mergeSCEColData <- function(inSCE1, inSCE2, id1 = "column_name", id2 = "column_name"){
26
-    not.in.sce1 <- c(setdiff(names(SummarizedExperiment::colData(inSCE2)),
27
-      names(SummarizedExperiment::colData(inSCE1))),id2)
28
-    not.in.sce1 <- not.in.sce1[!is.null(not.in.sce1)]
25
+mergeSCEColData <- function(inSCE1, inSCE2, id1 = "column_name", id2 = "column_name") {
26
+  # For default case & column_name not in colData
27
+  if (id1 == "column_name" && "column_name" %in%
28
+    names(SummarizedExperiment::colData(inSCE1))) {
29
+    columnNameColExist1 <- TRUE
30
+  } else {
31
+    columnNameColExist1 <- FALSE
32
+    SummarizedExperiment::colData(inSCE1)$column_name <- colnames(inSCE1)
33
+  }
34
+
35
+  if (id2 == "column_name" && "column_name" %in%
36
+    names(SummarizedExperiment::colData(inSCE2))) {
37
+    columnNameColExist2 <- TRUE
38
+  } else {
39
+    columnNameColExist2 <- FALSE
40
+    SummarizedExperiment::colData(inSCE2)$column_name <- colnames(inSCE2)
41
+  }
42
+  not.in.sce1 <- c(setdiff(
43
+    names(SummarizedExperiment::colData(inSCE2)),
44
+    names(SummarizedExperiment::colData(inSCE1))
45
+  ), id2)
46
+  not.in.sce1 <- not.in.sce1[!is.null(not.in.sce1)]
29 47
 
30
-    coldata.not.in.sce1 <- SummarizedExperiment::colData(inSCE2)[,c(not.in.sce1),
31
-      drop = FALSE]
48
+  coldata.not.in.sce1 <- SummarizedExperiment::colData(inSCE2)[, c(not.in.sce1),
49
+    drop = FALSE
50
+  ]
32 51
 
33
-    coldata.sce1 <- SummarizedExperiment::colData(inSCE1)
52
+  coldata.sce1 <- SummarizedExperiment::colData(inSCE1)
34 53
 
35
-    if(is.null(id1) | is.null(id2)){
36
-        if(is.null(rownames(coldata.not.in.sce1))){
37
-            stop("Unable to match between singleCellExperiment objects.
54
+  if (is.null(id1) | is.null(id2)) {
55
+    if (is.null(rownames(coldata.not.in.sce1))) {
56
+      stop("Unable to match between singleCellExperiment objects.
38 57
               Please define id1/id2 within the function,
39 58
               or assign a column name for the singleCellExperiment object.")
40
-        }else{
41
-            coldata.not.in.sce1$cell <- rownames(coldata.not.in.sce1)
42
-            coldata.sce1$cell <- rownames(SummarizedExperiment::colData(inSCE1))
43
-            id1 <- "cell"
44
-            id2 <- "cell"
45
-            placeholder = TRUE
46
-        }
47
-    }else{
48
-        placeholder <- FALSE
59
+    } else {
60
+      coldata.not.in.sce1$cell <- rownames(coldata.not.in.sce1)
61
+      coldata.sce1$cell <- rownames(SummarizedExperiment::colData(inSCE1))
62
+      id1 <- "cell"
63
+      id2 <- "cell"
64
+      placeholder <- TRUE
49 65
     }
66
+  } else {
67
+    placeholder <- FALSE
68
+  }
50 69
 
51
-    coldata.merge <- base::merge(coldata.sce1,
52
-        coldata.not.in.sce1,
53
-        all.x = TRUE,
54
-        sort = FALSE,
55
-        by.x = id1,
56
-        by.y = id2)
70
+  coldata.merge <- base::merge(coldata.sce1,
71
+    coldata.not.in.sce1,
72
+    all.x = TRUE,
73
+    sort = FALSE,
74
+    by.x = id1,
75
+    by.y = id2
76
+  )
57 77
 
58
-    coldata.merge <- coldata.merge[match(colnames(SingleCellExperiment::counts(inSCE1)),
59
-        coldata.merge[,id1]),]
78
+  coldata.merge <- coldata.merge[match(
79
+    colnames(SingleCellExperiment::counts(inSCE1)),
80
+    coldata.merge[, id1]
81
+  ), ]
60 82
 
61
-    rownames(coldata.merge) <- coldata.merge[,id1]
83
+  rownames(coldata.merge) <- coldata.merge[, id1]
62 84
 
63
-    if(placeholder == TRUE){
64
-    	  coldata.merge[,id1] <- NULL
65
-    }
85
+  if (placeholder == TRUE) {
86
+    coldata.merge[, id1] <- NULL
87
+  }
66 88
 
67
-    SummarizedExperiment::colData(inSCE1) <- S4Vectors::DataFrame(coldata.merge)
68
-    return(inSCE1)
89
+  SummarizedExperiment::colData(inSCE1) <- S4Vectors::DataFrame(coldata.merge)
90
+  return(inSCE1)
69 91
 }
... ...
@@ -13,9 +13,9 @@
13 13
 #                               BSPARAM=BSPARAM,
14 14
 #                               BPPARAM=BPPARAM
15 15
 #                               ) {
16
-# 
16
+#
17 17
 #   cell.matrix <- .convertToMatrix(cell.matrix)
18
-# 
18
+#
19 19
 #   scores <- matrix(scran::doubletCells(cell.matrix, k = k,
20 20
 #                                        niters = nIters,
21 21
 #                                        size.factors.norm = NULL,
... ...
@@ -32,11 +32,11 @@
32 32
 #                                        ), ncol=1)
33 33
 #   scores <- cbind(scores,log10(scores[,1]+1))
34 34
 #   colnames(scores) <- c("scran_doubletCells_score", "scran_doubletCells_score_log10")
35
-# 
36
-# 
35
+#
36
+#
37 37
 #   return(scores)
38 38
 # }
39
-# 
39
+#
40 40
 
41 41
 #' @title Detect doublet cells using \link[scDblFinder]{scDblFinder}.
42 42
 #' @description A wrapper function for \link[scDblFinder]{scDblFinder}. Identify
... ...
@@ -109,7 +109,13 @@ runDoubletCells <- function(inSCE,
109 109
 
110 110
   ## Loop through each sample and run barcodeRank
111 111
   #samples <- unique(sample)
112
-  
112
+
113
+  rm.ix <- which(colSums(assay(inSCE, useAssay)) == 0)
114
+  if(length(rm.ix) > 0){
115
+    inSCEOrig <- inSCE
116
+    inSCE <- inSCE[,-rm.ix]
117
+    sample <- sample[-rm.ix]
118
+  }
113 119
   inSCE <- withr::with_seed(seed,
114 120
                             scDblFinder::scDblFinder(sce = inSCE,
115 121
                             samples = sample,
... ...
@@ -117,16 +123,19 @@ runDoubletCells <- function(inSCE,
117 123
                             k = nNeighbors,
118 124
                             verbose = FALSE
119 125
                             ))
126
+  if(length(rm.ix) > 0){
127
+    inSCE <- mergeSCEColData(inSCE1 = inSCEOrig, inSCE2 = inSCE)
128
+  }
120 129
   names(SummarizedExperiment::colData(inSCE)) <- gsub(pattern = "scDblFinder\\.",
121 130
                                                       "scran_doubletCells_",
122 131
                                                       names(SummarizedExperiment::colData(inSCE)))
123
-  
132
+
124 133
   # for (i in seq_len(length(samples))) {
125 134
   #   sceSampleInd <- sample == samples[i]
126 135
   #   sceSample <- inSCE[, sceSampleInd]
127
-  # 
136
+  #
128 137
   #   mat <- SummarizedExperiment::assay(sceSample, i = useAssay)
129
-  # 
138
+  #
130 139
   #   result <- withr::with_seed(seed,
131 140
   #             .runDoubletCells(cell.matrix = mat,
132 141
   #                              k = nNeighbors,
... ...
@@ -143,7 +152,7 @@ runDoubletCells <- function(inSCE,
143 152
   #                              BSPARAM=BSPARAM,
144 153
   #                              BPPARAM=BPPARAM
145 154
   #                              ))
146
-  # 
155
+  #
147 156
   #   output[sceSampleInd, ] <- result
148 157
   # }
149 158
 
... ...
@@ -13,19 +13,19 @@ singleCellExperiment object with a combined colData from inSCE1 and inSCE2.}
13 13
 \item{inSCE2}{Input SingleCellExperiment object. colData from this object
14 14
 will be merged with colData from inSCE1 and loaded into inSCE1.}
15 15
 
16
-\item{id1}{Character vector. Column in colData of inSCE1 that will be 
16
+\item{id1}{Character vector. Column in colData of inSCE1 that will be
17 17
 used to combine inSCE1 and inSCE2. Default "column_name"}
18 18
 
19 19
 \item{id2}{Character vector. Column in colData of inSCE2 that will be
20 20
 used to combine inSCE1 and inSCE2. Default "column_name"}
21 21
 }
22 22
 \value{
23
-SingleCellExperiment object containing combined colData from  
23
+SingleCellExperiment object containing combined colData from
24 24
  both singleCellExperiment for samples in inSCE1.
25 25
 }
26 26
 \description{
27
-Merges colData of the singleCellExperiment objects 
28
- obtained from the same dataset which contain differing colData. 
27
+Merges colData of the singleCellExperiment objects
28
+ obtained from the same dataset which contain differing colData.
29 29
  (i.e. raw data and filtered data)
30 30
 }
31 31
 \examples{