Browse code

Add 'matrix' methods for `spatialPatterns()` and `modelSearch()`

Milan Malfait authored on 01/06/2021 11:28:59
Showing 4 changed files

... ...
@@ -4,17 +4,25 @@
4 4
 #' Expression Histology, using the
5 5
 #' [**SpatialDE**](https://github.com/Teichlab/SpatialDE) Python package.
6 6
 #'
7
-#' @param x \linkS4class{SpatialExperiment} object.
7
+#' @param x A numeric `matrix` of counts where genes are rows and cells are columns.
8
+#'
9
+#'    Alternatively, a \linkS4class{SpatialExperiment} object.
8 10
 #'
9 11
 #' @param ... For the generic, arguments to pass to specific methods.
10
-#' @param assay_type A `character` string specifying the assay from `x` to use
11
-#'   as input. Defaults to `"counts"`.
12 12
 #' @param de_results `data.frame` resulting from [run()] or [spatialDE()].
13
+#' @param coordinates A `data.frame` with sample coordinates. Each row is a
14
+#'   sample, the columns with coordinates should be named 'x' and 'y'.
15
+#'
16
+#'   For the *SpatialExperiment* method, coordinates are taken from
17
+#'   `spatialCoords(x)`.
18
+#'
13 19
 #' @param qval_thresh `numeric` scalar, specifying the q-value significance
14 20
 #'   threshold to filter `de_results`. Only rows in `de_results` with
15 21
 #'   `qval < qval_thresh` will be kept. To disable, set `qval_thresh = NULL`.
16 22
 #' @param n_patterns `integer` The number of spatial patterns
17 23
 #' @param length `numeric` The characteristic length scale of the clusters
24
+#' @param assay_type A `character` string specifying the assay from `x` to use
25
+#'   as input. Defaults to `"counts"`.
18 26
 #' @param verbose A `logical` controlling the display of a progress bar from the
19 27
 #'   Python package.
20 28
 #'
... ...
@@ -59,36 +67,51 @@
59 67
 NULL
60 68
 
61 69
 #' @importFrom Matrix colSums
62
-.spatialPatterns <- function(counts_spe, coordinates_spe, de_results,
63
-                             n_patterns, length, verbose = FALSE) {
64
-  sample_info <- data.frame(coordinates_spe, total_counts = colSums(counts_spe))
70
+#' @importFrom checkmate assert_data_frame assert_number assert_int assert_flag
71
+.spatialPatterns <- function(x, de_results, coordinates,
72
+                             qval_thresh = 0.05, n_patterns, length,
73
+                             verbose = FALSE) {
74
+    assert_data_frame(de_results, all.missing = FALSE)
75
+    assert_number(qval_thresh, null.ok = TRUE)
76
+    assert_int(n_patterns, coerce = TRUE)
77
+    assert_number(length)
78
+    assert_flag(verbose)
79
+
80
+    ## Filter de_results
81
+    if (!is.null(qval_thresh)) {
82
+        de_results <- .filter_de_results(
83
+            de_results = de_results, qval_thresh = qval_thresh
84
+        )
85
+    }
86
+
87
+    sample_info <- data.frame(coordinates, total_counts = colSums(x))
65 88
 
66
-  out <- basilisk::basiliskRun(
67
-      env = spatialDE_env,
68
-      fun = .run_spatial_patterns,
69
-      counts_spe = counts_spe,
70
-      sample_info = sample_info,
71
-      de_results = de_results,
72
-      n_patterns = n_patterns,
73
-      length = length,
74
-      verbose = verbose
75
-  )
76
-  out
89
+    out <- basilisk::basiliskRun(
90
+        env = spatialDE_env,
91
+        fun = .run_spatial_patterns,
92
+        x = x,
93
+        sample_info = sample_info,
94
+        de_results = de_results,
95
+        n_patterns = n_patterns,
96
+        length = length,
97
+        verbose = verbose
98
+    )
99
+    out
77 100
 }
78 101
 
79
-.run_spatial_patterns <- function(counts_spe, sample_info,
80
-                                  de_results, n_patterns, length,
102
+.run_spatial_patterns <- function(x, sample_info, de_results,
103
+                                  n_patterns, length,
81 104
                                   verbose = FALSE) {
82
-  ## Normalization
83
-  stabilized <- .naiveDE_stabilize(counts = counts_spe)
84
-  regressed <- .naiveDE_regress_out(counts = stabilized, sample_info)
105
+    ## Normalization
106
+    stabilized <- .naiveDE_stabilize(counts = x)
107
+    regressed <- .naiveDE_regress_out(counts = stabilized, sample_info)
85 108
 
86
-  coordinates <- sample_info[, c("x", "y")]
87
-  .spatialDE_spatial_patterns(
88
-      x = regressed, coordinates = coordinates,
89
-      de_results = de_results, n_patterns = n_patterns,
90
-      length = length, verbose = verbose
91
-  )
109
+    coordinates <- sample_info[, c("x", "y")]
110
+    .spatialDE_spatial_patterns(
111
+        x = regressed, coordinates = coordinates,
112
+        de_results = de_results, n_patterns = n_patterns,
113
+        length = length, verbose = verbose
114
+    )
92 115
 }
93 116
 
94 117
 #' @import methods
... ...
@@ -99,36 +122,27 @@ setGeneric("spatialPatterns",
99 122
     signature = "x"
100 123
 )
101 124
 
125
+#' @export
126
+#' @rdname spatialPatterns
127
+setMethod("spatialPatterns", "matrix", .spatialPatterns)
128
+
102 129
 #' @export
103 130
 #' @rdname spatialPatterns
104 131
 #' @importFrom SummarizedExperiment assay
105 132
 #' @importFrom SpatialExperiment spatialCoords spatialCoordsNames<-
106
-#' @importFrom checkmate assert_data_frame assert_number assert_int assert_flag
107 133
 setMethod("spatialPatterns", "SpatialExperiment",
108
-  function(x, de_results, assay_type = "counts", qval_thresh = 0.05,
109
-           n_patterns, length, verbose = FALSE) {
110
-    assert_data_frame(de_results, all.missing = FALSE)
111
-    assert_number(qval_thresh, null.ok = TRUE)
112
-    assert_int(n_patterns, coerce = TRUE)
113
-    assert_number(length)
114
-    assert_flag(verbose)
134
+    function(x, de_results, qval_thresh = 0.05,
135
+             n_patterns, length,
136
+             assay_type = "counts", verbose = FALSE) {
115 137
 
116
-    ## Rename spatialCoords columns to "x", "y"
117
-    spatialCoordsNames(x) <- c("x", "y")
118
-    coordinates_spe <- as.data.frame(spatialCoords(x))
119
-    counts_spe <- assay(x, assay_type)
138
+        ## Rename spatialCoords columns to "x", "y"
139
+        spatialCoordsNames(x) <- c("x", "y")
140
+        coordinates <- as.data.frame(spatialCoords(x))
120 141
 
121
-    ## Filter de_results
122
-    if (!is.null(qval_thresh)) {
123
-      de_results <- .filter_de_results(
124
-        de_results = de_results, qval_thresh = qval_thresh
125
-      )
142
+        .spatialPatterns(
143
+            x = assay(x, assay_type), de_results = de_results,
144
+            coordinates = coordinates, qval_thresh = qval_thresh,
145
+            n_patterns = n_patterns, length = length, verbose = verbose
146
+        )
126 147
     }
127
-
128
-    .spatialPatterns(
129
-        counts_spe = counts_spe, coordinates_spe = coordinates_spe,
130
-        de_results = de_results, n_patterns = n_patterns,
131
-        length = length, verbose = FALSE
132
-    )
133
-  }
134 148
 )
... ...
@@ -3,15 +3,23 @@
3 3
 #' Compare model fits with different models, using the
4 4
 #' [**SpatialDE**](https://github.com/Teichlab/SpatialDE) Python package.
5 5
 #'
6
-#' @param x \linkS4class{SpatialExperiment} object.
6
+#' @param x A numeric `matrix` of counts where genes are rows and cells are columns.
7
+#'
8
+#'    Alternatively, a \linkS4class{SpatialExperiment} object.
7 9
 #'
8 10
 #' @param ... For the generic, arguments to pass to specific methods.
9
-#' @param assay_type A `character` string specifying the assay from `x` to use
10
-#'   as input. Defaults to `"counts"`.
11 11
 #' @param de_results `data.frame` resulting from [run()] or [spatialDE()].
12
+#' @param coordinates A `data.frame` with sample coordinates. Each row is a
13
+#'   sample, the columns with coordinates should be named 'x' and 'y'.
14
+#'
15
+#'   For the *SpatialExperiment* method, coordinates are taken from
16
+#'   `spatialCoords(x)`.
17
+#'
12 18
 #' @param qval_thresh `numeric` scalar, specifying the q-value significance
13 19
 #'   threshold to filter `de_results`. Only rows in `de_results` with
14 20
 #'   `qval < qval_thresh` will be kept. To disable, set `qval_thresh = NULL`.
21
+#' @param assay_type A `character` string specifying the assay from `x` to use
22
+#'   as input. Defaults to `"counts"`.
15 23
 #' @param verbose A `logical` controlling the display of a progress bar from the
16 24
 #'   Python package.
17 25
 #'
... ...
@@ -25,12 +33,11 @@
25 33
 #' ## Run spatialDE with S4 integration
26 34
 #' de_results <- spatialDE(spe)
27 35
 #'
28
-#' ## Run model search with S4 integration
36
+#' ## Run model search
29 37
 #' model_search <- modelSearch(spe, de_results = de_results,
30 38
 #'     qval_thresh = NULL, verbose = FALSE
31 39
 #' )
32 40
 #'
33
-#'
34 41
 #' @seealso
35 42
 #' The individual steps performed by this function: [stabilize()],
36 43
 #' [regress_out()] and [model_search()].
... ...
@@ -48,32 +55,43 @@
48 55
 NULL
49 56
 
50 57
 #' @importFrom Matrix colSums
51
-.modelSearch <- function(counts_spe, coordinates_spe, de_results,
52
-                         verbose = FALSE) {
53
-  sample_info <- data.frame(coordinates_spe, total_counts = colSums(counts_spe))
58
+#' @importFrom checkmate assert_data_frame assert_number assert_flag
59
+.modelSearch <- function(x, de_results, coordinates,
60
+                         qval_thresh = 0.05, verbose = FALSE) {
61
+    assert_data_frame(de_results, all.missing = FALSE)
62
+    assert_number(qval_thresh, null.ok = TRUE)
63
+    assert_flag(verbose)
64
+
65
+    ## Filter de_results
66
+    if (!is.null(qval_thresh)) {
67
+        de_results <- .filter_de_results(
68
+            de_results = de_results, qval_thresh = qval_thresh
69
+        )
70
+    }
71
+
72
+    sample_info <- data.frame(coordinates, total_counts = colSums(x))
54 73
 
55
-  out <- basilisk::basiliskRun(
56
-      env = spatialDE_env,
57
-      fun = .run_model_search,
58
-      counts_spe = counts_spe,
59
-      sample_info = sample_info,
60
-      de_results = de_results,
61
-      verbose = verbose
62
-  )
63
-  out
74
+    out <- basilisk::basiliskRun(
75
+        env = spatialDE_env,
76
+        fun = .run_model_search,
77
+        x = x,
78
+        sample_info = sample_info,
79
+        de_results = de_results,
80
+        verbose = verbose
81
+    )
82
+    out
64 83
 }
65 84
 
66
-.run_model_search <- function(counts_spe, sample_info, de_results,
67
-                              verbose = FALSE) {
68
-  ## Normalization
69
-  stabilized <- .naiveDE_stabilize(counts = counts_spe)
70
-  regressed <- .naiveDE_regress_out(counts = stabilized, sample_info)
85
+.run_model_search <- function(x, sample_info, de_results, verbose = FALSE) {
86
+    ## Normalization
87
+    stabilized <- .naiveDE_stabilize(counts = x)
88
+    regressed <- .naiveDE_regress_out(counts = stabilized, sample_info)
71 89
 
72
-  coordinates <- sample_info[, c("x", "y")]
73
-  .spatialDE_model_search(
74
-      x = regressed, coordinates = coordinates,
75
-      de_results = de_results, verbose = verbose
76
-  )
90
+    coordinates <- sample_info[, c("x", "y")]
91
+    .spatialDE_model_search(
92
+        x = regressed, coordinates = coordinates,
93
+        de_results = de_results, verbose = verbose
94
+    )
77 95
 }
78 96
 
79 97
 #' @import methods
... ...
@@ -84,33 +102,26 @@ setGeneric("modelSearch",
84 102
     signature = "x"
85 103
 )
86 104
 
105
+#' @export
106
+#' @rdname modelSearch
107
+setMethod("modelSearch", "matrix", .modelSearch)
108
+
87 109
 #' @export
88 110
 #' @rdname modelSearch
89 111
 #' @importFrom SummarizedExperiment assay
90 112
 #' @importFrom SpatialExperiment spatialCoords spatialCoordsNames<-
91
-#' @importFrom checkmate assert_data_frame assert_number assert_flag
92 113
 setMethod("modelSearch", "SpatialExperiment",
93
-  function(x, de_results, assay_type = "counts", qval_thresh=0.05,
94
-           verbose = FALSE) {
95
-    assert_data_frame(de_results, all.missing = FALSE)
96
-    assert_number(qval_thresh, null.ok = TRUE)
97
-    assert_flag(verbose)
114
+    function(x, de_results, assay_type = "counts",
115
+             qval_thresh = 0.05, verbose = FALSE) {
98 116
 
99
-    ## Rename spatialCoords columns to "x", "y"
100
-    spatialCoordsNames(x) <- c("x", "y")
101
-    coordinates_spe <- as.data.frame(spatialCoords(x))
102
-    counts_spe <- assay(x, assay_type)
117
+        ## Rename spatialCoords columns to "x", "y"
118
+        spatialCoordsNames(x) <- c("x", "y")
119
+        coordinates <- as.data.frame(spatialCoords(x))
103 120
 
104
-    ## Filter de_results
105
-    if (!is.null(qval_thresh)) {
106
-      de_results <- .filter_de_results(
107
-        de_results = de_results, qval_thresh = qval_thresh
108
-      )
121
+        .modelSearch(
122
+            x = assay(x, assay_type), de_results = de_results,
123
+            coordinates = coordinates, qval_thresh = qval_thresh,
124
+            verbose = verbose
125
+        )
109 126
     }
110
-
111
-    .modelSearch(
112
-        counts_spe = counts_spe, coordinates_spe = coordinates_spe,
113
-        de_results = de_results, verbose = FALSE
114
-    )
115
-  }
116 127
 )
... ...
@@ -2,11 +2,14 @@
2 2
 % Please edit documentation in R/msearch.R
3 3
 \name{modelSearch}
4 4
 \alias{modelSearch}
5
+\alias{modelSearch,matrix-method}
5 6
 \alias{modelSearch,SpatialExperiment-method}
6 7
 \title{Classify Spatially Variable Genes to interpretable fitting classes}
7 8
 \usage{
8 9
 modelSearch(x, de_results, ...)
9 10
 
11
+\S4method{modelSearch}{matrix}(x, de_results, coordinates, qval_thresh = 0.05, verbose = FALSE)
12
+
10 13
 \S4method{modelSearch}{SpatialExperiment}(
11 14
   x,
12 15
   de_results,
... ...
@@ -16,14 +19,19 @@ modelSearch(x, de_results, ...)
16 19
 )
17 20
 }
18 21
 \arguments{
19
-\item{x}{\linkS4class{SpatialExperiment} object.}
22
+\item{x}{A numeric \code{matrix} of counts where genes are rows and cells are columns.
23
+
24
+Alternatively, a \linkS4class{SpatialExperiment} object.}
20 25
 
21 26
 \item{de_results}{\code{data.frame} resulting from \code{\link[=run]{run()}} or \code{\link[=spatialDE]{spatialDE()}}.}
22 27
 
23 28
 \item{...}{For the generic, arguments to pass to specific methods.}
24 29
 
25
-\item{assay_type}{A \code{character} string specifying the assay from \code{x} to use
26
-as input. Defaults to \code{"counts"}.}
30
+\item{coordinates}{A \code{data.frame} with sample coordinates. Each row is a
31
+sample, the columns with coordinates should be named 'x' and 'y'.
32
+
33
+For the \emph{SpatialExperiment} method, coordinates are taken from
34
+\code{spatialCoords(x)}.}
27 35
 
28 36
 \item{qval_thresh}{\code{numeric} scalar, specifying the q-value significance
29 37
 threshold to filter \code{de_results}. Only rows in \code{de_results} with
... ...
@@ -31,6 +39,9 @@ threshold to filter \code{de_results}. Only rows in \code{de_results} with
31 39
 
32 40
 \item{verbose}{A \code{logical} controlling the display of a progress bar from the
33 41
 Python package.}
42
+
43
+\item{assay_type}{A \code{character} string specifying the assay from \code{x} to use
44
+as input. Defaults to \code{"counts"}.}
34 45
 }
35 46
 \value{
36 47
 \code{data.frame} of model_search results.
... ...
@@ -47,12 +58,11 @@ spe <- mockSVG(size = 10, tot_genes = 200, de_genes = 20, return_SPE = TRUE)
47 58
 ## Run spatialDE with S4 integration
48 59
 de_results <- spatialDE(spe)
49 60
 
50
-## Run model search with S4 integration
61
+## Run model search
51 62
 model_search <- modelSearch(spe, de_results = de_results,
52 63
     qval_thresh = NULL, verbose = FALSE
53 64
 )
54 65
 
55
-
56 66
 }
57 67
 \references{
58 68
 Svensson, V., Teichmann, S. & Stegle, O. SpatialDE: identification of
... ...
@@ -2,30 +2,46 @@
2 2
 % Please edit documentation in R/aeh.R
3 3
 \name{spatialPatterns}
4 4
 \alias{spatialPatterns}
5
+\alias{spatialPatterns,matrix-method}
5 6
 \alias{spatialPatterns,SpatialExperiment-method}
6 7
 \title{Automatic expression histology in \strong{SpatialDE}}
7 8
 \usage{
8 9
 spatialPatterns(x, de_results, ...)
9 10
 
11
+\S4method{spatialPatterns}{matrix}(
12
+  x,
13
+  de_results,
14
+  coordinates,
15
+  qval_thresh = 0.05,
16
+  n_patterns,
17
+  length,
18
+  verbose = FALSE
19
+)
20
+
10 21
 \S4method{spatialPatterns}{SpatialExperiment}(
11 22
   x,
12 23
   de_results,
13
-  assay_type = "counts",
14 24
   qval_thresh = 0.05,
15 25
   n_patterns,
16 26
   length,
27
+  assay_type = "counts",
17 28
   verbose = FALSE
18 29
 )
19 30
 }
20 31
 \arguments{
21
-\item{x}{\linkS4class{SpatialExperiment} object.}
32
+\item{x}{A numeric \code{matrix} of counts where genes are rows and cells are columns.
33
+
34
+Alternatively, a \linkS4class{SpatialExperiment} object.}
22 35
 
23 36
 \item{de_results}{\code{data.frame} resulting from \code{\link[=run]{run()}} or \code{\link[=spatialDE]{spatialDE()}}.}
24 37
 
25 38
 \item{...}{For the generic, arguments to pass to specific methods.}
26 39
 
27
-\item{assay_type}{A \code{character} string specifying the assay from \code{x} to use
28
-as input. Defaults to \code{"counts"}.}
40
+\item{coordinates}{A \code{data.frame} with sample coordinates. Each row is a
41
+sample, the columns with coordinates should be named 'x' and 'y'.
42
+
43
+For the \emph{SpatialExperiment} method, coordinates are taken from
44
+\code{spatialCoords(x)}.}
29 45
 
30 46
 \item{qval_thresh}{\code{numeric} scalar, specifying the q-value significance
31 47
 threshold to filter \code{de_results}. Only rows in \code{de_results} with
... ...
@@ -37,6 +53,9 @@ threshold to filter \code{de_results}. Only rows in \code{de_results} with
37 53
 
38 54
 \item{verbose}{A \code{logical} controlling the display of a progress bar from the
39 55
 Python package.}
56
+
57
+\item{assay_type}{A \code{character} string specifying the assay from \code{x} to use
58
+as input. Defaults to \code{"counts"}.}
40 59
 }
41 60
 \value{
42 61
 A \code{list} of two \code{data.frame}s (pattern_results, patterns):