Browse code

Add Runnable functions

Yusuke Koga authored on 15/10/2020 16:44:51
Showing 73 changed files

... ...
@@ -1,7 +1,5 @@
1 1
 # Generated by roxygen2: do not edit by hand
2 2
 
3
-export(MAST)
4
-export(alignSingleCellData)
5 3
 export(calcEffectSizes)
6 4
 export(combineSCE)
7 5
 export(computeZScore)
... ...
@@ -50,7 +48,6 @@ export(importSEQC)
50 48
 export(importSTARsolo)
51 49
 export(iterateSimulations)
52 50
 export(mergeSCEColData)
53
-export(parseRsubreadLogs)
54 51
 export(plotBarcodeRankDropsResults)
55 52
 export(plotBarcodeRankScatter)
56 53
 export(plotBatchVariance)
... ...
@@ -4,7 +4,7 @@
4 4
   barcodes,
5 5
   metadata,
6 6
   reducedDims) {
7
-  
7
+
8 8
   sce <- SingleCellExperiment::SingleCellExperiment(assays = matrices)
9 9
   SummarizedExperiment::rowData(sce) <- S4Vectors::DataFrame(features)
10 10
   SummarizedExperiment::colData(sce) <- S4Vectors::DataFrame(barcodes)
... ...
@@ -21,9 +21,9 @@
21 21
   return(list(RowUnion, ColUnion))
22 22
 }
23 23
 
24
-.getMatUnion <- function(dimsList, x, 
25
-                         combineRow, combineCol, 
26
-                         sparse = FALSE, 
24
+.getMatUnion <- function(dimsList, x,
25
+                         combineRow, combineCol,
26
+                         sparse = FALSE,
27 27
                          fill = c("NA", "0")){
28 28
   row <- dimsList[[1]]
29 29
   col <- dimsList[[2]]
... ...
@@ -34,8 +34,8 @@
34 34
   } else {
35 35
     fill <- NA
36 36
   }
37
-  
38
-  ### combine row 
37
+
38
+  ### combine row
39 39
   if (isTRUE(combineRow) & (!is.null(row))) {
40 40
     missRow <- row[!row %in% rownames(x)]
41 41
     missMat <- Matrix::Matrix(fill, nrow = length(missRow), ncol = ncol(matOrigin),
... ...
@@ -43,15 +43,15 @@
43 43
     if (!isTRUE(sparse)) {
44 44
       missMat <- as.matrix(missMat)
45 45
     }
46
-    
46
+
47 47
     mat <- rbind(matOrigin, missMat)
48 48
     if (anyDuplicated(rownames(mat))) {
49 49
       mat <- mat[!duplicated(rownames(mat)), ]
50 50
     }
51 51
     matOrigin <- mat[row, ]
52 52
   }
53
-  
54
-  ### combine cols 
53
+
54
+  ### combine cols
55 55
   if (isTRUE(combineCol) & (!is.null(col))) {
56 56
     missCol <- col[!col %in% colnames(x)]
57 57
     missMat <- Matrix::Matrix(fill, nrow = nrow(matOrigin), ncol = length(missCol),
... ...
@@ -59,7 +59,7 @@
59 59
     if (!isTRUE(sparse)) {
60 60
       missMat <- as.matrix(missMat)
61 61
     }
62
-    
62
+
63 63
     mat <- cbind(matOrigin, missMat)
64 64
     if (anyDuplicated(colnames(mat))) {
65 65
       mat <- mat[, !duplicated(colnames(mat))]
... ...
@@ -76,17 +76,17 @@
76 76
     rw[['rownames']] <- rownames(rw)
77 77
     return(rw)
78 78
   })
79
-  
79
+
80 80
   ## Get merged rowData
81 81
   by.r <- unique(c('rownames', by.r))
82 82
   unionFe <- Reduce(function(r1, r2) merge(r1, r2, by=by.r, all=TRUE), feList)
83 83
   allGenes <- unique(unlist(lapply(feList, rownames)))
84
-  
84
+
85 85
   ## rowData
86 86
   newFe <- unionFe
87 87
   if (nrow(newFe) != length(allGenes)) {
88 88
     warning("Conflicts were found when merging two rowData. ",
89
-            "Resolved the conflicts by choosing the first entries.", 
89
+            "Resolved the conflicts by choosing the first entries.",
90 90
             "To avoid conflicts, please provide the 'by.r' arguments to ",
91 91
             "specify columns in rowData that does not have conflict between two singleCellExperiment object. ")
92 92
     newFe <- newFe[!duplicated(newFe$rownames), ]
... ...
@@ -102,7 +102,7 @@
102 102
     cD[['rownames']] <- rownames(cD)
103 103
     return(cD)
104 104
   })
105
-  
105
+
106 106
   by.c <- unique(c("rownames", by.c))
107 107
   unionCb <- Reduce(function(c1, c2) merge(c1, c2, by=by.c, all=TRUE), cbList)
108 108
   rownames(unionCb) <- unionCb[['rownames']]
... ...
@@ -118,34 +118,34 @@
118 118
   reduceList <- lapply(sceList, SingleCellExperiment::reducedDims)
119 119
   ## get every reducedDim exists in at least one SCEs
120 120
   UnionReducedDims <- unique(unlist(lapply(sceList, SingleCellExperiment::reducedDimNames)))
121
-  
121
+
122 122
   ## for each reducedDim, get union row/cols
123 123
   reducedDims <- list()
124 124
   for (reduceDim in UnionReducedDims) {
125 125
     x <- lapply(sceList, function(x) {if (reduceDim %in% SingleCellExperiment::reducedDimNames(x)) {SingleCellExperiment::reducedDim(x, reduceDim)}})
126 126
     reducedDims[[reduceDim]] <- .getDimUnion(x)
127 127
   }
128
-  
128
+
129 129
   ## Merge reducedDim for each SCE
130 130
   redList <- list()
131 131
   for (idx in seq_along(sceList)){
132 132
     redMat <- reduceList[[idx]]
133
-    
133
+
134 134
     for (DimName in UnionReducedDims) {
135 135
       if (DimName %in% names(redMat)) {
136 136
         redMat[[DimName]] <- .getMatUnion(reducedDims[[DimName]], redMat[[DimName]],
137 137
                                           combineRow = FALSE, combineCol = TRUE,
138 138
                                           sparse = FALSE, fill = "NA")
139 139
       } else {
140
-        redMat[[DimName]] <- base::matrix(NA, nrow = ncol(sceList[[idx]]), 
140
+        redMat[[DimName]] <- base::matrix(NA, nrow = ncol(sceList[[idx]]),
141 141
                                           ncol = length(reducedDims[[DimName]][[2]]),
142 142
                                           dimnames = list(colnames(sceList[[idx]]), reducedDims[[DimName]][[2]]))
143 143
       }
144 144
     }
145
-    
145
+
146 146
     redList[[idx]] <- redMat
147 147
   }
148
-  
148
+
149 149
   return(redList)
150 150
 }
151 151
 
... ...
@@ -154,21 +154,21 @@
154 154
                         lapply(sceList, SummarizedExperiment::assayNames))
155 155
   assayList <- lapply(sceList, assays)
156 156
   assayDims <- list(
157
-    unique(unlist(lapply(sceList, rownames))), 
157
+    unique(unlist(lapply(sceList, rownames))),
158 158
     unique(unlist(lapply(sceList, colnames)))
159 159
   )
160
-  
160
+
161 161
   asList <- list()
162 162
   for (idx in seq_along(assayList)){
163 163
     assay <- assayList[[idx]]
164 164
     for (assayName in UnionAssays) {
165 165
       if (assayName %in% names(assay)) {
166 166
         assay[[assayName]] <- .getMatUnion(assayDims, assay[[assayName]],
167
-                                           combineRow = TRUE, combineCol = FALSE, 
167
+                                           combineRow = TRUE, combineCol = FALSE,
168 168
                                            sparse = TRUE, fill = "0")
169 169
       } else{
170
-        assay[[assayName]] <- Matrix::Matrix(0, nrow = length(assayDims[[1]]), 
171
-                                             ncol = ncol(sceList[[idx]]), 
170
+        assay[[assayName]] <- Matrix::Matrix(0, nrow = length(assayDims[[1]]),
171
+                                             ncol = ncol(sceList[[idx]]),
172 172
                                              dimnames = list(assayDims[[1]], colnames(sceList[[idx]]))) #assayDims[[assayName]])
173 173
       }
174 174
     }
... ...
@@ -181,46 +181,48 @@
181 181
 # .mergeMetaSCE <- function(sceList) {
182 182
 #   metaList <- lapply(sceList, S4Vectors::metadata)
183 183
 #   metaNames <- unlist(lapply(metaList, names))
184
-  
184
+
185 185
 #   if ("runBarcodeRanksMetaOutput" %in% metaNames) {
186 186
 #     barcodeMetas <- lapply(metaList, function(x) {x[["runBarcodeRanksMetaOutput"]]})
187 187
 #     barcodeMetas <- do.call(rbind, barcodeMetas)
188
-    
188
+
189 189
 #     for (i in seq_along(metaList)) {
190
-#       metaList[[i]][["runBarcodeRanksMetaOutput"]] <- NULL  
190
+#       metaList[[i]][["runBarcodeRanksMetaOutput"]] <- NULL
191 191
 #     }
192
-    
192
+
193 193
 #     metaList[["runBarcodeRanksMetaOutput"]] <- barcodeMetas
194 194
 #   }
195
-  
195
+
196 196
 #   return(metaList)
197 197
 # }
198 198
 
199 199
 .mergeMetaSCE <- function(SCE_list) {
200
-  sampleMeta <- lapply(SCE_list, S4Vectors::metadata) 
200
+  sampleMeta <- lapply(SCE_list, S4Vectors::metadata)
201 201
   metaNames <- unique(unlist(lapply(sampleMeta, names)))
202 202
   NewMeta <- list()
203
-  
203
+
204 204
   for (meta in metaNames) {
205 205
     for (i in seq_along(sampleMeta)) {
206 206
       NewMeta[[meta]][[i]] <- sampleMeta[[i]][[meta]]
207 207
     }
208 208
   }
209
-  
209
+
210 210
   if ("runBarcodeRanksMetaOutput" %in% metaNames) {
211 211
     NewMeta[["runBarcodeRanksMetaOutput"]] <- unlist(NewMeta[["runBarcodeRanksMetaOutput"]])
212 212
   }
213
-  
213
+
214 214
   return(NewMeta)
215 215
 }
216 216
 
217 217
 #' Combine a list of SingleCellExperiment objects as one SingleCellExperiment object
218
-#' @param sceList A list contains \link[SingleCellExperiment]{SingleCellExperiment} objects 
218
+#' @param sceList A list contains \link[SingleCellExperiment]{SingleCellExperiment} objects
219 219
 #' @param by.r Specifications of the columns used for merging rowData. See 'Details'.
220 220
 #' @param by.c Specifications of the columns used for merging colData. See 'Details'.
221
-#' @param combined logical; if TRUE, it will combine the list of SingleCellExperiment objects. See 'Details'.  
222
-#' @return A \link[SingleCellExperiment]{SingleCellExperiment} object which combines all 
223
-#' objects in sceList. The colData is merged.  
221
+#' @param combined logical; if TRUE, it will combine the list of SingleCellExperiment objects. See 'Details'.
222
+#' @return A \link[SingleCellExperiment]{SingleCellExperiment} object which combines all
223
+#' objects in sceList. The colData is merged.
224
+#' @examples
225
+#' combinedsce <- combineSCE(list(sce,sce), by.r = NULL, by.c = NULL, combined = TRUE)
224 226
 #' @export
225 227
 
226 228
 combineSCE <- function(sceList, by.r, by.c, combined){
... ...
@@ -229,19 +231,19 @@ combineSCE <- function(sceList, by.r, by.c, combined){
229 231
   ## colData
230 232
   newCbList <- .mergeColDataSCE(sceList, by.c)
231 233
   ## reducedDim
232
-  redMatList <- .mergeRedimSCE(sceList) 
234
+  redMatList <- .mergeRedimSCE(sceList)
233 235
   ## assay
234
-  assayList <- .mergeAssaySCE(sceList) 
235
-  
236
+  assayList <- .mergeAssaySCE(sceList)
237
+
236 238
   New_SCE <- list()
237 239
   for (i in seq(length(sceList))) {
238 240
     ## create new sce
239 241
     New_SCE[[i]] <- .constructSCE(matrices = assayList[[i]], features = newFeList,
240
-                                  barcodes = newCbList[[i]], 
242
+                                  barcodes = newCbList[[i]],
241 243
                                   metadata = S4Vectors::metadata(sceList[[i]]),
242 244
                                   reducedDims = redMatList[[i]])
243 245
   }
244
-  
246
+
245 247
   if (isTRUE(combined)) {
246 248
     sce <- do.call(SingleCellExperiment::cbind, New_SCE)
247 249
     meta <- .mergeMetaSCE(New_SCE)
... ...
@@ -329,11 +329,9 @@
329 329
 #' @return SingleCellExperiment object containing the
330 330
 #'  'doublet_finder_doublet_score'.
331 331
 #' @examples
332
-#' \donttest{
333 332
 #' data(scExample, package = "singleCellTK")
334 333
 #' sce <- sce[, colData(sce)$type != 'EmptyDroplet']
335 334
 #' sce <- runDoubletFinder(sce)
336
-#' }
337 335
 #' @export
338 336
 #' @importFrom SummarizedExperiment colData colData<-
339 337
 #' @importFrom SingleCellExperiment reducedDim<-
... ...
@@ -1,5 +1,5 @@
1
-#' @title Export a \link[SingleCellExperiment]{SingleCellExperiment} R object as 
2
-#' Python annData object 
1
+#' @title Export a \link[SingleCellExperiment]{SingleCellExperiment} R object as
2
+#' Python annData object
3 3
 #' @description Writes all assays, colData, rowData, reducedDims, and altExps objects in a
4 4
 #' \link[SingleCellExperiment]{SingleCellExperiment} to a Python annData object in the .h5ad format
5 5
 #' All parameters of Anndata.write_h5ad function (https://icb-anndata.readthedocs-hosted.com/en/stable/anndata.AnnData.write_h5ad.html)
... ...
@@ -9,7 +9,7 @@
9 9
 #'  exported.
10 10
 #' @param useAssay Character. The name of assay of
11 11
 #' interests that will be set as the primary matrix of the output AnnData.
12
-#' Default \code{"counts"}. 
12
+#' Default \code{"counts"}.
13 13
 #' @param outputDir Path to the directory where .h5ad outputs will be written. Default is the current working directory.
14 14
 #' @param prefix Prefix to use for the name of the output file. Default \code{"sample"}.
15 15
 #' @param overwrite Boolean. Default \code{TRUE}.
... ...
@@ -17,15 +17,13 @@
17 17
 #' 'gzip' or 'lzf' as inputs. Default \code{None}.
18 18
 #' @param compressionOpts Integer. Sets the compression level
19 19
 #' @param forceDense Default \code{False} Write sparse data as a dense matrix.
20
-#' Refer \code{anndata.write_h5ad} documentation for details. Default \code{NULL}. 
20
+#' Refer \code{anndata.write_h5ad} documentation for details. Default \code{NULL}.
21 21
 #' @examples
22
-#' \dontrun{
23 22
 #' data(sce_chcl, package = "scds")
24 23
 #' exportSCEtoAnnData(sce=sce_chcl, compression="gzip")
25
-#' }
26
-#' 
24
+#'
27 25
 #' @export
28
-exportSCEtoAnnData <- function(sce, 
26
+exportSCEtoAnnData <- function(sce,
29 27
                                 useAssay = 'counts',
30 28
                                 outputDir = "./",
31 29
                                 prefix = "sample",
... ...
@@ -50,7 +48,7 @@ exportSCEtoAnnData <- function(sce,
50 48
             " function from the 'reticulate' package can be used to select the",
51 49
             " correct Python environment.")
52 50
     return(sce)}
53
-  
51
+
54 52
   AssayName <- SummarizedExperiment::assayNames(sce)
55 53
   for (assay in AssayName){
56 54
     if (!methods::is(SummarizedExperiment::assay(sce, assay), 'dgCMatrix')) {
... ...
@@ -58,18 +56,18 @@ exportSCEtoAnnData <- function(sce,
58 56
     }
59 57
   }
60 58
 
61
-  
59
+
62 60
   dir.create(outputDir, showWarnings = FALSE, recursive = TRUE)
63 61
   annData <- .sce2adata(sce,useAssay)
64 62
   fileName <- paste0(prefix,".h5ad")
65 63
   filePath <- file.path(outputDir,fileName)
66
-  
64
+
67 65
   if (file.exists(filePath) && !isTRUE(overwrite)) {
68 66
     stop(paste0(path, " already exists. Change 'outputDir' or set 'overwrite' to TRUE."))
69 67
     }
70 68
 
71 69
   annData$write_h5ad(filePath,
72
-                     compression = compression, 
70
+                     compression = compression,
73 71
                      compression_opts = compressionOpts,
74 72
                      force_dense = forceDense)
75 73
 }
... ...
@@ -10,13 +10,11 @@
10 10
 #' @param gzipped Boolean. \code{TRUE} if the output files are to be
11 11
 #'  gzip compressed. \code{FALSE} otherwise. Default
12 12
 #'  \code{TRUE}.
13
-#' @param sample Name of the sample. It will be used as the prefix of file names. 
13
+#' @param sample Name of the sample. It will be used as the prefix of file names.
14 14
 #' @examples
15
-#' \dontrun{
16 15
 #' data(sce_chcl, package = "scds")
17 16
 #' exportSCEtoFlatFile(sce_chcl, "sce_chcl")
18
-#' }
19
-#' 
17
+#'
20 18
 #' @export
21 19
 #' @importFrom SummarizedExperiment colData rowData
22 20
 exportSCEtoFlatFile <- function(sce,
... ...
@@ -24,10 +22,10 @@ exportSCEtoFlatFile <- function(sce,
24 22
                                 overwrite = TRUE,
25 23
                                 gzipped = TRUE,
26 24
                                 sample = 'sample') {
27
-  
25
+
28 26
   .writeAssays(sce, outputDir, overwrite, gzipped, sample)
29
-  .writeColData(sce, outputDir, overwrite, gzipped, sample)  
30
-  .writeRowData(sce, outputDir, overwrite, gzipped, sample)  
27
+  .writeColData(sce, outputDir, overwrite, gzipped, sample)
28
+  .writeRowData(sce, outputDir, overwrite, gzipped, sample)
31 29
   .writeMetaData(sce, outputDir, overwrite, sample)
32 30
   .writeReducedDims(sce, outputDir, overwrite, gzipped, sample)
33 31
   .writeAltExps(sce, outputDir, overwrite, gzipped, sample)
... ...
@@ -42,13 +40,13 @@ exportSCEtoFlatFile <- function(sce,
42 40
 
43 41
 # function to write txt gz files
44 42
 .writeSCEFile <- function(data, path, overwrite, gzipped) {
45
-  
43
+
46 44
   if(is.null(rownames(data))) {
47 45
     data <- data.frame(ID = seq(nrow(data)), data)
48 46
   } else {
49 47
     data <- data.frame(ID = rownames(data), data)
50 48
   }
51
-  
49
+
52 50
   if (isTRUE(gzipped)) {
53 51
     filename <- paste0(path, ".txt.gz")
54 52
   } else {
... ...
@@ -65,7 +63,7 @@ exportSCEtoFlatFile <- function(sce,
65 63
   if (length(SummarizedExperiment::assays(sce)) > 0) {
66 64
     assaysFolder <- file.path(path, "/assays")
67 65
     dir.create(assaysFolder, showWarnings = FALSE, recursive = TRUE)
68
-    
66
+
69 67
     assayNames <- names(SummarizedExperiment::assays(sce))
70 68
     if(is.null(assayNames)) {
71 69
       assayNames <- paste0("assay", seq(SummarizedExperiment::assays(sce)))
... ...
@@ -74,16 +72,16 @@ exportSCEtoFlatFile <- function(sce,
74 72
       message(date(), " .. Writing assay '", assayNames[i], "'")
75 73
       filename <- paste(sample, paste0(assayNames[i], ".mtx"), sep="_")
76 74
       assaypath <- file.path(assaysFolder, filename)
77
-      
75
+
78 76
       .checkOverwrite(assaypath, overwrite)
79 77
       mat <- .convertToMatrix(SummarizedExperiment::assays(sce)[[i]])
80 78
       out <- Matrix::writeMM(mat, assaypath)
81
-      
79
+
82 80
       if(isTRUE(gzipped)) {
83 81
         .checkOverwrite(paste0(assaypath, ".gz"), overwrite)
84 82
         R.utils::gzip(filename = assaypath, overwrite = overwrite)
85 83
       }
86
-    }  
84
+    }
87 85
   }
88 86
 }
89 87
 
... ...
@@ -94,13 +92,13 @@ exportSCEtoFlatFile <- function(sce,
94 92
   if (length(SingleCellExperiment::altExpNames(sce)) > 0) {
95 93
     altExpsFolder <- file.path(path, "/altExps")
96 94
     dir.create(altExpsFolder, showWarnings = FALSE, recursive = TRUE)
97
-    
95
+
98 96
     altExpNames <- SingleCellExperiment::altExpNames(sce)
99 97
     for (i in altExpNames) {
100 98
       sceAltExp <- SingleCellExperiment::altExp(sce, i, withColData = FALSE)
101 99
       altExpPath <- file.path(path, i)
102 100
       message(date(), " .. Writing altExp '", i, "'")
103
-      
101
+
104 102
       assaysFolder <- file.path(altExpPath, "/assays")
105 103
       dir.create(assaysFolder, showWarnings = FALSE, recursive = TRUE)
106 104
       .writeAssays(sceAltExp, path = assaysFolder, overwrite = overwrite, gzipped = gzipped, sample)
... ...
@@ -117,7 +115,7 @@ exportSCEtoFlatFile <- function(sce,
117 115
     data <- SummarizedExperiment::colData(sce)
118 116
     colDataPath <- file.path(path, paste(sample, "colData", sep="_"))
119 117
     .writeSCEFile(data, colDataPath, overwrite, gzipped)
120
-  } 
118
+  }
121 119
 }
122 120
 
123 121
 
... ...
@@ -137,7 +135,7 @@ exportSCEtoFlatFile <- function(sce,
137 135
   if (length(SingleCellExperiment::reducedDimNames(sce)) > 0) {
138 136
     reducedDimsFolder <- file.path(path, "reducedDims")
139 137
     dir.create(reducedDimsFolder, showWarnings = FALSE, recursive = TRUE)
140
-    
138
+
141 139
     if (length(reducedDimNames(sce)) > 0) {
142 140
       reducedDimNames <- SingleCellExperiment::reducedDimNames(sce)
143 141
       for (i in reducedDimNames) {
... ...
@@ -155,7 +153,7 @@ exportSCEtoFlatFile <- function(sce,
155 153
   if (length(S4Vectors::metadata(sce)) > 0) {
156 154
     metadataFolder <- file.path(path, "/metadata")
157 155
     dir.create(metadataFolder, showWarnings = FALSE, recursive = TRUE)
158
-    
156
+
159 157
     filename <- file.path(metadataFolder, paste(sample, "metadata.rds", sep="_"))
160 158
     .checkOverwrite(filename, overwrite)
161 159
     saveRDS(object = S4Vectors::metadata(sce), file = filename)
... ...
@@ -40,8 +40,8 @@
40 40
 #' @param sampleRelWidths If there are multiple samples and combining by "all",
41 41
 #'  the relative widths for each plot.
42 42
 #' @examples
43
-#' \donttest{
44 43
 #' data(scExample, package="singleCellTK")
44
+#' \donttest{
45 45
 #' sce <- sce[, colData(sce)$type != "EmptyDroplet"]
46 46
 #' sce <- getUMAP(inSCE=sce, useAssay="counts", reducedDimName="UMAP")
47 47
 #' sce <- runPerCellQC(sce)
... ...
@@ -888,7 +888,8 @@ plotDoubletFinderResults <- function(inSCE,
888 888
         pattern="doubletFinder_doublet_score_",
889 889
         "", x=x
890 890
       ))
891
-    })
891
+    }, character(1))
892
+
892 893
     # merged.plots <- list(merged.plots)
893 894
     merged.plots <- list(Violin = merged.plots)
894 895
   }
... ...
@@ -926,7 +927,7 @@ plotDoubletFinderResults <- function(inSCE,
926 927
             pattern="doubletFinder_doublet_score_",
927 928
             "", x=x
928 929
         ))
929
-    })
930
+    }, character(1))
930 931
     res.list <- c(res.list, densityScore)
931 932
 
932 933
     scatterScore <- lapply(df.scores, function(x) {
... ...
@@ -969,7 +970,7 @@ plotDoubletFinderResults <- function(inSCE,
969 970
         pattern="doubletFinder_doublet_score_",
970 971
         "", x=x
971 972
       ))
972
-    })
973
+    }, character(1))
973 974
     res.list <- c(res.list, scatterScore)
974 975
 
975 976
     if(combinePlot != "all" | length(samples) == 1){
... ...
@@ -1007,7 +1008,7 @@ plotDoubletFinderResults <- function(inSCE,
1007 1008
         pattern="doubletFinder_doublet_score_",
1008 1009
         "", x=x
1009 1010
       ))
1010
-    })
1011
+    }, character(1))
1011 1012
     res.list <- c(res.list, violinScore)
1012 1013
     }
1013 1014
 
... ...
@@ -1053,7 +1054,7 @@ plotDoubletFinderResults <- function(inSCE,
1053 1054
         pattern="doubletFinder_doublet_label_",
1054 1055
         "", x=x
1055 1056
       ))
1056
-    })
1057
+    }, character(1))
1057 1058
     res.list <- c(res.list, scatterCall)
1058 1059
     return(res.list)
1059 1060
   })
... ...
@@ -623,13 +623,11 @@ plotSCEDimReduceFeatures <- function(inSCE,
623 623
 #'  as the labels. If set to "none", no label will be plotted.
624 624
 #' @return a ggplot of the reduced dimensions.
625 625
 #' @examples
626
-#' \donttest{
627 626
 #' plotSCEScatter(
628 627
 #'   inSCE = mouseBrainSubsetSCE, legendTitle = NULL,
629 628
 #'   slot = "assays", annotation = "counts", feature = "Apoe",
630 629
 #'   reducedDimName = "TSNE_counts", labelClusters = FALSE
631 630
 #' )
632
-#' }
633 631
 #' @export
634 632
 #' @import SingleCellExperiment
635 633
 plotSCEScatter <- function(inSCE,
... ...
@@ -8,8 +8,8 @@
8 8
 #' @param output_dir name of the output directory to save the rendered file. If NULL/default the file is stored to the current working directory
9 9
 #' @return .html file
10 10
 #' @examples
11
-#' \dontrun{
12 11
 #' data(scExample, package = "singleCellTK")
12
+#' \dontrun{
13 13
 #' sce <- runDropletQC(sce)
14 14
 #' reportDropletQC(inSCE = sce)
15 15
 #' }
... ...
@@ -46,9 +46,9 @@ reportDropletQC <- function(inSCE, output_file = NULL,
46 46
 #' @param output_dir name of the output directory to save the rendered file. If NULL/default the file is stored to the current working directory
47 47
 #' @return .html file
48 48
 #' @examples
49
-#' \dontrun{
50 49
 #' data(scExample, package = "singleCellTK")
51 50
 #' sce <- sce[, colData(sce)$type != 'EmptyDroplet']
51
+#' \dontrun{
52 52
 #' sce <- runCellQC(sce)
53 53
 #' reportCellQC(inSCE = sce)
54 54
 #' }
... ...
@@ -83,9 +83,9 @@ reportCellQC <- function(inSCE, output_file = NULL,
83 83
 #' @param output_dir name of the output directory to save the rendered file. If NULL/default the file is stored to the current working directory
84 84
 #' @return .html file
85 85
 #' @examples
86
-#' \donttest{
87 86
 #' data(scExample, package = "singleCellTK")
88 87
 #' sce <- sce[, colData(sce)$type != 'EmptyDroplet']
88
+#' \donttest{
89 89
 #' sce <- runDecontX(sce)
90 90
 #' sce <- getUMAP(sce)
91 91
 #' reportQCTool(inSCE = sce, algorithm = "DecontX")
... ...
@@ -165,6 +165,12 @@ reportQCTool <- function(inSCE, algorithm=c("BarcodeRankDrops",
165 165
 #' @param output_dir name of the output directory to save the rendered file. If
166 166
 #' \code{NULL} the file is stored to the current working directory.
167 167
 #' Default \code{NULL}.
168
+#' @examples
169
+#' data(scExample, package = "singleCellTK")
170
+#' sce <- sce[, colData(sce)$type != 'EmptyDroplet']
171
+#' sce <- runDEAnalysis(inSCE = sce, groupName1 = "Sample1", method = "DESeq2",
172
+#'  groupName2 = "Sample2", index1 = 1:20, index2 = 21:40, analysisName = "DESeq2")
173
+#' reportDiffExp(sce, study = "DESeq2", output_file = "DESeq2_res")
168 174
 #' @return .html file
169 175
 #' @export
170 176
 reportDiffExp <- function(inSCE, study,
... ...
@@ -1,25 +1,25 @@
1 1
 .importAnnDataSample <- function(sampleDir = './',
2 2
                                  sampleName = 'sample',
3 3
                                  delayedArray = TRUE){
4
-  
4
+
5 5
   anndata_file <- file.path(sampleDir, paste0(sampleName,'.h5ad',sep=''))
6 6
   if (!file.exists(anndata_file)){
7 7
     stop("AnnData file not found at specified location. Please check path provided and/or filename.")
8 8
   }
9 9
   anndata <- ad$read_h5ad(anndata_file)
10
-  
10
+
11 11
   counts_matrix <- t((reticulate::py_to_r(anndata$X)))
12 12
   if (isTRUE(delayedArray)) {
13 13
     counts_matrix <- DelayedArray::DelayedArray(counts_matrix)
14 14
   }
15
-  
15
+
16 16
   sce_rowdata <- S4Vectors::DataFrame(reticulate::py_to_r(anndata$var))
17 17
   sce_coldata <- S4Vectors::DataFrame(reticulate::py_to_r(anndata$obs))
18 18
   sce <- SingleCellExperiment(list(counts = counts_matrix),
19 19
                               rowData = sce_rowdata,
20 20
                               colData = sce_coldata)
21 21
   colnames(sce) <- paste0(sampleName,"_",colnames(sce))
22
-  
22
+
23 23
   multidim_observations <- reticulate::py_to_r(anndata$obsm_keys())
24 24
   for(obsm_name in multidim_observations){
25 25
     tryCatch({
... ...
@@ -28,9 +28,9 @@
28 28
       error_message <- paste0("Warning: unable to add '",uns_name,"' from .obsm AnnData slot to SCE metadata. Skipping. ")
29 29
       message(error_message)
30 30
     })
31
-    
31
+
32 32
   }
33
-  
33
+
34 34
   unstructured_data <- reticulate::py_to_r(anndata$uns_keys())
35 35
   for(uns_name in unstructured_data){
36 36
     tryCatch({
... ...
@@ -39,71 +39,72 @@
39 39
       error_message <- paste0("Warning: unable to add unstructured data (.uns slot): '",uns_name,"' to SCE metadata. Skipping. ")
40 40
       message(error_message)
41 41
     })
42
-    
42
+
43 43
   }
44
-  
44
+
45 45
   return(sce)
46
-  
46
+
47 47
 }
48 48
 
49 49
 #' @name importAnnData
50 50
 #' @rdname importAnnData
51 51
 #' @title Create a SingleCellExperiment Object from Python AnnData .h5ad files
52
-#' @description This function reads in one or more Python AnnData files in the .h5ad format 
53
-#' and returns a single \link[SingleCellExperiment]{SingleCellExperiment} object containing all the 
52
+#' @description This function reads in one or more Python AnnData files in the .h5ad format
53
+#' and returns a single \link[SingleCellExperiment]{SingleCellExperiment} object containing all the
54 54
 #' AnnData samples by concatenating their counts matrices and related information slots.
55
-#' @param sampleDirs Folder containing the .h5ad file. Can be one of - 
55
+#' @param sampleDirs Folder containing the .h5ad file. Can be one of -
56 56
 #' \itemize{
57 57
 #'   \item Default \code{current working directory}.
58
-#'   \item Full path to the directory containing the .h5ad file. 
58
+#'   \item Full path to the directory containing the .h5ad file.
59 59
 #'   E.g \code{sampleDirs = '/path/to/sample'}
60
-#'   \item A vector of folder paths for the samples to import. 
60
+#'   \item A vector of folder paths for the samples to import.
61 61
 #'   E.g. \code{sampleDirs = c('/path/to/sample1', '/path/to/sample2','/path/to/sample3')}
62
-#'   importAnnData will return a single SCE object containing all the samples 
62
+#'   importAnnData will return a single SCE object containing all the samples
63 63
 #'   with the sample name appended to each colname in colData
64 64
 #' }
65
-#' @param sampleNames The prefix/name of the .h5ad file without the .h5ad extension 
65
+#' @param sampleNames The prefix/name of the .h5ad file without the .h5ad extension
66 66
 #' e.g. if 'sample.h5ad' is the filename, pass \code{sampleNames = 'sample'}.
67
-#' Can be one of - 
67
+#' Can be one of -
68 68
 #' \itemize{
69 69
 #'   \item Default \code{sample}.
70 70
 #'   \item A vector of samples to import. Length of vector must be equal to length of sampleDirs vector
71 71
 #'   E.g. \code{sampleDirs = c('sample1', 'sample2','sample3')}
72
-#'   importAnnData will return a single SCE object containing all the samples 
72
+#'   importAnnData will return a single SCE object containing all the samples
73 73
 #'   with the sample name appended to each colname in colData
74 74
 #' }
75 75
 #' @param delayedArray Boolean. Whether to read the expression matrix as
76 76
 #'  \link[DelayedArray]{DelayedArray} object. Default \code{TRUE}.
77 77
 #' @details
78 78
 #' \code{importAnnData} converts scRNA-seq data in the AnnData format to the
79
-#' \code{SingleCellExperiment} object. The .X slot in AnnData is transposed to the features x cells 
79
+#' \code{SingleCellExperiment} object. The .X slot in AnnData is transposed to the features x cells
80 80
 #' format and becomes the 'counts' matrix in the assay slot. The .vars AnnData slot becomes the SCE rowData
81 81
 #' and the .obs AnnData slot becomes the SCE colData. Multidimensional data in the .obsm AnnData slot is
82
-#' ported over to the SCE reducedDims slot. Additionally, unstructured data in the .uns AnnData slot is 
83
-#' available through the SCE metadata slot. 
84
-#' There are 2 currently known minor issues - 
82
+#' ported over to the SCE reducedDims slot. Additionally, unstructured data in the .uns AnnData slot is
83
+#' available through the SCE metadata slot.
84
+#' There are 2 currently known minor issues -
85 85
 #' Anndata python module depends on another python module h5pyto read hd5 format files.
86 86
 #' If there are errors reading the .h5ad files, such as "ValueError: invalid shape in fixed-type tuple."
87
-#' the user will need to do downgrade h5py by running \code{pip3 install --user h5py==2.9.0} 
87
+#' the user will need to do downgrade h5py by running \code{pip3 install --user h5py==2.9.0}
88 88
 #' Additionally there might be errors in converting some python objects in the unstructured data slots.
89 89
 #' There are no known R solutions at present. Refer \url{https://github.com/rstudio/reticulate/issues/209}
90 90
 #' @return A \code{SingleCellExperiment} object.
91 91
 #' @examples
92
+#' file.path <- system.file("extdata/annData_pbmc_3k", package = "singleCellTK")
92 93
 #' \dontrun{
93
-#' sce <- importAnnData(sampleDirs = system.file("extdata/annData_pbmc_3k", package = "singleCellTK"),
94
+#' sce <- importAnnData(sampleDirs = file.path,
94 95
 #'                      sampleNames = 'pbmc3k_20by20')
95 96
 #' }
96 97
 #' @export
97 98
 importAnnData <- function(sampleDirs = NULL,
98 99
                           sampleNames = NULL,
99 100
                           delayedArray = TRUE) {
100
-  
101
+
101 102
   if (length(sampleDirs)!=length(sampleNames)){
102 103
     stop("Number of sampleDirs must be equal to number of SampleNames. Please provide sample names for all input directories")
103 104
   }
104
-  
105
+
105 106
   res <- vector("list", length = length(sampleDirs))
106
-  
107
+
107 108
   for (i in seq_along(sampleDirs)){
108 109
     scei <- .importAnnDataSample(sampleDir = sampleDirs[[i]],
109 110
                                  sampleName = sampleNames[[i]],
... ...
@@ -6,12 +6,12 @@
6 6
 #' \link[TENxPBMCData]{TENxPBMCData} packages. See 'Details' for a
7 7
 #' list of available datasets.
8 8
 #' @param dataset Character. Name of the dataset to retrieve.
9
-#' @param class Character. The class of the expression matrix stored in the SCE 
9
+#' @param class Character. The class of the expression matrix stored in the SCE
10 10
 #'   object. Can be one of \code{"Matrix"} or \code{"matrix"}. \code{"Matrix"}
11 11
 #'   will store the data as a sparse matrix from package \link{Matrix} while
12 12
 #'   \code{"matrix"} will store the data in a standard matrix. Default
13 13
 #'   \code{"Matrix"}.
14
-#' @param delayedArray Boolean. Whether to read the expression matrix as 
14
+#' @param delayedArray Boolean. Whether to read the expression matrix as
15 15
 #'   \link[DelayedArray]{DelayedArray} object or not. Default \code{FALSE}.
16 16
 #' @details See the list below for the available datasets and their
17 17
 #' descriptions.
... ...
@@ -24,32 +24,30 @@
24 24
 #' \code{\link[scRNAseq]{ReprocessedAllenData}}. Returns a dataset of 379 mouse
25 25
 #' brain cells from Tasic et al. (2016).}
26 26
 #' \item{"pbmc3k"}{Retrieved with \code{\link[TENxPBMCData]{TENxPBMCData}}.
27
-#'  2,700 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.} 
27
+#'  2,700 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.}
28 28
 #' \item{"pbmc4k"}{Retrieved with \code{\link[TENxPBMCData]{TENxPBMCData}}.
29
-#'  4,340 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.} 
29
+#'  4,340 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.}
30 30
 #' \item{"pbmc6k"}{Retrieved with \code{\link[TENxPBMCData]{TENxPBMCData}}.
31
-#'  5,419 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.} 
31
+#'  5,419 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.}
32 32
 #' \item{"pbmc8k"}{Retrieved with \code{\link[TENxPBMCData]{TENxPBMCData}}.
33 33
 #'  8,381 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.}
34 34
 #' \item{"pbmc33k"}{Retrieved with \code{\link[TENxPBMCData]{TENxPBMCData}}.
35
-#'  33,148 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.} 
35
+#'  33,148 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.}
36 36
 #' \item{"pbmc68k"}{Retrieved with \code{\link[TENxPBMCData]{TENxPBMCData}}.
37 37
 #'  68,579 peripheral blood mononuclear cells (PBMCs) from 10X Genomics.}
38
-#' }   
38
+#' }
39 39
 #' @author Joshua D. Campbell, David Jenkins
40
-#' @examples 
41
-#' \dontrun{
40
+#' @examples
42 41
 #' sce <- importExampleData("pbmc3k")
43
-#' }
44 42
 #' @export
45 43
 #' @importFrom SummarizedExperiment colData rowData colData<- assay assays
46 44
 importExampleData <- function(dataset, class = c("Matrix", "matrix"),
47 45
                               delayedArray = FALSE) {
48 46
   class <- match.arg(class)
49
-  
47
+
50 48
   scRNAseqDatasets <- c("fluidigm_pollen", "allen_tasic")
51 49
   tenxPbmcDatasets <- c("pbmc3k", "pbmc4k", "pbmc6k", "pbmc8k", "pbmc33k", "pbmc68k")
52
-  
50
+
53 51
   if(dataset %in% scRNAseqDatasets) {
54 52
     if(!("scRNAseq" %in% rownames(utils::installed.packages()))) {
55 53
       stop(paste0("Package 'scRNAseq' is not installed. Please install to load dataset '", dataset, "'."))
... ...
@@ -72,15 +70,15 @@ importExampleData <- function(dataset, class = c("Matrix", "matrix"),
72 70
   } else {
73 71
     stop("'dataset' must be one of: ", paste(c(scRNAseqDatasets, tenxPbmcDatasets), collapse = ","))
74 72
   }
75
-    
73
+
76 74
   # Convert to sparseMatrix or regular matrix
77 75
   for(i in seq_along(names(assays(temp)))) {
78 76
     if (class == "matrix") {
79 77
       assay(temp, i) <- as.matrix(temp)
80 78
     } else if(class == "Matrix") {
81
-      assay(temp, i) <- .convertToMatrix(assay(temp, i))  
79
+      assay(temp, i) <- .convertToMatrix(assay(temp, i))
82 80
     }
83
-    
81
+
84 82
     if (isTRUE(delayedArray)) {
85 83
       assay(temp, i) <- DelayedArray::DelayedArray(assay(temp, i))
86 84
     }
... ...
@@ -10,7 +10,7 @@
10 10
   #  sparse <- reticulate::import("scipy.sparse")
11 11
   #  numpy <- reticulate::import("numpy")
12 12
   if (!reticulate::py_module_available(module = "scipy.sparse")) {
13
-    stop("Error!", "Cannot find python module 'scipy.sparse', please install Conda and run sctkPythonInstallConda() 
13
+    stop("Error!", "Cannot find python module 'scipy.sparse', please install Conda and run sctkPythonInstallConda()
14 14
          or run sctkPythonInstallVirtualEnv(). If one of these have been previously run to install the modules,
15 15
          make sure to run selectSCTKConda() or selectSCTKVirtualEnvironment(), respectively, if R has been
16 16
          restarted since the module installation. Alternatively, scipy can be installed on the local machine
... ...
@@ -18,14 +18,14 @@
18 18
          can be used to select the correct Python environment.")
19 19
   }
20 20
   if (!reticulate::py_module_available(module = "numpy")) {
21
-    stop("Error!", "Cannot find python module 'numpy', please install Conda and run sctkPythonInstallConda() 
21
+    stop("Error!", "Cannot find python module 'numpy', please install Conda and run sctkPythonInstallConda()
22 22
          or run sctkPythonInstallVirtualEnv(). If one of these have been previously run to install the modules,
23 23
          make sure to run selectSCTKConda() or selectSCTKVirtualEnvironment(), respectively, if R has been
24 24
          restarted since the module installation. Alternatively, numpy can be installed on the local machine
25 25
          with pip (e.g. pip install numpy) and then the 'use_python()' function from the 'reticulate' package
26 26
          can be used to select the correct Python environment.")
27 27
   }
28
-  
28
+
29 29
   error <- try({
30 30
     mat <- sparse$load_npz(matrixLocation)
31 31
     colIndex <- as.vector(numpy$load(colIndexLocation, allow_pickle = TRUE))
... ...
@@ -54,11 +54,11 @@
54 54
     rownames(newM) <- rownames(mat)
55 55
     mat <- newM
56 56
   }, silent = TRUE)
57
-  
57
+
58 58
   if(inherits(error, "try-error")) {
59 59
     stop(paste0("importOptimus did not complete successfully. SCE could not be generated. Error given during the import process: \n\n", error))
60 60
   }
61
-  
61
+
62 62
   if (class == "matrix") {
63 63
     mat <- as.matrix(mat)
64 64
   }
... ...
@@ -251,10 +251,10 @@
251 251
 #'  containing the count
252 252
 #'  matrix, the gene annotation, and the cell annotation.
253 253
 #' @examples
254
+#' file.path <- system.file("extdata/Optimus_20x1000",
255
+#'   package = "singleCellTK")
254 256
 #' \dontrun{
255
-#' sce <- importOptimus(OptimusDirs =
256
-#'   system.file("extdata/Optimus_20x1000",
257
-#'   package = "singleCellTK"),
257
+#' sce <- importOptimus(OptimusDirs = file.path,
258 258
 #'   samples = "Optimus_20x1000")
259 259
 #' }
260 260
 #' @export
... ...
@@ -236,6 +236,10 @@ featureNameDedup <- function(countmat){
236 236
 #' or to identify partial matches using \code{\link{grep}}. Default \code{TRUE}
237 237
 #' @param firstMatch A logical scalar. Whether to only identify the first
238 238
 #' matches or to return all plausible matches. Default \code{TRUE}
239
+#' @examples
240
+#' data(scExample, package = "singleCellTK")
241
+#' retrieveSCEIndex(inSCE = sce, IDs = "ENSG00000205542",
242
+#'  axis = "row")
239 243
 #' @return A unique, non-NA numeric vector of indices for the matching
240 244
 #' features/cells in \code{inSCE}.
241 245
 #' @author Yusuke Koga, Joshua Campbell
... ...
@@ -172,6 +172,9 @@ plotBatchVariance <- function(inSCE, useAssay = NULL, useReddim = NULL,
172 172
 #' @param xlab label for x-axis. Default \code{"batch"}.
173 173
 #' @param ylab label for y-axis. Default \code{"Feature Mean"}.
174 174
 #' @param ... Additional arguments passed to \code{\link{.ggViolin}}.
175
+#' @examples
176
+#' data('sceBatches', package = 'singleCellTK')
177
+#' plotSCEBatchFeatureMean(sceBatches, useAssay = "logcounts")
175 178
 #' @return ggplot
176 179
 #' @export
177 180
 plotSCEBatchFeatureMean <- function(inSCE, useAssay = NULL, useReddim = NULL,
... ...
@@ -44,6 +44,7 @@
44 44
 #' @param ncol Integer. Number of columns in the plot grid. Default \code{6}.
45 45
 #' @param defaultTheme Logical scalar. Whether to use default SCTK theme in
46 46
 #' ggplot. Default \code{TRUE}.
47
+#'
47 48
 #' @return A ggplot object of violin plot
48 49
 #' @export
49 50
 plotDEGViolin <- function(inSCE, useResult, threshP = FALSE, labelBy = NULL,
... ...
@@ -258,6 +259,15 @@ plotDEGRegression <- function(inSCE, useResult, threshP = FALSE, labelBy = NULL,
258 259
 #' @param title character. Main title of the heatmap. Default
259 260
 #' \code{"MAST Result: <useResult>"}.
260 261
 #' @param ... Other arguments passed to \code{\link{plotSCEHeatmap}}
262
+#' @examples
263
+#' data(scExample, package = "singleCellTK")
264
+#' \dontrun{
265
+#' sce <- sce[, colData(sce)$type != 'EmptyDroplet']
266
+#' sce <- runDEAnalysis(inSCE = sce, groupName1 = "Sample1", method = "DESeq2",
267
+#'  groupName2 = "Sample2", index1 = 1:100, index2 = 101:190, analysisName = "DESeq2")
268
+#' plotDEGHeatmap(sce, useResult = "DESeq2", fdrThreshold = 1)
269
+#' }
270
+#'
261 271
 #' @return A ComplexHeatmap::Heatmap object
262 272
 #' @export
263 273
 #' @author Yichen Wang
... ...
@@ -1,493 +1,496 @@
1
-#' Extract columns from row/colData and transfer to factors
2
-#' @param inSCE \linkS4class{SingleCellExperiment} inherited object.
3
-#' @param axis Choose from \code{"col"} or \code{"row"}.
4
-#' @param columns character vector. The columns needed to be extracted. If
5
-#' \code{NULL}, will return an empty \code{data.frame} with matched row
6
-#' names. Default \code{NULL}.
7
-#' @param index Valid index to subset the col/row.
8
-#' @return A \code{data.frame} object.
9
-.extractSCEAnnotation <- function(inSCE, axis = NULL, columns = NULL,
10
-                                  index = NULL){
11
-    if(is.null(axis) || !axis %in% c('col', 'row')){
12
-        stop("axis should be 'col' or 'row'.")
13
-    } else if(axis == 'col'){
14
-        data <- SummarizedExperiment::colData(inSCE)
15
-    } else if(axis == 'row'){
16
-        data <- SummarizedExperiment::rowData(inSCE)
17
-    }
18
-    if(!is.null(index)){
19
-        data <- data[index, , drop = FALSE]
20
-    }
21
-    if(is.null(columns)){
22
-        return(data.frame(row.names = rownames(data)))
23
-    } else {
24
-        df <- data[, columns, drop = FALSE]
25
-        for(i in colnames(df)){
26
-            if(is.character(df[[i]]) || is.logical(df[[i]])){
27
-                # Only converting character and logical columns, but not integer
28
-                # cluster labels..
29
-                df[[i]] <- as.factor(df[[i]])
30
-            }
31
-        }
32
-        return(df)
33
-    }
34
-}
35
-
36
-#' Generate distinct colors for all categorical col/rowData entries.
37
-#' Character columns will be considered as well as all-integer columns. Any
38
-#' column with all-distinct values will be excluded.
39
-#' @param inSCE \linkS4class{SingleCellExperiment} inherited object.
40
-#' @param axis Choose from \code{"col"} or \code{"row"}.
41
-#' @param colorGen A function that generates color code vector by giving an
42
-#' integer for the number of colors. Alternatively,
43
-#' \code{\link[grDevices]{rainbow}}. Default \code{\link{distinctColors}}.
44
-#' @return A \code{list} object containing distinct colors mapped to all
45
-#' possible categorical entries in \code{rowData(inSCE)} or
46
-#' \code{colData(inSCE)}.
47
-#' @author Yichen Wang
48
-dataAnnotationColor <- function(inSCE, axis = NULL,
49
-                                colorGen = distinctColors){
50
-    if(!is.null(axis) && axis == 'col'){
51
-        data <- SummarizedExperiment::colData(inSCE)
52
-    } else if(!is.null(axis) && axis == 'row'){
53
-        data <- SummarizedExperiment::rowData(inSCE)
54
-    } else {
55
-        stop('please specify "col" or "row"')
56
-    }
57
-    nColor <- 0
58
-    for(i in names(data)){
59
-        if(length(grep('counts', i)) > 0){
60
-            next
61
-        }
62
-        column <- stats::na.omit(data[[i]])
63
-        if(is.numeric(column)){
64
-            if(!all(as.integer(column) == column)){
65
-                # Temporarily the way to tell whether numeric categorical
66
-                next
67
-            }
68
-        }
69
-        if(is.factor(column)){
70
-            uniqLevel <- levels(column)
71
-        } else {
72
-            uniqLevel <- unique(column)
73
-        }
74
-        if(!length(uniqLevel) == nrow(data)){
75
-            # Don't generate color for all-uniq annotation (such as IDs/symbols)
76
-            nColor <- nColor + length(uniqLevel)
77
-        }
78
-    }
79
-    allColors <- colorGen(nColor)
80
-    nUsed <- 0
81
-    allColorMap <- list()
82
-    for(i in names(data)){
83
-        if(length(grep('counts', i)) > 0){
84
-            next
85
-        }
86
-        column <- stats::na.omit(data[[i]])
87
-        if(is.numeric(column)){
88
-            if(!all(as.integer(column) == column)){
89
-                # Temporarily the way to tell whether numeric categorical
90
-                next
91
-            }
92
-        }
93
-        if(is.factor(column)){
94
-            uniqLevel <- levels(column)
95
-        } else {
96
-            uniqLevel <- unique(column)
97
-        }
98
-        if(!length(uniqLevel) == nrow(data)){
99
-            subColors <- allColors[(nUsed+1):(nUsed+length(uniqLevel))]
100
-            names(subColors) <- uniqLevel
101
-            allColorMap[[i]] <- subColors
102
-            nUsed <- nUsed + length(uniqLevel)
103
-        }
104
-    }
105
-    return(allColorMap)
106
-}
107
-
108
-#' Plot heatmap of using data stored in SingleCellExperiment Object
109
-#' @param inSCE \linkS4class{SingleCellExperiment} inherited object.
110
-#' @param useAssay character. A string indicating the assay name that
111
-#' provides the expression level to plot.
112
-#' @param featureIndex A vector that can subset the input SCE object by rows
113
-#' (features). Alternatively, it can be a vector identifying features in
114
-#' another feature list indicated by \code{featureIndexBy}. Default \code{NULL}.
115
-#' @param cellIndex A vector that can subset the input SCE object by columns
116
-#' (cells). Alternatively, it can be a vector identifying cells in another
117
-#' cell list indicated by \code{featureIndexBy}. Default \code{NULL}.
118
-#' @param featureIndexBy A single character specifying a column name of
119
-#' \code{rowData(inSCE)}, or a vector of the same length as \code{nrow(inSCE)},
120
-#' where we search for the non-rowname feature indices. Default
121
-#' \code{"rownames"}.
122
-#' @param cellIndexBy A single character specifying a column name of
123
-#' \code{colData(inSCE)}, or a vector of the same length as \code{ncol(inSCE)},
124
-#' where we search for the non-rowname cell indices. Default \code{"rownames"}.
125
-#' @param featureAnnotations \code{data.frame}, with \code{rownames} containing
126
-#' all the features going to be plotted. Character columns should be factors.
127
-#' Default \code{NULL}.
128
-#' @param cellAnnotations \code{data.frame}, with \code{rownames} containing
129
-#' all the cells going to be plotted. Character columns should be factors.
130
-#' Default \code{NULL}.
131
-#' @param featureAnnotationColor A named list. Customized color settings for
132
-#' feature labeling. Should match the entries in the \code{featureAnnotations}
133
-#' or \code{rowDataName}. For each entry, there should be a list/vector of
134
-#' colors named with categories. Default \code{NULL}.
135
-#' @param cellAnnotationColor A named list. Customized color settings for
136
-#' cell labeling. Should match the entries in the \code{cellAnnotations} or
137
-#' \code{colDataName}. For each entry, there should be a list/vector of colors
138
-#' named with categories. Default \code{NULL}.
139
-#' @param rowDataName character. The column name(s) in \code{rowData} that need
140
-#' to be added to the annotation. Default \code{NULL}.
141
-#' @param colDataName character. The column name(s) in \code{colData} that need
142
-#' to be added to the annotation. Default \code{NULL}.
143
-#' @param rowSplitBy character. Do semi-heatmap based on the grouping of
144
-#' this(these) annotation(s). Should exist in either \code{rowDataName} or
145
-#' \code{names(featureAnnotations)}. Default \code{NULL}.
146
-#' @param colSplitBy character. Do semi-heatmap based on the grouping of
147
-#' this(these) annotation(s). Should exist in either \code{colDataName} or
148
-#' \code{names(cellAnnotations)}. Default \code{NULL}.
149
-#' @param rowLabel Use a logical for whether to display all the feature names,
150
-#' a single character to display a column of \code{rowData(inSCE)} annotation,
151
-#' a vector of the same length as full/subset \code{nrow(inSCE)} to display
152
-#' customized info. Default \code{FALSE}.
153
-#' @param colLabel Use a logical for whether to display all the cell names, a
154
-#' single character to display a column of \code{colData(inSCE)} annotation,
155
-#' a vector of the same length as full/subset \code{ncol(inSCE)} to display
156
-#' customized info. Default \code{FALSE}.
157
-#' @param rowDend Whether to display row dendrogram. Default \code{TRUE}.
158
-#' @param colDend Whether to display column dendrogram. Default \code{TRUE}.
159
-#' @param scale Whether to perform z-score scaling on each row. Default
160
-#' \code{TRUE}.
161
-#' @param trim A 2-element numeric vector. Values outside of this range will be
162
-#' trimmed to their nearst bound. Default \code{c(-2, 2)}
163
-#' @param title The main title of the whole plot. Default \code{"SCE Heatmap"}
164
-#' @param rowTitle The subtitle for the rows. Default \code{"Genes"}.
165
-#' @param colTitle The subtitle for the columns. Default \code{"Cells"}.
166
-#' @param rowGap A numeric value or a \code{\link[grid]{unit}} object. For the
167
-#' gap size between rows of the splitted heatmap. Default
168
-#' \code{grid::unit(0, 'mm')}.
169
-#' @param colGap A numeric value or a \code{\link[grid]{unit}} object. For the
170
-#' gap size between columns of the splitted heatmap. Default
171
-#' \code{grid::unit(0, 'mm')}.
172
-#' @param border A logical scalar. Whether to show the border of the heatmap or
173
-#' splitted heatmaps. Default \code{TRUE}.
174
-#' @param colorScheme function. A function that generates color code by giving
175
-#' a value. Can be generated by \code{\link[circlize]{colorRamp2}}.
176
-#' Default \code{NULL}.
177
-#' @param ... Other arguments passed to \code{\link[ComplexHeatmap]{Heatmap}}.
178
-#' @return A \code{\link[ComplexHeatmap]{Heatmap}} object
179
-#' @export
180
-#' @author Yichen Wang
181
-plotSCEHeatmap <- function(inSCE, useAssay = 'logcounts', featureIndex = NULL,
182
-    cellIndex = NULL, featureIndexBy = 'rownames', cellIndexBy = 'rownames',
183
-    featureAnnotations = NULL, cellAnnotations = NULL,
184
-    featureAnnotationColor = NULL, cellAnnotationColor = NULL,
185
-    rowDataName = NULL, colDataName = NULL, rowSplitBy = NULL,
186
-    colSplitBy = NULL, rowLabel = FALSE, colLabel = FALSE, rowDend = TRUE,
187
-    colDend = TRUE, scale = TRUE, trim = c(-2, 2),
188
-    title = 'SCE Heatmap', rowTitle = 'Genes', colTitle = 'Cells',
189
-    rowGap = grid::unit(0, 'mm'), colGap = grid::unit(0, 'mm'), border = FALSE,
190
-    colorScheme = NULL, ...){
191
-    # Check input
192
-    if(!inherits(inSCE, "SingleCellExperiment")){
193
-        stop('Input object is not a valid SingleCellExperiment object.')
194
-    }
195
-    if(!useAssay %in% SummarizedExperiment::assayNames(inSCE)){
196
-        stop('Specified assay does not exist in input SCE object')
197
-    }
198
-    if(!all(rowDataName %in% names(SummarizedExperiment::rowData(inSCE)))){
199
-        notIn <- !rowDataName %in% names(SummarizedExperiment::rowData(inSCE))
200
-        notIn <- rowDataName[notIn]
201
-        stop('rowDataName - Specified columns: ', paste(notIn, collapse = ', '),
202
-             ', not found. ')
203
-    }
204
-    if(!all(colDataName %in% names(SummarizedExperiment::colData(inSCE)))){
205
-        notIn <- !colDataName %in% names(SummarizedExperiment::colData(inSCE))
206
-        notIn <- colDataName[notIn]
207
-        stop('colDataName - Specified columns: ', paste(notIn, collapse = ', '),
208
-             ', not found. ')
209
-    }
210
-    if(!is.null(rowSplitBy) &&
211
-       any(!rowSplitBy %in% c(rowDataName, names(featureAnnotations)))){
212
-        notIn <- !rowSplitBy %in% c(names(SummarizedExperiment::rowData(inSCE)),
213
-                                    featureAnnotations)
214
-        notIn <- rowSplitBy[notIn]
215
-        stop('rowSplitBy - Specified columns: ', paste(notIn, collapse = ', '),
216
-             ', not found. ')
217
-    }
218
-    if(!is.null(colSplitBy) &&
219
-       any(!colSplitBy %in% c(colDataName, names(cellAnnotations)))){
220
-        notIn <- !colSplitBy %in% c(names(SummarizedExperiment::colData(inSCE)),
221
-                                    cellAnnotations)
222
-        notIn <- colSplitBy[notIn]
223
-        stop('colSplitBy - Specified columns: ', paste(notIn, collapse = ', '),
224
-             ', not found. ')
225
-    }
226
-    if(is.null(featureIndex)){
227
-        featureIndex <- 1:nrow(inSCE)
228
-    } else {
229
-        if(is.character(featureIndexBy) && length(featureIndexBy) == 1){
230
-            if(!featureIndexBy == 'rownames'){
231
-                # Search by a column in rowData
232
-                featureIndex <- celda::retrieveFeatureIndex(featureIndex,
233
-                                                            inSCE,
234
-                                                            featureIndexBy)
235
-            }
236
-        } else if(length(featureIndexBy) == nrow(inSCE)){
237
-            # featureIndexBy is vector or single-col/row matrix
238
-            featureIndex <- celda::retrieveFeatureIndex(featureIndex,
239
-                                                        featureIndexBy,
240
-                                                        '')
241
-        } else {
242
-            stop('Given "featureIndexBy" not valid. Please give a single ',
243
-                 'character to specify a column in rowData(inSCE) or a vector ',
244
-                 'as long as nrow(inSCE) where you search for "featureIndex".')
245
-        }
246
-    }
247
-    ### Force index as numeric
248
-    if(is.character(featureIndex)){
249
-        featureIndex <- which(rownames(inSCE) %in% featureIndex)
250
-    } else if(is.logical(featureIndex)){
251
-        featureIndex <- which(featureIndex)
252
-    }
253
-    if(is.null(cellIndex)){
254
-        cellIndex <- 1:ncol(inSCE)
255
-    } else {
256
-        if(is.character(cellIndexBy) && length(cellIndexBy) == 1){
257
-            if(!cellIndexBy == 'rownames'){
258
-                # Search by a column in colData
259
-                if(!cellIndexBy %in%
260
-                   names(SummarizedExperiment::colData(inSCE))){
261
-                    stop('"cellIndexBy": ', cellIndexBy, ' is not a column of ',
262
-                         'colData(inSCE)')
263
-                }
264
-                searchIn <- SummarizedExperiment::colData(inSCE)[[cellIndexBy]]
265
-                cellIndex <- celda::retrieveFeatureIndex(cellIndex,
266
-                                                            searchIn,
267
-                                                            '')
268
-            }
269
-        } else if(length(cellIndexBy) == ncol(inSCE)){
270
-            # featureIndexBy is vector or single-col/row matrix
271
-            cellIndex <- celda::retrieveFeatureIndex(cellIndex,
272
-                                                        cellIndexBy,
273
-                                                        '')
274
-        } else {
275
-            stop('Given "cellIndexBy" not valid. Please give a single ',
276
-                 'character to specify a column in colData(inSCE) or a vector ',
277
-                 'as long as ncol(inSCE) where you search for "cellIndex".')
278
-        }
279
-    }
280
-    ### Force index as numeric
281
-    if(is.character(cellIndex)){
282
-        cellIndex <- which(colnames(inSCE) %in% cellIndex)
283
-    } else if (is.logical(cellIndex)){
284
-        cellIndex <- which(cellIndex)
285
-    }
286
-    ## Customized row text labeling
287
-    rowLabelText <- rownames(inSCE)[featureIndex]
288
-    if(!is.logical(rowLabel)){
289
-        if(is.character(rowLabel) && length(rowLabel) == 1){
290
-            if(!rowLabel %in% names(SummarizedExperiment::rowData(inSCE))){
291
-                stop('"rowLabel": ', rowLabel, ' is not a column of ',
292
-                     'rowData(inSCE).')
293
-            }
294
-            rowLabelText <- SummarizedExperiment::rowData(inSCE)[featureIndex,
295
-                                                                 rowLabel]
296
-            rowLabel <- TRUE
297
-        } else if(length(rowLabel) == nrow(inSCE)){
298
-            rowLabelText <- rowLabel[featureIndex]
299
-            rowLabel <- TRUE
300
-        } else if(length(rowLabel) == length(featureIndex)){
301
-            rowLabelText <- rowLabel
302
-            rowLabel <- TRUE
303
-        } else {
304
-            stop('Invalid "rowLabel". Use TRUE/FALSE, a column name of ',
305
-                 'rowData(inSCE), or a vector as the same length of ',
306
-                 'nrow(inSCE) or the subsetted number of features.')
307
-        }
308
-    }
309
-    ## Customized col text labeling
310
-    colLabelText <- colnames(inSCE)[cellIndex]
311
-    if(!is.logical(colLabel)){
312
-        if(is.character(colLabel) && length(colLabel) == 1){
313
-            if(!colLabel %in% names(SummarizedExperiment::colData(inSCE))){
314
-                stop('"colLabel": ', colLabel, ' is not a column of ',
315
-                     'colData(inSCE).')
316
-            }
317
-            colLabelText <- SummarizedExperiment::colData(inSCE)[cellIndex,
318
-                                                                 colLabel]
319
-            colLabel <- TRUE
320
-        } else if(length(colLabel) == ncol(inSCE)){
321
-            colLabelText <- colLabel[cellIndex]
322
-            colLabel <- TRUE
323
-        } else if(length(colLabel) == length(cellIndex)){
324
-            colLabelText <- colLabel
325
-            colLabel <- TRUE
326
-        } else {
327
-            stop('Invalid "colLabel". Use TRUE/FALSE, a column name of ',
328
-                 'colData(inSCE), or a vector as the same length of ',
329
-                 'ncol(inSCE) or the subsetted number of cells.')
330
-        }
331
-    }
332
-
333
-    inSCE <- inSCE[featureIndex, cellIndex]
334
-
335
-    if (!is.null(trim) && length(trim) != 2) {
336
-        stop("'trim' should be a 2 element vector specifying the lower",
337
-             " and upper boundaries")
338
-    }
339
-    if(0 %in% dim(inSCE)){
340
-        stop('Given indices specified 0-dim')
341
-    }
342
-    if(!is.null(featureAnnotations)){
343
-        if(!all(rownames(inSCE) %in% rownames(featureAnnotations))){
344
-            stop('Incomplete feature names in `featureAnnotations')
345
-        } else {
346
-            featureAnnotations <-
347
-                featureAnnotations[rownames(inSCE), , drop = FALSE]
348
-        }
349
-    }
350
-    if(!is.null(cellAnnotations)){
351
-        if(!all(colnames(inSCE) %in% rownames(cellAnnotations))){
352
-            stop('Incomplete cell names in cellAnnotations')
353
-        } else {
354
-            cellAnnotations <- cellAnnotations[colnames(inSCE), , drop = FALSE]
355
-        }
356
-    }
357
-
358
-    # Extract
359
-    mat <- as.matrix(SummarizedExperiment::assay(inSCE, useAssay))
360
-    ## rowData info
361
-    rowDataExtract <- .extractSCEAnnotation(inSCE, 'row', rowDataName)
362
-    rowDataColor <- dataAnnotationColor(inSCE, 'row')
363
-    if(is.null(rowDataName)){
364
-        rowDataColor <- NULL
365
-    } else {
366
-        # Have to do an extraction because continuous values won't be in
367
-        # rowDataColor
368
-        rowDataColor <- rowDataColor[rowDataName[rowDataName %in%
369
-                                                     names(rowDataColor)]]
370
-    }
371
-    if(!is.null(featureAnnotationColor)){
372
-        add <- setdiff(names(rowDataColor), names(featureAnnotationColor))
373
-        featureAnnotationColor <- c(rowDataColor[add], featureAnnotationColor)
374
-    } else {
375
-        featureAnnotationColor <- rowDataColor
376
-    }
377
-    ## colData info
378
-    colDataExtract <- .extractSCEAnnotation(inSCE, 'col', colDataName)
379
-    colDataColor <- dataAnnotationColor(inSCE, 'col')
380
-    if(is.null(colDataName)){
381
-        colDataColor <- NULL
382
-    } else {
383
-        colDataColor <- colDataColor[colDataName[colDataName %in%
384
-                                                     names(colDataColor)]]
385
-    }
386
-    if(!is.null(cellAnnotationColor)){
387
-        add <- setdiff(names(colDataColor), names(cellAnnotationColor))
388
-        cellAnnotationColor <- c(colDataColor[add], cellAnnotationColor)
389
-    } else {
390
-        cellAnnotationColor <- colDataColor
391
-    }
392
-    ## Merge with extra annotations
393
-    if(is.null(featureAnnotations)){
394
-        featureAnnotations <- rowDataExtract
395
-    } else {
396
-        featureAnnotations <- data.frame(rowDataExtract, featureAnnotations)
397
-    }
398
-    if(is.null(cellAnnotations)){
399
-        cellAnnotations <- colDataExtract
400
-    } else {
401
-        cellAnnotations <- data.frame(colDataExtract, cellAnnotations)
402
-    }
403
-    # Data process
404
-    if(isTRUE(scale)){
405
-        mat <- as.matrix(computeZScore(mat))
406
-    }
407
-    if (!is.null(trim)) {
408
-        mat <- trimCounts(mat, trim)
409
-    }
410
-    # Plot
411
-    if(is.null(colorScheme)){
412
-        if(!is.null(trim)){
413
-            colorScheme <- circlize::colorRamp2(c(trim[1], 0, trim[2]),
414
-                                                c('blue', 'white', 'red'))
415
-        } else {
416
-            colorScheme <- circlize::colorRamp2(c(min(mat),
417
-                                                  (max(mat) + min(mat))/2,
418
-                                                  max(mat)),
419
-                                                c('blue', 'white', 'red'))
420
-        }
421
-
422
-    } else {
423
-        if(!is.function(colorScheme)){
424
-            stop('`colorScheme` must be a function generated by ',
425
-                 'circlize::colorRamp2')
426
-        }
427
-        breaks <- attr(colorScheme, 'breaks')
428
-        if(breaks[1] != min(trim) || breaks[length(breaks)] != max(trim)){
429
-            stop('Breaks of `colorScheme` do not match with `trim`.')
430
-        }
431
-    }
432
-    if(dim(featureAnnotations)[2] > 0){
433
-        ra <- ComplexHeatmap::rowAnnotation(df = featureAnnotations,
434
-                                            col = featureAnnotationColor)
435
-    } else {
436
-        ra <- NULL
437
-    }
438
-    if(dim(cellAnnotations)[2] > 0){
439
-        ca <- ComplexHeatmap::HeatmapAnnotation(df = cellAnnotations,
440
-                                                col = cellAnnotationColor)
441
-    } else {
442
-        ca <- NULL
443
-    }
444
-    if(!is.null(rowSplitBy)){
445
-        rs <- featureAnnotations[rowSplitBy]
446
-    } else {
447
-        rs <- NULL
448
-    }
449
-    if(!is.null(colSplitBy)){
450
-        cs <- cellAnnotations[colSplitBy]
451
-    } else {
452
-        cs <- NULL
453
-    }
454
-    if(!is.null(rowGap)) {
455
-      if(inherits(rowGap, "unit")){
456
-        rowGap <- rowGap
457
-      } else if (is.numeric(rowGap)) {
458
-        warning("rowGap is given a numeric value. Using 'mm' as the unit")
459
-        rowGap <- grid::unit(rowGap, 'mm')
460
-      } else {
461
-        stop("Given value for 'rowGap' not understandable.")
462
-      }
463
-    } else {
464
-      rowGap <- grid::unit(0, 'mm')
465
-    }
466
-    if(!is.null(colGap)) {
467
-      if (inherits(colGap, "unit")) {
468
-        colGap <- colGap
469
-      } else if(is.numeric(colGap)){
470
-        warning("colGap is given a numeric value. Using 'mm' as the unit")
471
-        colGap <- grid::unit(colGap, 'mm')
472
-      } else {
473
-        stop("Given value for 'colGap' not understandable.")
474
-      }
475
-    } else {
476
-      colGap <- grid::unit(0, 'mm')
477
-    }
478
-    rownames(mat) <- rowLabelText
479
-    colnames(mat) <- colLabelText
480
-    hm <- ComplexHeatmap::Heatmap(mat, name = useAssay, left_annotation = ra,
481
-                                  top_annotation = ca, col = colorScheme,
482
-                                  row_split = rs, column_split = cs,
483
-                                  row_title = rowTitle, column_title = colTitle,
484
-                                  show_row_names = rowLabel,
485
-                                  show_row_dend = rowDend,
486
-                                  show_column_names = colLabel,
487
-                                  show_column_dend = colDend,
488
-                                  row_gap = rowGap, column_gap = colGap,
489
-                                  border = border,
490
-                                  ...)
491
-    #HM <- ComplexHeatmap::draw(hm, column_title = title)
492
-    return(hm)
493
-}
1
+#' Extract columns from row/colData and transfer to factors
2
+#' @param inSCE \linkS4class{SingleCellExperiment} inherited object.