-
-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathpo.R
More file actions
121 lines (109 loc) · 4.05 KB
/
Copy pathpo.R
File metadata and controls
121 lines (109 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#' @title Shorthand PipeOp Constructor
#'
#' @description
#' Create
#' - a `PipeOp` from `mlr_pipeops` from given ID
#' - a `PipeOpLearner` from a `Learner` object
#' - a `PipeOpFilter` from a `Filter` object
#' - a `PipeOpSelect` from a `Selector` object
#' - a clone of a `PipeOp` from a given `PipeOp` (possibly with changed settings)
#'
#' The object is initialized with given parameters and `param_vals`.
#'
#' `po()` taks a single `obj` (`PipeOp` id, [`Learner`][mlr3::Learner], ...) and converts
#' it to a [`PipeOp`]. `pos()` (with plural-s) takes either a `character`-vector, or a
#' list of objects, and creates an unnamed `list` of [`PipeOp`]s.
#'
#' @param .obj `[any]`\cr
#' The object from which to construct a `PipeOp`. If this is a
#' `character(1)`, it is looked up in the [`mlr_pipeops`] dictionary.
#' Otherwise, it is converted to a [`PipeOp`].
#' @param .objs `character` | `list`\cr
#' Either a `character` of [`PipeOp`]s to look up in [`mlr_pipeops`],
#' or a list of other objects to be converted to a [`PipeOp`].
#' If this is a named `character` or `list`, then the names are used as `$id` slot for the resulting
#' [`PipeOp`]s.
#' @param ... `any`\cr
#' Additional parameters to give to constructed object.
#' This may be an argument of the constructor of the
#' `PipeOp`, in which case it is given to this constructor;
#' or it may be a parameter value, in which case it is
#' given to the `param_vals` argument of the constructor.
#' @return A [`PipeOp`] (for `po()`), or an unnamed `list` of [`PipeOp`]s (for `pos()`).
#' @export
#' @examplesIf requireNamespace("rpart")
#' library("mlr3")
#'
#' po("learner", lrn("classif.rpart"), cp = 0.3)
#'
#' po(lrn("classif.rpart"), cp = 0.3)
#'
#' # is equivalent with:
#' mlr_pipeops$get("learner", lrn("classif.rpart"),
#' param_vals = list(cp = 0.3))
#'
#' mlr3pipelines::pos(c("pca", original = "nop"))
# mlr3pipelines::pos instead of just pos() because of https://github.com/mlr-org/mlr3pipelines/issues/751
po = function(.obj, ...) {
UseMethod("po")
}
#' @rdname po
#' @export
pos = function(.objs, ...) {
UseMethod("pos")
}
#' @export
po.NULL = function(.obj, ...) {
# class is NULL if .obj is missing
dictionary_sugar_get(dict = mlr_pipeops)
}
#' @export
po.PipeOp = function(.obj, ...) {
.obj = .obj$clone(deep = TRUE)
changing = list(...)
if (length(changing)) assert_names(names(changing), type = "unique", .var.name = "additional arguments given to po() with PipeOp-type argument")
params = .obj$param_set$ids()
setting_params = names(changing) %in% params
.obj$param_set$values = insert_named(.obj$param_set$values, changing[setting_params])
changing = changing[!setting_params]
fields = discard(names(.obj), function(n) bindingIsLocked(n, .obj) || bindingIsActive(n, .obj))
for (n in names(changing)) {
if (!exists(n, envir = .obj, inherits = FALSE)) {
stopf("Cannot set argument '%s' for '%s' (not a parameter and not a field).%s",
n, .obj$id, did_you_mean(n, c(params, fields)))
}
.obj[[n]] = changing[[n]]
}
.obj
}
#' @export
po.character = function(.obj, ...) {
dictionary_sugar_inc_get(dict = mlr_pipeops, .key = .obj, ..., .dicts_suggest = list("ppl()" = mlr_graphs))
}
#' @export
po.Learner = function(.obj, ...) {
# we use po() because that makes it possible to set hyperpars via `...`
po(.obj = "learner", learner = .obj, ...)
}
#' @export
po.Filter = function(.obj, ...) {
# we use po() because that makes it possible to set hyperpars via `...`
po(.obj = "filter", filter = .obj, ...)
}
#' @export
po.Selector = function(.obj, ...) {
po(.obj = "select", selector = .obj, ...)
}
#' @export
pos.NULL = function(.objs, ...) {
# class is NULL if .obj is missing
dictionary_sugar_mget(dict = mlr_pipeops)
}
#' @export
pos.character = function(.objs, ...) {
unname(dictionary_sugar_inc_mget(dict = mlr_pipeops, .keys = .objs, ..., .dicts_suggest = list("ppls()" = mlr_graphs)))
}
#' @export
pos.list = function(.objs, ...) {
unname(imap(.x = .objs, .f = function(x, n) if (is.character(n) && n != "") po(x, id = n, ...) else po(x, ...)))
}