Browse code

add DFA

Gavin Rhys Lloyd authored on 12/03/2020 15:12:43
Showing 7 changed files

... ...
@@ -1,6 +1,7 @@
1 1
 # Generated by roxygen2: do not edit by hand
2 2
 
3 3
 export(ANOVA)
4
+export(DFA)
4 5
 export(DatasetExperiment_boxplot)
5 6
 export(DatasetExperiment_dist)
6 7
 export(DatasetExperiment_factor_barchart)
... ...
@@ -25,6 +26,7 @@ export(confounders_lsq_barchart)
25 26
 export(confounders_lsq_boxplot)
26 27
 export(constant_sum_norm)
27 28
 export(corr_coef)
29
+export(dfa_scores_plot)
28 30
 export(dratio_filter)
29 31
 export(feature_boxplot)
30 32
 export(feature_profile)
31 33
new file mode 100644
... ...
@@ -0,0 +1,367 @@
1
+#' Discriminant Factor Analysis (DFA)
2
+#'
3
+#' Applies Dicriminant Factor Analysis to a dataset.
4
+#' @param factor_name The sample_meta column name containing group labels
5
+#' @param number_factors The number of discriminant factors to calculate
6
+#' @param ... additional slots and values passed to struct_class
7
+#' @return struct object
8
+#' @export DFA
9
+#' @include entity_objects.R
10
+#' @examples
11
+#' D = iris_DatasetExperiment()
12
+#' M = DFA(factor_name='Species')
13
+#' M = model_apply(M,D)
14
+DFA = function(factor_name,...) {
15
+    out=struct::new_struct('DFA',
16
+        factor_name=factor_name,
17
+        ...)
18
+    return(out)
19
+}
20
+
21
+
22
+.DFA<-setClass(
23
+    "DFA",
24
+    contains = c('model'),
25
+    slots=c(
26
+        factor_name='entity',
27
+        scores='DatasetExperiment',
28
+        loadings='data.frame',
29
+        eigenvalues='data.frame',
30
+        that='DatasetExperiment'
31
+    ),
32
+
33
+    prototype=list(name = 'Discriminant Factor Analysis',
34
+        description = 'Applies DFA to a data matrix.',
35
+        type = 'classification',
36
+        predicted = 'that',
37
+        .params=c('factor_name'),
38
+        .outputs=c('scores','loadings','eigenvalues','that'),
39
+
40
+        factor_name=ents$factor_name
41
+        
42
+    )
43
+)
44
+
45
+#' @export
46
+#' @template model_train
47
+setMethod(f="model_train",
48
+    signature=c("DFA","DatasetExperiment"),
49
+    definition=function(M,D) {
50
+        
51
+        # column means
52
+        cm = as.matrix(colMeans(D$data))
53
+        
54
+        # factors
55
+        fn = levels(D$sample_meta[[M$factor_name]])
56
+        
57
+        # within covariance
58
+        Sw=matrix(0,nrow=ncol(D$data),ncol=ncol(D$data))
59
+        # between covariance
60
+        Sb=Sw
61
+        nk=matrix(0,nrow=length(fn),ncol=1)
62
+        for (k in 1:length(fn)) {
63
+            # samples in this class
64
+            IN=D$sample_meta[[M$factor_name]]==fn[k] 
65
+            # number in each class
66
+            nk[k]=sum(IN) 
67
+            # covariance for this class
68
+            w=(nk[k]-1)*cov(D$data[IN,])
69
+            # within covariance 
70
+            Sw=Sw+w
71
+            # between covariance
72
+            m = as.matrix(colMeans(D$data[IN,])) # group mean
73
+            b = nk[k]*(m - cm) %*% t(m - cm)
74
+            Sb = Sb+b
75
+        }
76
+        # scale
77
+        Sw=Sw/(nrow(D$data)-length(fn))
78
+        Sb=Sb/(length(fn)-1)
79
+        
80
+        # fisher discriminant
81
+        P = solve(Sw) %*% Sb
82
+        
83
+        # projection
84
+        ev = eigen(P)
85
+        scores = as.matrix(D$data) %*% ev$vectors
86
+        
87
+        ## store outputs
88
+        #scores
89
+        scores=as.data.frame(scores)
90
+        colnames(scores)=as.character(interaction('DF',1:ncol(scores),sep=''))
91
+        rownames(scores)=rownames(D$data)
92
+        VM=data.frame('DFA'=colnames(scores))
93
+        rownames(VM)=VM$DFA
94
+        M$scores=DatasetExperiment(data=scores,sample_meta=D$sample_meta,variable_meta=VM)
95
+        
96
+        # loadings
97
+        loadings=as.data.frame(ev$vectors)
98
+        colnames(loadings)=colnames(scores)
99
+        rownames(loadings)=colnames(D$data)
100
+        M$loadings=loadings
101
+        
102
+        # eigenvalues
103
+        M$eigenvalues=data.frame('eigenvalue'=ev$values,row.names = colnames(scores))
104
+        
105
+        return(M)
106
+    }
107
+)
108
+
109
+#' @export
110
+#' @template model_predict
111
+setMethod(f="model_predict",
112
+    signature=c("DFA","DatasetExperiment"),
113
+    definition=function(M,D) {
114
+
115
+        X=as.matrix(D$data)
116
+        P=output_value(M,'loadings')
117
+        that=X%*%as.matrix(P)
118
+        
119
+        that=as.data.frame(that)
120
+        rownames(that)=rownames(X)
121
+        varnames=colnames(M$loadings)
122
+        colnames(that)=varnames
123
+        
124
+        # convert to DatasetExperiment for preprocessing output
125
+        S=DatasetExperiment(data=that,sample_meta=D$sample_meta,variable_meta=varnames)
126
+        M$that=S
127
+        
128
+        return(M)
129
+    }
130
+)
131
+
132
+
133
+#' dfa_scores_plot class
134
+#'
135
+#' 2d scatter plot of discriminant factor scores.
136
+#'
137
+#' @import struct
138
+#' @param components The discriminant factors to plot (\code{numeric(2)})
139
+#' @param points_to_label "none", "all", or "outliers" will be labelled on the plot.
140
+#' @param factor_name The sample_meta column name to use for colouring the points.
141
+#' You can provide up to two factors for this plot.
142
+#' @param ellipse "all" will plot all ellipses, "group" will only plot group ellipses,
143
+#' "none" will not plot any ellipses and "sample" will plot ellipse for all samples (ignoring group).
144
+#' @param label_filter Only include labels for samples in the group specified by label_filter.
145
+#' If zero length then all labels will be included.
146
+#' @param label_factor The sample_meta column to use for labelling the samples.
147
+#' If 'rownames' then the rownames will be used.
148
+#' @param label_size The text size of the labels.NB ggplot units, not font size units.
149
+#' Default 3.88.
150
+#' @param ... additional slots and values passed to struct_class
151
+#' @return struct object
152
+#' @export dfa_scores_plot
153
+#' @include DFA_class.R
154
+#' @examples
155
+#' D = iris_DatasetExperiment()
156
+#' M = mean_centre() + DFA(factor_name='Species')
157
+#' M = model_apply(M,D)
158
+#' C = dfa_scores_plot(factor_name = 'Species')
159
+#' chart_plot(C,M[2])
160
+#'
161
+dfa_scores_plot = function(
162
+    components=c(1,2),
163
+    points_to_label='none',
164
+    factor_name,
165
+    ellipse='all',
166
+    label_filter=character(0),
167
+    label_factor='rownames',
168
+    label_size=3.88,
169
+    ...) {
170
+    out=struct::new_struct('dfa_scores_plot',
171
+        components=components,
172
+        points_to_label=points_to_label,
173
+        factor_name=factor_name,
174
+        ellipse=ellipse,
175
+        label_filter=label_filter,
176
+        label_factor=label_factor,
177
+        label_size=label_size,
178
+        ...)
179
+    return(out)
180
+}
181
+
182
+
183
+.dfa_scores_plot<-setClass(
184
+    "dfa_scores_plot",
185
+    contains='chart',
186
+    slots=c(
187
+        # INPUTS
188
+        components='entity',
189
+        points_to_label='enum',
190
+        factor_name='entity',
191
+        ellipse='enum',
192
+        label_filter='entity',
193
+        label_factor='entity',
194
+        label_size='entity'
195
+    ),
196
+    
197
+    prototype = list(name='DFA scores plot',
198
+        description='Plots a 2d scatter plot of the selected components',
199
+        type="scatter",
200
+        .params=c('components','points_to_label','factor_name','ellipse','label_filter','label_factor','label_size'),
201
+        
202
+        components=entity(name='Components to plot',
203
+            value=c(1,2),
204
+            type='numeric',
205
+            description='the components to be plotted e.g. c(1,2) plots component 1 on the x axis and component 2 on the y axis.',
206
+            max_length=2
207
+        ),
208
+        
209
+        points_to_label=enum(name='points_to_label',
210
+            value='none',
211
+            type='character',
212
+            description='("none"), "all", or "outliers" will be labelled on the plot.',
213
+            allowed=c('none','all','outliers')
214
+        ),
215
+        factor_name=entity(name='Factor name',
216
+            value='factor',
217
+            type='character',
218
+            description='The column name of sample meta to use for plotting. A second column can be included to plot using symbols.',
219
+            max_length=2
220
+        ),
221
+        ellipse=enum(name = 'Plot ellipses',description=c(
222
+            '"all" will plot all ellipses',
223
+            '"group" will only plot group ellipses',
224
+            '"none" will not plot any ellipses',
225
+            '"sample" will plot ellipse for all samples (ignoring group)'),
226
+            allowed=c('all','group','none','sample'),
227
+            value='all'),
228
+        label_filter=entity(name='Label filter',
229
+            value=character(0),
230
+            type='character',
231
+            description='Only include the param.group labels included in label_filter. If zero length then all labels will be included.'
232
+        ),
233
+        label_factor=entity(name='Factor for labels',
234
+            description='The column name of sample_meta to use as labels. "rownames" will use the row names from sample_meta.',
235
+            type='character',
236
+            value='rownames'),
237
+        label_size=entity(name='Text size of labels',
238
+            description='The text size of labels. Note this is not in Font Units. Default 3.88.',
239
+            type='numeric',
240
+            value=3.88)
241
+    )
242
+)
243
+
244
+
245
+
246
+#' @importFrom sp point.in.polygon
247
+#' @import ggplot2
248
+#' @importFrom scales squish
249
+#' @param ... additional slots and values passed to struct_class
250
+#' @export
251
+#' @template chart_plot
252
+setMethod(f="chart_plot",
253
+    signature=c("dfa_scores_plot",'DFA'),
254
+    definition=function(obj,dobj)
255
+    {
256
+        
257
+        if (obj$points_to_label=='outliers' & !(obj$ellipse %in% c('all','sample'))) {
258
+            warning('Outliers are only labelled when plotting the sample ellipse')
259
+        }
260
+        opt=param_list(obj)
261
+        scores=output_value(dobj,'scores')$data
262
+
263
+        if (length(obj$factor_name)==1) {
264
+            shapes = 19 # filled circles for all samples
265
+        } else {
266
+            shapes = factor(dobj$scores$sample_meta[[obj$factor_name[2]]])
267
+        }
268
+        
269
+        if (obj$label_factor=='rownames') {
270
+            slabels = rownames(dobj$scores$sample_meta)
271
+        } else {
272
+            slabels = dobj$scores$sample_meta[[obj$label_factor]]
273
+        }
274
+        opt$factor_name=opt$factor_name[[1]] # only use the first factor from now on
275
+        
276
+        x=scores[,opt$components[1]]
277
+        y=scores[,opt$components[2]]
278
+        xlabel=paste("DF",opt$components[[1]],')',sep='')
279
+        ylabel=paste("DF",opt$components[[2]],')',sep='')
280
+        
281
+        # get the factor from meta data
282
+        opt$groups=dobj$scores$sample_meta[[opt$factor_name]]
283
+        
284
+        # add a space to the front of the labels to offset them from the points, because nudge_x is in data units
285
+        for (i in 1:length(slabels)) {
286
+            slabels[i]=paste0('  ',slabels[i], '  ')
287
+        }
288
+        
289
+        # filter by label_filter list if provided
290
+        if (length(obj$label_filter)>0) {
291
+            out=!(as.character(opt$groups) %in% obj$label_filter)
292
+            slabels[out]=''
293
+        }
294
+        
295
+        if (is(opt$groups,'factor') | is(opt$groups,'character')) {
296
+            plotClass= createClassAndColors(opt$groups)
297
+            opt$groups=plotClass$class
298
+        }
299
+        
300
+        # build the plot
301
+        A <- data.frame (group=opt$groups,x=x, y=y)
302
+        
303
+        if (length(obj$factor_name)==2) {
304
+            out=ggplot (data=A, aes_(x=~x,y=~y,colour=~group,label=~slabels,shape=~shapes))
305
+        }   else {
306
+            out=ggplot (data=A, aes_(x=~x,y=~y,colour=~group,label=~slabels))
307
+        }
308
+        out=out+
309
+            
310
+            geom_point(na.rm=TRUE) +
311
+            xlab(xlabel) +
312
+            ylab(ylabel) +
313
+            ggtitle('PCA Scores', subtitle=NULL)
314
+        
315
+        if (length(obj$factor_name)==2) {
316
+            out=out+labs(shape=obj$factor_name[[2]],colour=obj$factor_name[[1]])
317
+        } else {
318
+            out=out+labs(shape=obj$factor_name[[1]])
319
+        }
320
+        
321
+        if (obj$ellipse %in% c('all','group')) {
322
+            out = out +stat_ellipse(type='norm') # ellipse for individual groups
323
+        }
324
+        
325
+        if (is(opt$groups,'factor')) { # if a factor then plot by group using the colours from pmp package
326
+            out=out+scale_colour_manual(values=plotClass$manual_colors,name=opt$factor_name)
327
+        }
328
+        else {# assume continuous and use the default colour gradient
329
+            out=out+scale_colour_viridis_c(limits=quantile(opt$groups,c(0.05,0.95),na.rm = TRUE),oob=squish,name=opt$factor_name)
330
+        }
331
+        out=out+theme_Publication(base_size = 12)
332
+        # add ellipse for all samples (ignoring group)
333
+        if (obj$ellipse %in% c('all','sample')) {
334
+            out=out+stat_ellipse(type='norm',mapping=aes(x=x,y=y),colour="#C0C0C0",linetype='dashed',data=A)
335
+        }
336
+        
337
+        if (obj$ellipse %in% c('all','sample')) { # only do this if we plotted the sample ellipse
338
+            # identify samples outside the ellipse
339
+            build=ggplot_build(out)$data
340
+            points=build[[1]]
341
+            ell=build[[length(build)]]
342
+            # outlier for DatasetExperiment ellipse
343
+            points$in.ell=as.logical(sp::point.in.polygon(points$x,points$y,ell$x,ell$y))
344
+            
345
+            # label outliers if
346
+            if (opt$points_to_label=='outliers')
347
+            {
348
+                if (!all(points$in.ell))
349
+                {
350
+                    temp=subset(points,!points$in.ell)
351
+                    temp$group=opt$groups[!points$in.ell]
352
+                    out=out+geom_text(data=temp,aes_(x=~x,y=~y,label=~label,colour=~group),size=obj$label_size,vjust="inward",hjust="inward")
353
+                    
354
+                }
355
+            }
356
+            # add a list of outliers to the plot object
357
+            out$outliers=trimws(slabels[!points$in.ell])
358
+        }
359
+        
360
+        # label all points if requested
361
+        if (opt$points_to_label=='all') {
362
+            out=out+geom_text(vjust="inward",hjust="inward")
363
+        }
364
+        
365
+        return(out)
366
+    }
367
+)
0 368
new file mode 100644
... ...
@@ -0,0 +1,26 @@
1
+% Generated by roxygen2: do not edit by hand
2
+% Please edit documentation in R/DFA_class.R
3
+\name{DFA}
4
+\alias{DFA}
5
+\title{Discriminant Factor Analysis (DFA)}
6
+\usage{
7
+DFA(factor_name, ...)
8
+}
9
+\arguments{
10
+\item{factor_name}{The sample_meta column name containing group labels}
11
+
12
+\item{...}{additional slots and values passed to struct_class}
13
+
14
+\item{number_factors}{The number of discriminant factors to calculate}
15
+}
16
+\value{
17
+struct object
18
+}
19
+\description{
20
+Applies Dicriminant Factor Analysis to a dataset.
21
+}
22
+\examples{
23
+D = iris_DatasetExperiment()
24
+M = DFA(factor_name='Species')
25
+M = model_apply(M,D)
26
+}
... ...
@@ -1,15 +1,16 @@
1 1
 % Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/PCA_plotfcns.R, R/PLSDA_charts.R,
3
-%   R/PLSR_class.R, R/blank_filter_class.R, R/confounders_clsq_class.R,
4
-%   R/dataset_chart_classes.R, R/factor_barchart_class.R,
5
-%   R/feature_profile_class.R, R/fold_change_class.R,
6
-%   R/forward_selection_by_rank_class.R, R/glog_class.R,
7
-%   R/grid_search_1d_class.R, R/hca_class.R, R/kfold_xval_charts.R,
8
-%   R/kw_rank_sum_class.R, R/mv_feature_filter_class.R,
2
+% Please edit documentation in R/DFA_class.R, R/PCA_plotfcns.R,
3
+%   R/PLSDA_charts.R, R/PLSR_class.R, R/blank_filter_class.R,
4
+%   R/confounders_clsq_class.R, R/dataset_chart_classes.R,
5
+%   R/factor_barchart_class.R, R/feature_profile_class.R,
6
+%   R/fold_change_class.R, R/forward_selection_by_rank_class.R,
7
+%   R/glog_class.R, R/grid_search_1d_class.R, R/hca_class.R,
8
+%   R/kfold_xval_charts.R, R/kw_rank_sum_class.R, R/mv_feature_filter_class.R,
9 9
 %   R/mv_sample_filter_class.R, R/permutation_test_class.R,
10 10
 %   R/pqn_norm_method_class.R, R/rsd_filter.R, R/svm_classifier_class.R,
11 11
 %   R/tSNE_class.R, R/wilcox_test_class.R
12
-\name{chart_plot,pca_correlation_plot,PCA-method}
12
+\name{chart_plot,dfa_scores_plot,DFA-method}
13
+\alias{chart_plot,dfa_scores_plot,DFA-method}
13 14
 \alias{chart_plot,pca_correlation_plot,PCA-method}
14 15
 \alias{chart_plot,pca_scores_plot,PCA-method}
15 16
 \alias{chart_plot,pca_biplot_plot,PCA-method}
... ...
@@ -51,6 +52,8 @@
51 52
 \alias{chart_plot,wilcox_p_hist,wilcox_test-method}
52 53
 \title{chart_plot}
53 54
 \usage{
55
+\S4method{chart_plot}{dfa_scores_plot,DFA}(obj, dobj)
56
+
54 57
 \S4method{chart_plot}{pca_correlation_plot,PCA}(obj, dobj)
55 58
 
56 59
 \S4method{chart_plot}{pca_scores_plot,PCA}(obj, dobj)
57 60
new file mode 100644
... ...
@@ -0,0 +1,53 @@
1
+% Generated by roxygen2: do not edit by hand
2
+% Please edit documentation in R/DFA_class.R
3
+\name{dfa_scores_plot}
4
+\alias{dfa_scores_plot}
5
+\title{dfa_scores_plot class}
6
+\usage{
7
+dfa_scores_plot(
8
+  components = c(1, 2),
9
+  points_to_label = "none",
10
+  factor_name,
11
+  ellipse = "all",
12
+  label_filter = character(0),
13
+  label_factor = "rownames",
14
+  label_size = 3.88,
15
+  ...
16
+)
17
+}
18
+\arguments{
19
+\item{components}{The discriminant factors to plot (\code{numeric(2)})}
20
+
21
+\item{points_to_label}{"none", "all", or "outliers" will be labelled on the plot.}
22
+
23
+\item{factor_name}{The sample_meta column name to use for colouring the points.
24
+You can provide up to two factors for this plot.}
25
+
26
+\item{ellipse}{"all" will plot all ellipses, "group" will only plot group ellipses,
27
+"none" will not plot any ellipses and "sample" will plot ellipse for all samples (ignoring group).}
28
+
29
+\item{label_filter}{Only include labels for samples in the group specified by label_filter.
30
+If zero length then all labels will be included.}
31
+
32
+\item{label_factor}{The sample_meta column to use for labelling the samples.
33
+If 'rownames' then the rownames will be used.}
34
+
35
+\item{label_size}{The text size of the labels.NB ggplot units, not font size units.
36
+Default 3.88.}
37
+
38
+\item{...}{additional slots and values passed to struct_class}
39
+}
40
+\value{
41
+struct object
42
+}
43
+\description{
44
+2d scatter plot of discriminant factor scores.
45
+}
46
+\examples{
47
+D = iris_DatasetExperiment()
48
+M = mean_centre() + DFA(factor_name='Species')
49
+M = model_apply(M,D)
50
+C = dfa_scores_plot(factor_name = 'Species')
51
+chart_plot(C,M[2])
52
+
53
+}
... ...
@@ -1,12 +1,14 @@
1 1
 % Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/PCA_class.R, R/PLSDA_class.R, R/PLSR_class.R,
3
-%   R/autoscale_class.R, R/blank_filter_class.R, R/constant_sum_norm_class.R,
4
-%   R/d_ratio_filter_class.R, R/filter_by_name_class.R, R/filter_na_count.R,
5
-%   R/filter_smeta_class.R, R/glog_class.R, R/linear_model_class.R,
6
-%   R/mean_centre_class.R, R/model_predict_doc.R, R/mv_feature_filter_class.R,
2
+% Please edit documentation in R/DFA_class.R, R/PCA_class.R, R/PLSDA_class.R,
3
+%   R/PLSR_class.R, R/autoscale_class.R, R/blank_filter_class.R,
4
+%   R/constant_sum_norm_class.R, R/d_ratio_filter_class.R,
5
+%   R/filter_by_name_class.R, R/filter_na_count.R, R/filter_smeta_class.R,
6
+%   R/glog_class.R, R/linear_model_class.R, R/mean_centre_class.R,
7
+%   R/model_predict_doc.R, R/mv_feature_filter_class.R,
7 8
 %   R/mv_sample_filter_class.R, R/paretoscale_class.R, R/svm_classifier_class.R,
8 9
 %   R/vec_norm_class.R
9
-\name{model_predict,PCA,DatasetExperiment-method}
10
+\name{model_predict,DFA,DatasetExperiment-method}
11
+\alias{model_predict,DFA,DatasetExperiment-method}
10 12
 \alias{model_predict,PCA,DatasetExperiment-method}
11 13
 \alias{model_predict,PLSDA,DatasetExperiment-method}
12 14
 \alias{model_predict,PLSR,DatasetExperiment-method}
... ...
@@ -28,6 +30,8 @@
28 30
 \alias{model_predict,vec_norm,DatasetExperiment-method}
29 31
 \title{Model prediction}
30 32
 \usage{
33
+\S4method{model_predict}{DFA,DatasetExperiment}(M, D)
34
+
31 35
 \S4method{model_predict}{PCA,DatasetExperiment}(M, D)
32 36
 
33 37
 \S4method{model_predict}{PLSDA,DatasetExperiment}(M, D)
... ...
@@ -1,12 +1,14 @@
1 1
 % Generated by roxygen2: do not edit by hand
2
-% Please edit documentation in R/PCA_class.R, R/PLSDA_class.R, R/PLSR_class.R,
3
-%   R/autoscale_class.R, R/blank_filter_class.R, R/constant_sum_norm_class.R,
2
+% Please edit documentation in R/DFA_class.R, R/PCA_class.R,
3
+%   R/PLSDA_class.R, R/PLSR_class.R, R/autoscale_class.R,
4
+%   R/blank_filter_class.R, R/constant_sum_norm_class.R,
4 5
 %   R/d_ratio_filter_class.R, R/filter_by_name_class.R, R/filter_na_count.R,
5 6
 %   R/filter_smeta_class.R, R/glog_class.R, R/linear_model_class.R,
6 7
 %   R/mean_centre_class.R, R/model_train_doc.R, R/mv_feature_filter_class.R,
7 8
 %   R/mv_sample_filter_class.R, R/paretoscale_class.R, R/svm_classifier_class.R,
8 9
 %   R/vec_norm_class.R
9
-\name{model_train,PCA,DatasetExperiment-method}
10
+\name{model_train,DFA,DatasetExperiment-method}
11
+\alias{model_train,DFA,DatasetExperiment-method}
10 12
 \alias{model_train,PCA,DatasetExperiment-method}
11 13
 \alias{model_train,PLSDA,DatasetExperiment-method}
12 14
 \alias{model_train,PLSR,DatasetExperiment-method}
... ...
@@ -28,6 +30,8 @@
28 30
 \alias{model_train,vec_norm,DatasetExperiment-method}
29 31
 \title{Train a model}
30 32
 \usage{
33
+\S4method{model_train}{DFA,DatasetExperiment}(M, D)
34
+
31 35
 \S4method{model_train}{PCA,DatasetExperiment}(M, D)
32 36
 
33 37
 \S4method{model_train}{PLSDA,DatasetExperiment}(M, D)