mlr3misc/0000755000176200001440000000000015212172057012005 5ustar liggesusersmlr3misc/tests/0000755000176200001440000000000014455233002013143 5ustar liggesusersmlr3misc/tests/testthat/0000755000176200001440000000000015212172057015007 5ustar liggesusersmlr3misc/tests/testthat/test_is_scalar_na.R0000644000176200001440000000031014455233002020575 0ustar liggesuserstest_that("is_scalar_na", { expect_true(is_scalar_na(NA)) expect_false(is_scalar_na(1)) expect_false(is_scalar_na(iris)) expect_false(is_scalar_na(NULL)) expect_false(is_scalar_na("NA")) }) mlr3misc/tests/testthat/test_reorder_vector.R0000644000176200001440000000213515156722625021227 0ustar liggesuserstest_that("reorder_vector", { x = c(letters[3:1], "a") y = letters res = x[reorder_vector(x, y)] expect_character(res, sorted = TRUE, unique = FALSE, any.missing = FALSE) x = letters[3:1] y = c("a", "b", "a") res = x[reorder_vector(x, y)] expect_character(res, sorted = TRUE, unique = TRUE, any.missing = FALSE) x = c("b", "a", "c", "d") y = letters[1:3] expect_character(x[reorder_vector(x, y)], sorted = TRUE, unique = TRUE, any.missing = FALSE) expect_character(x[reorder_vector(x, y, na_last = TRUE)], unique = TRUE, any.missing = FALSE) expect_character(x[reorder_vector(x, y, na_last = FALSE)], unique = TRUE, any.missing = FALSE) x = factor(letters[3:1], levels = letters[3:1]) y = factor(letters[1:5]) res = x[reorder_vector(x, y)] expect_factor(res, levels = letters[3:1], any.missing = FALSE) expect_equal(as.character(res), letters[1:3]) x = factor(letters[3:1], levels = letters[3:1]) y = factor(letters[1:2]) res = x[reorder_vector(x, y)] expect_factor(res, levels = letters[3:1], any.missing = FALSE) expect_equal(as.character(res), as.character(y)) }) mlr3misc/tests/testthat/test_nin.R0000644000176200001440000000031214455233002016745 0ustar liggesuserstest_that("nin", { expect_true(1 %nin% 2:3) expect_false(1 %nin% 1) expect_false(1 %nin% c(NA, 1)) expect_true(1 %nin% c(NA, 2)) expect_false(NA %nin% c(NA, 1)) expect_true(NA %nin% 1:2) }) mlr3misc/tests/testthat/test_Context.R0000644000176200001440000000124315156722625017626 0ustar liggesuserstest_that("Context", { ContextTest = R6::R6Class( "ContextTest", inherit = Context, public = list( table = NULL, initialize = function(table) { super$initialize(id = "test", label = "Context Test") self$table = table } ), active = list( data = function(rhs) { if (missing(rhs)) { self$table } else { self$table = rhs } } ) ) table = data.table::data.table(x1 = runif(10)) test = ContextTest$new(table) expect_output(print(test), "data") expect_string(test$label, "Context Test") expect_string(test$id, "test") expect_data_table(test$data) }) mlr3misc/tests/testthat/test_modify.R0000644000176200001440000000061514455233002017456 0ustar liggesuserstest_that("modify_if", { x = modify_if(iris, is.factor, as.character) expect_character(x$Species) x = modify_if(as.data.table(iris), is.factor, as.character) expect_character(x$Species) }) test_that("modify_at", { x = modify_at(iris, "Species", as.character) expect_character(x$Species) x = modify_at(as.data.table(iris), "Species", as.character) expect_character(x$Species) }) mlr3misc/tests/testthat/test_seq.R0000644000176200001440000000061314455233002016755 0ustar liggesuserstest_that("seq", { expect_identical(seq_row(iris), seq_len(nrow(iris))) expect_identical(seq_col(iris), seq_len(ncol(iris))) expect_identical(seq_len0(10), 0:9) expect_identical(seq_along0(1:10), 0:9) expect_identical(seq_len0(0), integer(0)) expect_identical(seq_along0(integer(0)), integer(0)) expect_identical(seq_len0(1), 0L) expect_identical(seq_along0(integer(1)), 0L) }) mlr3misc/tests/testthat/test_has_element.R0000644000176200001440000000150015156722625020462 0ustar liggesuserstest_that("has_element", { xs = list() expect_false(has_element(xs, NULL)) expect_false(has_element(xs, NA)) expect_false(has_element(xs, list())) xs = list(1, iris, NULL) expect_true(has_element(xs, NULL)) expect_false(has_element(xs, NA)) expect_false(has_element(xs, list())) expect_true(has_element(xs, iris)) x = iris expect_true(has_element(xs, x)) x[1, 1] = 123 expect_false(has_element(xs, x)) }) test_that("has_element with R6", { Foo = R6Class( "Foo", public = list( bar = 123, initialize = function(b) { self$bar = b } ) ) f1 = Foo$new(1) f2 = Foo$new(2) f3 = Foo$new(3) xs = list(1, f1, f2) expect_true(has_element(xs, 1)) expect_true(has_element(xs, f1)) expect_false(has_element(xs, f1$clone())) expect_false(has_element(xs, f3)) }) mlr3misc/tests/testthat/test_leanify.R0000644000176200001440000000667015170404765017640 0ustar liggesusersmake_classes = function(pe = parent.frame()) { cls_top = R6::R6Class( "test", parent_env = pe, public = list(a = function() 1), private = list(b = function() 2), active = list(c = function() 3) ) cls_bottom = R6::R6Class( "test_sub", parent_env = pe, inherit = cls_top, # nolint next public = list(a = function() super$a() + 1), private = list(b = function() super$b() + 1), active = list(c = function() super$c + 1) ) pe$cls_top = cls_top pe$cls_bottom = cls_bottom list(cls_top = cls_top, cls_bottom = cls_bottom) } test_that("leanificate method", { en = new.env(parent = emptyenv()) clx = make_classes(en) leanificate_method(clx$cls_top, "a", en) expect_equal(as.character(body(clx$cls_top$new()$a)[[1]]), ".__test__a") expect_subset(".__test__a", names(en)) expect_equal(clx$cls_top$new()$a(), 1) leanificate_method(clx$cls_top, "b", en) expect_equal(as.character(body(clx$cls_top$new()$.__enclos_env__$private$b)[[1]]), ".__test__b") expect_subset(".__test__b", names(en)) expect_equal(clx$cls_top$new()$.__enclos_env__$private$b(), 2) leanificate_method(clx$cls_top, "c", en) expect_equal(as.character(body(clx$cls_top$new()$.__enclos_env__$.__active__$c)[[1]]), ".__test__c") expect_subset(".__test__c", names(en)) expect_equal(clx$cls_top$new()$c, 3) leanificate_method(clx$cls_bottom, "a", en) expect_equal(as.character(body(clx$cls_bottom$new()$a)[[1]]), ".__test_sub__a") expect_subset(".__test_sub__a", names(en)) expect_equal(clx$cls_bottom$new()$a(), 2) leanificate_method(clx$cls_bottom, "b", en) expect_equal(as.character(body(clx$cls_bottom$new()$.__enclos_env__$private$b)[[1]]), ".__test_sub__b") expect_subset(".__test_sub__b", names(en)) expect_equal(clx$cls_bottom$new()$.__enclos_env__$private$b(), 3) leanificate_method(clx$cls_bottom, "c", en) expect_equal(as.character(body(clx$cls_bottom$new()$.__enclos_env__$.__active__$c)[[1]]), ".__test_sub__c") expect_subset(".__test_sub__c", names(en)) expect_equal(clx$cls_bottom$new()$c, 4) }) test_that("leanify r6 method", { en = new.env(parent = emptyenv()) clx = make_classes(en) leanify_r6(clx$cls_bottom, en) expect_equal(as.character(body(clx$cls_bottom$new()$a)[[1]]), ".__test_sub__a") expect_subset(".__test_sub__a", names(en)) expect_equal(clx$cls_bottom$new()$a(), 2) expect_equal(as.character(body(clx$cls_bottom$new()$.__enclos_env__$private$b)[[1]]), ".__test_sub__b") expect_subset(".__test_sub__b", names(en)) expect_equal(clx$cls_bottom$new()$.__enclos_env__$private$b(), 3) expect_equal(as.character(body(clx$cls_bottom$new()$.__enclos_env__$.__active__$c)[[1]]), ".__test_sub__c") expect_subset(".__test_sub__c", names(en)) expect_equal(clx$cls_bottom$new()$c, 4) }) test_that("leanify_package", { en = new.env(parent = emptyenv()) clx = make_classes(en) leanify_package(en, function(x) x$classname == "test_sub") expect_equal(as.character(body(clx$cls_top$new()$a)[[1]]), ".__test__a") expect_subset(".__test__a", names(en)) expect_equal(clx$cls_top$new()$a(), 1) expect_equal(as.character(body(clx$cls_top$new()$.__enclos_env__$private$b)[[1]]), ".__test__b") expect_subset(".__test__b", names(en)) expect_equal(clx$cls_top$new()$.__enclos_env__$private$b(), 2) expect_equal(as.character(body(clx$cls_top$new()$.__enclos_env__$.__active__$c)[[1]]), ".__test__c") expect_subset(".__test__c", names(en)) expect_equal(clx$cls_top$new()$c, 3) }) mlr3misc/tests/testthat/test_str_trunc.R0000644000176200001440000000050714455233002020212 0ustar liggesuserstest_that("str_trunc", { expect_equal(str_trunc("abcdefghij", 7), "ab[...]") expect_equal(str_trunc("abcdef", 7), "abcdef") expect_equal(str_trunc("abcdef", 6), "abcdef") expect_equal(str_trunc("abcdef", 5), "[...]") expect_error(str_trunc("abcdef", 2)) expect_equal(str_trunc(NA_character_, 5), NA_character_) }) mlr3misc/tests/testthat/test_count_missing.R0000644000176200001440000000063514455233002021052 0ustar liggesuserstest_that("count_missing", { expect_equal(count_missing(1), 0) expect_equal(count_missing(integer()), 0) expect_equal(count_missing(NA), 1) expect_equal(count_missing(c(1, NA)), 1) expect_equal(count_missing(NA), 1) expect_equal(count_missing(NA_integer_), 1) expect_equal(count_missing(NA_real_), 1) expect_equal(count_missing(NA_complex_), 1) expect_equal(count_missing(NA_character_), 1) }) mlr3misc/tests/testthat/test_chunk.R0000644000176200001440000000351315156722625017314 0ustar liggesuserstest_that("chunk", { x = 1:10 n_chunks = 2 expect_integer( chunk(length(x), n_chunks = n_chunks), len = length(x), lower = 1, upper = n_chunks, any.missing = FALSE ) x = 1:10 n_chunks = 1 expect_integer( chunk(length(x), n_chunks = n_chunks), len = length(x), lower = 1, upper = n_chunks, any.missing = FALSE ) x = 1:10 n_chunks = 10 expect_integer( chunk(length(x), n_chunks = n_chunks), len = length(x), lower = 1, upper = n_chunks, any.missing = FALSE ) x = 1:10 n_chunks = 20 expect_integer( chunk(length(x), n_chunks = n_chunks), len = length(x), lower = 1, upper = n_chunks, any.missing = FALSE ) x = integer(0) n_chunks = 20 expect_integer( chunk(length(x), n_chunks = n_chunks), len = length(x), lower = 1, upper = n_chunks, any.missing = FALSE ) x = 1:10 chunk_size = 3 res = chunk(length(x), chunk_size = chunk_size) expect_integer(res, len = length(x), lower = 1, upper = length(x), any.missing = FALSE) expect_integer(table(res), lower = 1, upper = chunk_size, any.missing = FALSE) x = 1:10 chunk_size = 1 res = chunk(length(x), chunk_size = chunk_size) expect_integer(res, len = length(x), lower = 1, upper = length(x), any.missing = FALSE) expect_integer(table(res), lower = 1, upper = chunk_size, any.missing = FALSE) expect_equal(chunk(0, chunk_size = 1), integer(0)) expect_equal(chunk(0, n_chunks = 1), integer(0)) x = 1:10 n_chunks = 2 res = c(rep(1, 5), rep(2, 5)) expect_equal(chunk(length(x), n_chunks = n_chunks, shuffle = FALSE), res) res = chunk_vector(letters[1:10], n_chunks = 2) expect_list(res, types = "character", len = 2) expect_subset(res[[1]], letters[1:10]) expect_subset(res[[2]], letters[1:10]) expect_character(unlist(res), unique = TRUE) }) mlr3misc/tests/testthat/test_named_vector.R0000644000176200001440000000063414455233002020636 0ustar liggesuserstest_that("named_vector", { expect_equal(named_vector(character()), setNames(vector("logical", 0), nm = character())) expect_equal(named_vector(), setNames(vector("logical", 0), nm = character())) expect_equal(named_vector("a"), c(a = NA)) expect_equal(named_vector(c("a", "b")), c(a = NA, b = NA)) expect_equal(named_vector(c("a", "b"), 1), c(a = 1, b = 1)) expect_error(named_vector("a", iris)) }) mlr3misc/tests/testthat/test_as_short_string.R0000644000176200001440000000363615170404762021415 0ustar liggesuserstest_that("as_short_string", { expect_equal(as_short_string(1L), "1") expect_equal(as_short_string(1.0), "1") expect_equal(as_short_string(1.23), "1.23") expect_equal(as_short_string(numeric(0)), "numeric(0)") expect_equal(as_short_string(factor(NULL)), "factor(0)") expect_equal(as_short_string(iris), "") expect_equal(as_short_string(NULL), "") expect_equal(as_short_string(c(a = 1, b = 2)), "1,2") expect_equal(as_short_string(expression(a + b + 3)), "a + b + 3") expect_equal(as_short_string(list(a = 1, 45)), "a=1, =45") expect_equal(as_short_string(list(a = 1, b = list(x = 3))), "a=1, b=") expect_equal(as_short_string(list(a = 1, b = iris)), "a=1, b=") expect_equal(as_short_string(list()), "list()") expect_equal(as_short_string(list(a = 1)), "a=1") expect_equal(as_short_string(list(a = 1:2)), "a=1,2") # expect_equal(as_short_string(list(a=1:20)), "a=1,2,3,4,5,6,...") expect_equal(as_short_string(list(a = 1, 2, b = 3)), "a=1, =2, b=3") expect_equal(as_short_string(list(a = 1, 2, b = data.frame())), "a=1, =2, b=") expect_equal( as_short_string(list(a = identity, b = new.env(), c = NULL, d = expression(a + b + 3))), "a=, b=, c=, d=a + b + 3" ) expect_equal(as_short_string(list(a = 1, b = 3.2)), "a=1, b=3.2") expect_equal(as_short_string(list(a = 1, b = 3.223), num_format = "%.2f"), "a=1.00, b=3.22") expect_equal(as_short_string(list(a = 1L, b = 3.223), num_format = "%.2f"), "a=1, b=3.22") expect_equal(as_short_string(character(0)), "character(0)") expect_equal(as_short_string(factor("setosa")), "setosa") expect_equal(as_short_string(factor(c("setosa", "versicolor"))), "setosa,versicolor") expect_equal(as_short_string(ordered("low", levels = c("low", "high"))), "low") expect_equal(as_short_string(list(a = 1, b = factor("setosa"))), "a=1, b=setosa") }) mlr3misc/tests/testthat/test_printf.R0000644000176200001440000000156315061011111017461 0ustar liggesuserstest_that("messagef", { expect_message(messagef("xxx%ixxx", 123), "xxx123xxx") }) test_that("catf", { expect_output(catf("xxx%ixxx", 123), "xxx123xxx") }) test_that("catf into file", { fn = tempfile() catf("xxx%ixxx", 123, file = fn) s = readLines(fn) expect_equal(s, "xxx123xxx") file.remove(fn) }) test_that("warningf", { expect_warning(warningf("xxx%ixxx", 123), "xxx123xxx") f = function() warningf("123") # "Warning: " not caught by gives_warning expect_warning(f(), "123") expect_warning(warningf("abc"), "abc") }) test_that("stopf", { expect_error(stopf("xxx%ixxx", 123), "xxx123xxx") f = function() stopf("123") expect_error(f(), "123") expect_error(stopf("abc"), "abc") }) test_that("formatting", { expect_snapshot(stopf("abc"), error = TRUE) expect_snapshot(stopf("s: %s", "b"), error = TRUE) expect_snapshot(warningf("abc")) }) mlr3misc/tests/testthat/test_shuffle.R0000644000176200001440000000023614455233002017622 0ustar liggesuserstest_that("shuffle", { x = shuffle(1:3) expect_true(setequal(x, 1:3)) x = shuffle(10L) expect_identical(x, 10L) expect_error(shuffle(10L, 2L)) }) mlr3misc/tests/testthat/test_check_packages_installed.R0000644000176200001440000000104015156722625023147 0ustar liggesuserstest_that("check_packages_installed", { expect_equal(check_packages_installed("mlr3misc"), setNames(TRUE, "mlr3misc")) expect_warning(check_packages_installed("this_is_not_a_package999"), "required but not installed") expect_warning(check_packages_installed("this_is_not_a_package999", msg = "foobar %s"), "foobar") expect_logical(check_packages_installed("this_is_not_a_package999", warn = FALSE)) expect_true(tryCatch( check_packages_installed("this_is_not_a_package999"), packageNotFoundWarning = function(e) TRUE )) }) mlr3misc/tests/testthat/teardown.R0000644000176200001440000000002214455233002016743 0ustar liggesusersoptions(old_opts) mlr3misc/tests/testthat/test_topo_sort.R0000644000176200001440000000320215156722625020227 0ustar liggesuserstest_that("topo_sort", { # graph: # a nodes = rbindlist( list( list(id = "a", parents = list(character())) ), use.names = TRUE ) r = topo_sort(nodes) rr = data.table(id = "a", depth = 0) expect_equal(r, rr) # graph: # a b nodes = rbindlist( list( list(id = "a", parents = list(character())), list(id = "b", parents = list(character())) ), use.names = TRUE ) r = topo_sort(nodes) rr = data.table( id = c("a", "b"), depth = c(0, 0) ) expect_equal(r, rr) # graph: # c -> b -> a nodes = rbindlist( list( list(id = "a", parents = list("b")), list(id = "b", parents = list("c")), list(id = "c", parents = list(character())) ), use.names = TRUE ) r = topo_sort(nodes) rr = data.table( id = c("c", "b", "a"), depth = c(0, 1, 2) ) expect_equal(r, rr) # graph: # c -> b ---------> e # b -> a ----> e # d -> b nodes = rbindlist( list( list(id = "a", parents = list("b")), list(id = "b", parents = list(c("c", "d"))), list(id = "c", parents = list(character())), list(id = "d", parents = list(character())), list(id = "e", parents = list(c("a", "b"))) ), use.names = TRUE ) r = topo_sort(nodes) rr = data.table( id = c("c", "d", "b", "a", "e"), depth = c(0, 0, 1, 2, 3) ) expect_equal(r, rr) # graph: # a -> b -> c -> a nodes = rbindlist( list( list(id = "a", parents = list("c")), list(id = "b", parents = list("a")), list(id = "c", parents = list("a")) ), use.names = TRUE ) expect_error(topo_sort(nodes), "Cycle") }) mlr3misc/tests/testthat/test_Dictionary.R0000644000176200001440000001111015156722625020301 0ustar liggesuserstest_that("Dictionary", { Foo = R6::R6Class("Foo", public = list(x = 0, id = NULL, initialize = function(x) self$x = x), cloneable = TRUE) d = Dictionary$new() expect_identical(d$keys(), character(0L)) f1 = Foo f2 = Foo expect_false(d$has("f1")) d$add("f1", f1) expect_identical(d$keys(), "f1") expect_true(d$has("f1")) f1c = d$get("f1", x = 1) expect_list(d$mget("f1", x = 1), names = "unique", len = 1, types = "Foo") d$add("f2", f2) expect_set_equal(d$keys(), c("f1", "f2")) expect_list(d$mget(c("f1", "f2"), x = 1), names = "unique", len = 2, types = "Foo") d$remove("f2") expect_set_equal(d$keys(), "f1") expect_false(d$has("f2")) expect_data_table(as.data.table(d), nrows = 1L) }) test_that("Dictionary clones R6", { foo = R6Class("Foo")$new() d = Dictionary$new() d$add("f", foo) expect_false(data.table::address(foo) == data.table::address(d$get("f"))) }) test_that("Dictionary throws exception on unnamed args", { foo = R6Class("Foo", public = list(x = 0)) x = Dictionary$new() x$add("a", foo) x$add("b", foo) expect_error(x$get("a", 1), "names") expect_error(x$mget("a", "b"), "names") }) test_that("dictionary_sugar_get", { Foo = R6::R6Class( "Foo", public = list(x = 0, y = 0, key = 0, initialize = function(y, key = -1) { self$y = y self$key = key }), cloneable = TRUE ) d = Dictionary$new() d$add("f1", Foo) x = dictionary_sugar_get(d, "f1", y = 99, x = 1) expect_equal(x$x, 1) expect_equal(x$y, 99) expect_equal(x$key, -1) x2 = dictionary_sugar_get(d, "f1", 99, x = 1) expect_equal(x, x2) x2 = dictionary_sugar_get(d, "f1", x = 1, 99) expect_equal(x, x2) x = dictionary_sugar_get(d, "f1", 1, 99) expect_equal(x$x, 0) expect_equal(x$y, 1) expect_equal(x$key, 99) x2 = dictionary_sugar_get(d, "f1", key = 99, y = 1) expect_equal(x, x2) }) test_that("mget", { Foo = R6::R6Class( "Foo", public = list(id = "foo", x = 0, y = 0, key = 0, initialize = function(y, key = -1) { self$y = y self$key = key }), cloneable = TRUE ) d = Dictionary$new() d$add("f1", Foo) d$add("f2", Foo) x = dictionary_sugar_mget(d, "f1", y = 99, x = 1) expect_list(x, len = 1, types = "Foo") x = dictionary_sugar_mget(d, c("f1", "f2"), y = 99) expect_list(x, len = 2, types = "Foo") expect_equal(ids(x), c("foo", "foo")) x = dictionary_sugar_mget(d, c(a = "f1", b = "f2"), y = 99) expect_list(x, len = 2, types = "Foo") expect_equal(ids(x), c("a", "b")) }) test_that("incrementing ids works", { d = Dictionary$new() d$add("a", R6Class("A", public = list(id = "a"))) d$add("b", R6Class("B", public = list(id = "c"))) obj1 = dictionary_sugar_inc_get(d, "a_1") expect_r6(obj1, "A") expect_true(obj1$id == "a_1") obj2 = dictionary_sugar_inc_get(d, "b_1") expect_r6(obj2, "B") expect_true(obj2$id == "c_1") objs = dictionary_sugar_inc_mget(d, c("a_10", "b_2")) expect_r6(objs$a_10, "A") expect_true(objs$a_10$id == "a_10") expect_r6(objs$c_2, "B") expect_true(objs$c_2$id == "c_2") objs = dictionary_sugar_inc_mget(d, c("a", "b_1")) expect_identical(ids(objs), c("a", "c_1")) obj = dictionary_sugar_inc_get(d, "a") expect_class(obj, "A") }) test_that("prototype_args works", { A = R6Class("A", public = list(x = NULL, initialize = function(x) self$x = x)) d = Dictionary$new() d$add("a", A, .prototype_args = list(x = 1)) expect_identical(d$prototype_args("a"), list(x = 1)) a = d$get("a", .prototype = TRUE) expect_identical(a$x, 1) expect_identical(d$prototype_args("a"), list(x = 1)) }) test_that("#115", { A = R6Class("A", public = list(x = NULL)) d = Dictionary$new() d$add("a", function() A$new()) expect_error(dictionary_sugar_get(d, "a", y = 10), "Did you mean") }) test_that("similar entries in other dictionaries", { obj = R6Class("A", public = list(x = NULL)) d = Dictionary$new() d$add("abc", obj) d_lookup1 = Dictionary$new() d_lookup1$add("cde", obj) # Makes suggestions expect_error( dictionary_sugar_get(d, "cde", .dicts_suggest = list("lookup1" = d_lookup1)), "Similar entries in other dictionaries" ) # Makes no suggestions expect_error( dictionary_sugar_get(d, "xyz", .dicts_suggest = list("lookup1" = d_lookup1)), "(?!(Similar entries in other dictionaries))", perl = TRUE ) d_lookup2 = Dictionary$new() d_lookup2$add("bcd", obj) # Dictionaries ordered by closest match per dictionary expect_error( dictionary_sugar_get(d, "bcd", .dicts_suggest = list("lookup1" = d_lookup1, "lookup2" = d_lookup2)), "Similar entries in other dictionaries.*lookup2.*lookup1" ) }) mlr3misc/tests/testthat/test_unnest.R0000644000176200001440000000450315147263543017517 0ustar liggesuserstest_that("unnest", { x = data.table(id = 1:2, x = list(list(a = 1L), list(a = 2L, b = 2L))) expect_data_table(x, ncols = 2, nrows = 2) x = unnest(x, "x") expect_data_table(x, ncols = 3, nrows = 2) expect_null(x$x) expect_equal(x$a, 1:2) expect_equal(x$b, c(NA, 2L)) x = data.table(id = 1:2, x = list(list(a = 1L), list(a = 2L, b = 2L))) x = unnest(x, "x", prefix = "par.") expect_data_table(x, ncols = 3, nrows = 2) expect_null(x$x) expect_equal(x$par.a, 1:2) expect_equal(x$par.b, c(NA, 2L)) }) test_that("unnest with empty rows", { x = data.table(id = 1:2, x = list(list(a = 1), list())) col = "x" expect_data_table(x, ncols = 2, nrows = 2) x = unnest(x, "x") expect_data_table(x, ncols = 2, nrows = 2) }) test_that("unnest with nested lists", { x = data.table( id = 1:2, p1 = list(list(mtry = 1L, ctrl = list(eps = 0.1)), list(mtry = 2L, ctrl = list(eps = 0.2))), p2 = list(list(mtry = 1L, aggr = mean), list(mtry = 2L, aggr = median)) ) tab = unnest(copy(x), "p1") expect_data_table(tab, nrows = 2L) expect_names(names(tab), permutation.of = c("id", "p2", "mtry", "ctrl")) expect_integer(tab$mtry, any.missing = FALSE) expect_list(tab$ctrl, any.missing = FALSE) expect_list(tab$p2, any.missing = FALSE) unnest(tab, "ctrl") expect_data_table(tab, nrows = 2L) expect_names(names(tab), permutation.of = c("id", "p2", "mtry", "eps")) expect_double(tab$eps, any.missing = FALSE) tab = unnest(copy(x), "p2") expect_data_table(tab, nrows = 2L) expect_names(names(tab), permutation.of = c("id", "p1", "mtry", "aggr")) expect_integer(tab$mtry, any.missing = FALSE) expect_list(tab$aggr, "function", any.missing = FALSE) }) test_that("unnest with vector-valued elements", { x = data.table(id = 1:2, x = list(list(a = 1, b = c(2, 1)), list(a = 3, b = c(4, 5)))) x = unnest(x, "x") expect_data_table(x, ncols = 3, nrows = 2) expect_null(x$x) expect_equal(x$a, c(1, 3)) expect_list(x$b) expect_equal(x$b[[1L]], c(2, 1)) expect_equal(x$b[[2L]], c(4, 5)) }) test_that("prefix with placeholder", { x = data.table( id = 1:2, p1 = list(list(mtry = 1L, ctrl = list(eps = 0.1)), list(mtry = 2L, ctrl = list(eps = 0.2))), p2 = list(list(mtry = 1L, aggr = mean), list(mtry = 2L, aggr = median)) ) expect_data_table(unnest(x, c("p1", "p2"), prefix = "{col}.")) }) mlr3misc/tests/testthat/test_get_seed.R0000644000176200001440000000013314455233002017741 0ustar liggesuserstest_that("get_seed", { expect_integer(get_seed(), any.missing = FALSE, min.len = 1L) }) mlr3misc/tests/testthat/test_as_factor.R0000644000176200001440000000057614455233002020136 0ustar liggesuserstest_that("as_factor", { x = as_factor(c("a", "b"), c("a", "b")) y = as_factor(c("a", "b"), c("b", "a")) expect_factor(x, levels = c("a", "b")) expect_factor(y, levels = c("b", "a")) expect_equal(levels(x), c("a", "b")) expect_equal(levels(y), c("b", "a")) z = as_factor(x, levels(y)) expect_factor(z, levels = c("a", "b")) expect_equal(levels(z), levels(y)) }) mlr3misc/tests/testthat/test_rcbind.R0000644000176200001440000000066114455233002017431 0ustar liggesuserstest_that("rcbind", { x = data.table(a = 1:3) y = data.table(b = 3:1) x = rcbind(x, y) expect_data_table(x, nrows = 3, ncols = 2, any.missing = FALSE) expect_identical(x$a, 1:3) expect_identical(x$b, 3:1) }) test_that("y as column name in x (#42)", { a = data.table(y = list(0), opt_x = list(list(z_1 = 100, z_2 = 200))) res = unnest(a, "opt_x") expect_equal(res, data.table(y = list(0), z_1 = 100, z_2 = 200)) }) mlr3misc/tests/testthat/test_format_bib.R0000644000176200001440000000027714455233002020277 0ustar liggesuserstest_that("format_bib", { bibentries = list(checkmate = citation("checkmate"), R = citation()) expect_string(format_bib("checkmate", "R")) expect_string(cite_bib("checkmate", "R")) }) mlr3misc/tests/testthat/helper.R0000644000176200001440000000057114455233002016410 0ustar liggesuserslibrary(checkmate) library(R6) expect_man_exists = function(man) { checkmate::expect_string(man, na.ok = TRUE, fixed = "::") if (!is.na(man)) { parts = strsplit(man, "::", fixed = TRUE)[[1L]] matches = help.search(parts[2L], package = parts[1L], ignore.case = FALSE) checkmate::expect_data_frame(matches$matches, min.rows = 1L, info = "man page lookup") } } mlr3misc/tests/testthat/test_to_decimal.R0000644000176200001440000000051614455233002020267 0ustar liggesuserstest_that("to_decimal()", { expect_identical( to_decimal(c(1, 0)), 2L ) expect_identical( to_decimal(c(1, 1)), 3L ) expect_error( to_decimal(c(NA, 1)), "missing" ) expect_equal( to_decimal(logical()), 0L ) expect_error( to_decimal(rep(TRUE, 31)), "for vectors with" ) }) mlr3misc/tests/testthat/test_insert.R0000644000176200001440000000376414635030076017511 0ustar liggesuserstest_that("insert_named.list", { x = named_list(letters[1:3], 1) x = insert_named(x, list(d = 1)) expect_list(x, len = 4L) expect_set_equal(names(x), letters[1:4]) expect_equal(x$d, 1) x = remove_named(x, c("d", "e")) expect_list(x, len = 3L) expect_set_equal(names(x), letters[1:3]) expect_null(x$d) x = insert_named(list(), list(a = 1)) expect_list(x, len = 1L) expect_equal(x$a, 1) x = insert_named(c(a = 1), c(b = 2)) expect_numeric(x, len = 2L) expect_equal(x[["a"]], 1) expect_equal(x[["b"]], 2) x = remove_named(x, "a") expect_numeric(x, len = 1L) expect_equal(x[["b"]], 2) }) test_that("insert_named.environment", { x = list2env(named_list(letters[1:3], 1)) x = insert_named(x, list(d = 1)) expect_environment(x, contains = letters[1:4]) expect_equal(x$d, 1) x = remove_named(x, c("d", "e")) expect_environment(x, contains = letters[1:3]) expect_null(x$d) x = insert_named(new.env(), list(a = 1)) expect_environment(x, contains = "a") expect_equal(x$a, 1) }) test_that("insert_named.data.frame", { x = as.data.frame(named_list(letters[1:3], 1)) x = insert_named(x, list(d = 1)) expect_data_frame(x, nrows = 1L, ncols = 4L) expect_set_equal(names(x), letters[1:4]) expect_equal(x$d, 1) x = remove_named(x, c("d", "e")) expect_data_frame(x, nrows = 1L, ncols = 3L) expect_set_equal(names(x), letters[1:3]) expect_null(x$d) x = insert_named(data.frame(), list(a = 1)) expect_data_frame(x, nrows = 1L, ncols = 1L) expect_equal(x$a, 1) }) test_that("insert_named.data.table", { x = as.data.table(named_list(letters[1:3], 1)) x = insert_named(x, list(d = 1)) expect_data_table(x, nrows = 1L, ncols = 4L) expect_set_equal(names(x), letters[1:4]) expect_equal(x$d, 1) x = remove_named(x, c("d", "e")) expect_data_table(x, nrows = 1L, ncols = 3L) expect_set_equal(names(x), letters[1:3]) expect_null(x$d) x = insert_named(data.table(), list(a = 1)) expect_data_table(x, nrows = 1L, ncols = 1L) expect_equal(x$a, 1) }) mlr3misc/tests/testthat/test_load_data.R0000644000176200001440000000012214455233002020070 0ustar liggesuserstest_that("load_data", { expect_data_frame(load_dataset("iris", "datasets")) }) mlr3misc/tests/testthat/test_formulate.R0000644000176200001440000000133215170404762020172 0ustar liggesuserstest_that("formulate", { f = formulate("Species", c("Sepal.Width", "Petal.Length")) expect_formula(f) expect_null(environment(f)) x = extract_vars(f) expect_set_equal(x$lhs, "Species") expect_set_equal(x$rhs, c("Sepal.Width", "Petal.Length")) }) test_that("formulate_multioutput", { f = formulate(c("Petal.Width", "Petal.Length"), c("Sepal.Width", "Sepal.Length")) expect_formula(f) expect_null(environment(f)) x = extract_vars(f) expect_set_equal(x$lhs, c("Petal.Width", "Petal.Length")) expect_set_equal(x$rhs, c("Sepal.Width", "Sepal.Length")) }) test_that("formulate quotes", { f = formulate("y", "a-b") str = as.character(f) expect_character(str, len = 3) expect_equal(str[3], "`a-b`") }) mlr3misc/tests/testthat/test_warn_deprecated.R0000644000176200001440000000320715156722625021333 0ustar liggesuserstest_that("warn_deprecated warns once", { rm(list = ls(deprecated_warning_given_db), envir = deprecated_warning_given_db) on.exit(rm(list = ls(deprecated_warning_given_db), envir = deprecated_warning_given_db)) expect_warning(warn_deprecated("TestClass$foo()"), "TestClass\\$foo\\(\\) is deprecated") expect_silent(warn_deprecated("TestClass$foo()")) }) test_that("warn_deprecated has correct class", { rm(list = ls(deprecated_warning_given_db), envir = deprecated_warning_given_db) on.exit(rm(list = ls(deprecated_warning_given_db), envir = deprecated_warning_given_db)) w = tryCatch(warn_deprecated("TestClass$bar()"), warning = identity) expect_class(w, "Mlr3WarningDeprecated") }) test_that("warn_deprecated respects option", { rm(list = ls(deprecated_warning_given_db), envir = deprecated_warning_given_db) on.exit(rm(list = ls(deprecated_warning_given_db), envir = deprecated_warning_given_db)) expect_silent(invoke(warn_deprecated, "TestClass$baz()", .opts = list(mlr3.warn_deprecated = FALSE))) }) test_that("deprecated_binding works in R6 class", { rm(list = ls(deprecated_warning_given_db), envir = deprecated_warning_given_db) on.exit(rm(list = ls(deprecated_warning_given_db), envir = deprecated_warning_given_db)) MyClass = R6::R6Class( "MyClass", public = list(), active = list( foo = deprecated_binding("MyClass$foo", "bar") ) ) mco = MyClass$new() expect_warning(val <- mco$foo, "MyClass\\$foo is deprecated") expect_equal(val, "bar") # second access should not warn expect_silent(mco$foo) # write access should error expect_error(mco$foo <- "baz", "MyClass\\$foo read-only") }) mlr3misc/tests/testthat/test_names2.R0000644000176200001440000000045314635030076017362 0ustar liggesuserstest_that("names2", { x = 1:3 expect_identical(names2(x), rep.int(NA_character_, 3)) names(x)[1] = letters[1] expect_identical(names2(x), c("a", rep.int(NA_character_, 2))) expect_identical(names2(x, ""), c("a", rep.int("", 2))) names(x) = letters[1:3] expect_named(x, names2(x)) }) mlr3misc/tests/testthat/test_named_list.R0000644000176200001440000000056114455233002020306 0ustar liggesuserstest_that("named_list", { expect_equal(named_list(character()), setNames(vector("list", 0), nm = character())) expect_equal(named_list(), setNames(vector("list", 0), nm = character())) expect_equal(named_list("a"), list(a = NULL)) expect_equal(named_list(c("a", "b")), list(a = NULL, b = NULL)) expect_equal(named_list(c("a", "b"), 1), list(a = 1, b = 1)) }) mlr3misc/tests/testthat/test_rowwise_table.R0000644000176200001440000000071514455233002021036 0ustar liggesuserstest_that("construction", { x = rowwise_table(~a, ~b, 1, "a", 2, "b") expect_data_table(x, nrows = 2, ncols = 2) expect_names(names(x), identical.to = c("a", "b")) expect_equal(x$a, c(1, 2)) expect_equal(x$b, c("a", "b")) expect_error(rowwise_table(1, 2), "No column names") expect_error(rowwise_table(~a, ~b, 1), "rectangular") x = rowwise_table(~a, ~b, 1, "a", 2, "b", .key = "b") expect_data_table(x, nrows = 2, ncols = 2, key = "b") }) mlr3misc/tests/testthat/test_with_package.R0000644000176200001440000000035715156722625020635 0ustar liggesuserstest_that("with_package", { skip_if_not_installed("callr") before = .packages() expect_number( with_package("callr", { r(function() runif(1)) }), lower = 0, upper = 1 ) expect_equal(before, .packages()) }) mlr3misc/tests/testthat/test_extract_vars.R0000644000176200001440000000043214455233002020671 0ustar liggesuserstest_that("extract_vars", { f = Species ~ Sepal.Width > 1 + Petal.Length x = extract_vars(f) expect_list(x, len = 2L) expect_names(names(x), identical.to = c("lhs", "rhs")) expect_set_equal(x$lhs, "Species") expect_set_equal(x$rhs, c("Sepal.Width", "Petal.Length")) }) mlr3misc/tests/testthat/test_cross_join.R0000644000176200001440000000053214455233002020335 0ustar liggesuserstest_that("cross_join", { tab = cross_join(list(a = 1:3, b = 1:2)) expect_equal(tab, CJ(a = 1:3, b = 1:2)) tab = cross_join(list(sorted = 1:3, b = 1:2)) expect_equal(tab, setnames(CJ(a = 1:3, b = 1:2), "a", "sorted")) tab = cross_join(list(unique = 1:3, b = 1:2)) expect_equal(tab, setnames(CJ(a = 1:3, b = 1:2), "a", "unique")) }) mlr3misc/tests/testthat/test_strip_srcrefs.R0000644000176200001440000000025614635030076021066 0ustar liggesuserstest_that("remove srcref from function", { f = function(x) NULL attr(f, "srcref") = "mock_srcrefs" f_strip = strip_srcrefs(f) expect_null(attr(f_strip, "srcref")) }) mlr3misc/tests/testthat/test_crate.R0000644000176200001440000000101115156722625017271 0ustar liggesuserstest_that("crate", { meta_f = function(z) { x = 1 y = 2 crate( function() { c(x, y, z) }, x, .parent = parent.frame() ) } x = 100 y = 200 z = 300 f = meta_f(1) expect_equal(f(), c(1, 200, 300)) }) test_that("compilation works", { expect_false(is_compiled(crate(function() NULL, .compile = FALSE))) expect_true(is_compiled(crate(function() NULL, .compile = TRUE))) expect_true(is_compiled(crate(compiler::cmpfun(function() NULL), .compile = FALSE))) }) mlr3misc/tests/testthat/test_Callback.R0000644000176200001440000000637515170404762017704 0ustar liggesuserstest_that("Callback works", { CallbackTest = R6Class( "CallbackTest", inherit = Callback, public = list( on_stage = function(callback, context) { context$a = 1 }, info = "Test" ) ) test_callback = CallbackTest$new(id = "mlr3misc.test", label = "Test Callback", man = "mlr3misc::Callback") expect_equal(test_callback$id, "mlr3misc.test") expect_equal(test_callback$label, "Test Callback") expect_equal(test_callback$info, "Test") expect_man_exists(test_callback$man) ContextTest = R6::R6Class("ContextTest", inherit = Context, public = list(a = NULL)) context = ContextTest$new(id = "test") test_callback$call("on_stage", context) expect_equal(context$a, 1) expect_null(test_callback$call("on_stage_2", context)) expect_list(test_callback$state) test_callback$state$b = 1 expect_equal(test_callback$state$b, 1) }) test_that("call_back() function works", { CallbackTest1 = R6Class( "CallbackTest1", inherit = Callback, public = list( on_stage_1 = function(callback, context) { context$a = 1 }, on_stage_2 = function(callback, context) { context$b = 2 } ) ) test_callback_1 = CallbackTest1$new(id = "mlr3misc.test", label = "Test Callback") CallbackTest2 = R6Class( "CallbackTest2", inherit = Callback, public = list( on_stage_1 = function(callback, context) { context$c = 2 } ) ) test_callback_2 = CallbackTest2$new(id = "mlr3misc.test", label = "Test Callback") CallbackTest3 = R6Class( "CallbackTest3", inherit = Callback, public = list( on_stage_3 = function(callback, context) { context$d = 1 } ) ) test_callback_3 = CallbackTest3$new(id = "mlr3misc.test", label = "Test Callback") callbacks = list(test_callback_1, test_callback_2, test_callback_3) ContextTest = R6::R6Class("ContextTest", inherit = Context, public = list(a = NULL, b = NULL, c = NULL, d = NULL)) context = ContextTest$new(id = "test") call_back("on_stage_1", callbacks, context) expect_equal(context$a, 1) expect_null(context$b) expect_equal(context$c, 2) expect_null(context$d) call_back("on_stage_2", callbacks, context) expect_equal(context$a, 1) expect_equal(context$b, 2) expect_equal(context$c, 2) expect_null(context$d) call_back("on_stage_3", callbacks, context) expect_equal(context$a, 1) expect_equal(context$b, 2) expect_equal(context$c, 2) expect_equal(context$d, 1) }) test_that("as_callbacks.Callback works", { CallbackTest = R6Class( "CallbackTest", inherit = Callback, public = list( on_stage = function(callback, context) { context$a = 1 }, info = "Test" ) ) test_callback = CallbackTest$new(id = "mlr3misc.test", label = "Test Callback", man = "mlr3misc::Callback") expect_list(as_callbacks(test_callback)) expect_names(names(as_callbacks(test_callback)), identical.to = "mlr3misc.test") test_callback_2 = CallbackTest$new(id = "mlr3misc.test_2", label = "Test Callback", man = "mlr3misc::Callback") expect_list(as_callbacks(list(test_callback, test_callback_2))) expect_names( names(as_callbacks(list(test_callback, test_callback_2))), identical.to = c("mlr3misc.test", "mlr3misc.test_2") ) }) mlr3misc/tests/testthat/test_recycle_vectors.R0000644000176200001440000000100514455233002021354 0ustar liggesuserstest_that("recycle_vectors", { x = list(a = 1:3, b = 2L) res = recycle_vectors(x) expect_equal( res, list(a = 1:3, b = c(2L, 2L, 2L)) ) x = list(a = 1:3, b = 2L, c = integer()) expect_error( recycle_vectors(x), "common length" ) x = list(a = 1:3, b = 1:2) expect_error( recycle_vectors(x), "common length" ) x = list(a = 1:4, b = 1:2, c = 1L, d = letters[1:20]) res = recycle_vectors(x) expect_list(res, len = length(x)) expect_true(all(lengths(res) == 20)) }) mlr3misc/tests/testthat/test_keep_in_bounds.R0000644000176200001440000000102114455233002021143 0ustar liggesuserstest_that("keep_in_bounds", { expect_equal(keep_in_bounds(1:10, 1, 10), 1:10) expect_equal(keep_in_bounds(10:1, 1, 10), 10:1) expect_set_equal(keep_in_bounds(sample(100), 1, 10), 1:10) expect_equal(keep_in_bounds(NA, 1, 10), integer()) expect_equal(keep_in_bounds(c(NA, 1L), 1, 10), 1L) expect_equal(keep_in_bounds(c(NA, 1L), 10, 10), integer()) expect_equal(keep_in_bounds(11:20, 1, 10), integer()) expect_equal(keep_in_bounds(1:10, 11, 1), integer()) expect_equal(keep_in_bounds(-(1:10), -7, -5), -(5:7)) }) mlr3misc/tests/testthat/_snaps/0000755000176200001440000000000015150001267016265 5ustar liggesusersmlr3misc/tests/testthat/_snaps/conditions.md0000644000176200001440000000306515212054771020773 0ustar liggesusers# errors Code error_input("a: %s", "b") Condition Error: ! x a: b > Class: Mlr3ErrorInput --- Code error_config("abc") Condition Error: ! x abc > Class: Mlr3ErrorConfig --- Code error_timeout() Condition Error: ! x reached elapsed time limit > Class: Mlr3ErrorTimeout --- Code error_mlr3("abc") Condition Error: ! x abc > Class: Mlr3Error # warnings Code warning_config("%s & %s", "a", "b") Condition Warning: x a & b > Class: Mlr3WarningConfig --- Code warning_mlr3("a") Condition Warning: x a > Class: Mlr3Warning # bullets Code error_mlr3(c(i = "abc", i = "def")) Condition Error: ! abc def > Class: Mlr3Error # parent error chaining Code error_mlr3("wrapper context", parent = parent) Condition Error: ! x wrapper context > Class: Mlr3Error Caused by: x original problem > Class: Mlr3Error --- Code error_mlr3("wrapper", parent = plain_error) Condition Error: ! x wrapper > Class: Mlr3Error Caused by: plain error --- Code error_mlr3("outer", parent = middle) Condition Error: ! x outer > Class: Mlr3Error Caused by: x middle > Class: Mlr3Error Caused by: x inner > Class: Mlr3Error mlr3misc/tests/testthat/_snaps/printf.md0000644000176200001440000000035715212054772020126 0ustar liggesusers# formatting Code stopf("abc") Condition Error: ! abc --- Code stopf("s: %s", "b") Condition Error: ! s: b --- Code warningf("abc") Condition Warning: abc mlr3misc/tests/testthat/test_conditions.R0000644000176200001440000000452615150001267020344 0ustar liggesuserstest_that("errors", { expect_snapshot(error_input("a: %s", "b"), error = TRUE) expect_snapshot(error_config("abc"), error = TRUE) expect_snapshot(error_timeout(), error = TRUE) expect_snapshot(error_mlr3("abc"), error = TRUE) expect_class(error_input("a", signal = FALSE), "Mlr3ErrorInput") expect_class(error_config("a", signal = FALSE), "Mlr3ErrorConfig") expect_class(error_timeout(signal = FALSE), "Mlr3ErrorTimeout") expect_class(error_mlr3("a", signal = FALSE), "Mlr3Error") }) test_that("warnings", { expect_warning(warning_config("%s & %s", "a", "b")) expect_snapshot(warning_config("%s & %s", "a", "b")) expect_class(warning_config("abc", signal = FALSE), "Mlr3WarningConfig") expect_class(warning_input("a", signal = FALSE), "Mlr3WarningInput") expect_class(warning_config("a", signal = FALSE), "Mlr3WarningConfig") expect_class(warning_mlr3("a", signal = FALSE), "Mlr3Warning") expect_warning(warning_mlr3("a")) expect_snapshot(warning_mlr3("a")) expect_class(warning_mlr3("a", signal = FALSE), "Mlr3Warning") }) test_that("class is as expected", { x = try(suppressMessages(suppressWarnings(error_mlr3("a"))), silent = TRUE) cond = attr(x, "condition") expect_class(cond, "Mlr3Error") }) test_that("bullets", { expect_snapshot(error_mlr3(c(i = "abc", i = "def")), error = TRUE) }) test_that("parent error chaining", { parent = error_mlr3("original problem", signal = FALSE) expect_snapshot(error_mlr3("wrapper context", parent = parent), error = TRUE) # parent is stored on the condition wrapper = error_mlr3("wrapper", parent = parent, signal = FALSE) expect_class(wrapper$parent, "Mlr3Error") # works with non-mlr3 parent plain_error = simpleError("plain error") expect_snapshot(error_mlr3("wrapper", parent = plain_error), error = TRUE) # nested chaining inner = error_mlr3("inner", signal = FALSE) middle = error_mlr3("middle", parent = inner, signal = FALSE) expect_snapshot(error_mlr3("outer", parent = middle), error = TRUE) }) test_that("condition object is identical with signal = TRUE/FALSE", { err1 = error_mlr3("a", signal = FALSE) err2 = attr(try(error_mlr3("a", signal = TRUE), silent = TRUE), "condition") expect_equal(err1, err2) warn1 = warning_mlr3("a", signal = FALSE) warn2 = tryCatch(warning_mlr3("a", signal = TRUE), warning = identity) expect_equal(warn1, warn2) }) mlr3misc/tests/testthat/test_transpose.R0000644000176200001440000000034014455233002020200 0ustar liggesuserstest_that("transpose_list", { x = list(list(a = 2, b = 3), list(a = 5, b = 10)) expect_equal(transpose_list(x), list(a = list(2, 5), b = list(3, 10))) x = list(a = list()) expect_equal(transpose_list(x), list()) }) mlr3misc/tests/testthat/test_get_private.R0000644000176200001440000000075415156722625020521 0ustar liggesuserstest_that("get_private<- works", { a = R6Class( "A", private = list( y = 123 ) )$new() get_private(a, "y") = 314L expect_true(get_private(a)$y == 314L) }) test_that("get_private<- checks for correct input", { a = R6Class( "A", private = list( y = 123 ) )$new() expect_error({ get_private(a, c("x", "y")) = 314L }) expect_error({ get_private(a, character(0)) = 314L }) expect_error({ get_private(a, NULL) = 314L }) }) mlr3misc/tests/testthat/test_set_params.R0000644000176200001440000000314214635030076020331 0ustar liggesusersskip_if_not_installed("paradox") test_that("set_params checks inputs correctly", { .ps = paradox::ps(a = paradox::p_dbl(), b = paradox::p_dbl()) expect_error(set_params(.ps, a = 2, .values = list(a = 1))) expect_error(set_params(.ps, 2)) expect_error(set_params(.ps, .values = list(1))) }) test_that("set_params works for ... with correct inputs", { .ps = paradox::ps(a = paradox::p_dbl(), b = paradox::p_dbl()) .ps$values$a = 1 set_params(.ps, b = 2, .insert = FALSE) expect_null(.ps$values$a) expect_true(.ps$values$b == 2) .ps$values = list(a = 1) set_params(.ps, b = 2, .insert = TRUE) expect_true(.ps$values$b == 2) expect_true(.ps$values$a == 1) }) test_that("set_params works for .values with correct inputs", { .ps = paradox::ps(a = paradox::p_dbl(), b = paradox::p_dbl()) .ps$values$a = 1 set_params(.ps, .values = list(b = 2), .insert = FALSE) expect_null(.ps$values$a) expect_true(.ps$values$b == 2) .ps$values = list(a = 1) set_params(.ps, .values = list(b = 2), .insert = TRUE) expect_true(.ps$values$b == 2) expect_true(.ps$values$a == 1) }) test_that("set_params works for .values and ... with correct inputs", { .ps = paradox::ps(a = paradox::p_dbl(), b = paradox::p_dbl(), c = paradox::p_dbl()) .ps$values$a = 1 set_params(.ps, b = 2, .values = list(c = 3), .insert = TRUE) expect_true(.ps$values$a == 1) expect_true(.ps$values$b == 2) expect_true(.ps$values$c == 3) .ps$values = list(a = 1) set_params(.ps, b = 2, .values = list(c = 3), .insert = FALSE) expect_null(.ps$values$a) expect_true(.ps$values$b == 2) expect_true(.ps$values$c == 3) }) mlr3misc/tests/testthat/test_set_names.R0000644000176200001440000000077214455233002020151 0ustar liggesuserstest_that("set_names", { x = 1:3 expect_names(names(x), "unnamed") x = set_names(x, letters[1:3]) expect_set_equal(names(x), letters[1:3]) x = set_names(x, toupper) expect_set_equal(names(x), LETTERS[1:3]) x = letters[1:3] x = set_names(x) expect_equal(unname(x), names(x)) }) test_that("set_col_names", { x = iris[, 1:3] x = set_col_names(x, letters[1:3]) expect_set_equal(names(x), letters[1:3]) x = set_col_names(x, toupper) expect_set_equal(names(x), LETTERS[1:3]) }) mlr3misc/tests/testthat/test_map.R0000644000176200001440000001551315147263543016763 0ustar liggesuserstest_that("map (lapply)", { x = 1:2 names(x) = letters[1:2] expect_identical(map(x, identity), list(a = 1L, b = 2L)) x = c(TRUE, FALSE) names(x) = letters[1:2] expect_identical(map_lgl(x, identity), x) x = 1:2 names(x) = letters[1:2] expect_identical(map_int(x, identity), x) x = 1:2 + 0.5 names(x) = letters[1:2] expect_identical(map_dbl(x, identity), x) x = letters[1:2] names(x) = letters[1:2] expect_identical(map_chr(x, identity), x) }) test_that("map (extract)", { x = list(list(a = 1L, b = 1L), list(a = 2L)) expect_identical(map(x, "a"), list(1L, 2L)) expect_identical(map(x, 1L), list(1L, 2L)) expect_identical(map(x, "b"), list(1L, NULL)) expect_error(map(x, 2L)) expect_identical(map_int(x, "a"), 1:2) expect_identical(map_int(x, 1L), 1:2) expect_error(map_int(x, "b")) }) test_that("imap", { x = list(a = 1, b = 2) fun = function(x, y) sprintf("%s:%i", y, x) res = imap(x, fun) expect_list(res, len = 2, names = "unique") expect_equal(res$a, "a:1") expect_equal(res$b, "b:2") res = imap_chr(x, fun) expect_character(res, len = 2) expect_named(res, c("a", "b")) expect_equal(unname(res), c("a:1", "b:2")) x = list(1L, 2L) fun = function(x, y) x + y res = imap(x, fun) expect_list(res, len = 2, names = "unnamed") expect_identical(res[[1]], 2L) expect_identical(res[[2]], 4L) res = imap_int(x, fun) expect_identical(res, c(2L, 4L)) }) test_that("pmap", { x = list(a = 1:2, b = 2:1) fun = function(a, b) c(a, b) res = pmap(x, fun) expect_list(res, len = 2, names = "unnamed") expect_equal(res[[1]], 1:2) expect_equal(res[[2]], 2:1) fun = function(a, b) a + b res = pmap(x, fun) expect_identical(res, list(3L, 3L)) res = pmap_int(x, fun) expect_identical(res, c(3L, 3L)) }) test_that("map_dtr", { x = list(list(a = 1L), list(a = 2L)) expect_data_table(map_dtr(x, identity), nrows = 2, ncols = 1) x = list(data.table(a = 1L), data.table(a = 2L)) expect_data_table(map_dtr(x, identity), nrows = 2, ncols = 1) x = list(x = data.table(a = 1L), y = data.table(b = 2L)) res = map_dtr(x, identity, .fill = TRUE) expect_data_table(res, nrows = 2L, ncols = 2L) expect_names(names(res), identical.to = c("a", "b")) x = list(data.table(a = 1L), data.table(a = 2L)) res = map_dtr(x, identity, .idcol = "id") expect_data_table(res, nrows = 2L, ncols = 2L) expect_names(names(res), identical.to = c("id", "a")) expect_equal(res$id, 1:2) }) test_that("map_dtc", { x = list(a = 1L, b = 2L) res = map_dtc(x, identity) expect_data_table(res, nrows = 1, ncols = 2) expect_names(names(res), identical.to = names(x)) x = list(data.table(a = 1L, b = 1L), data.table(c = 2L)) res = map_dtc(x, identity) expect_data_table(res, nrows = 1, ncols = 3) expect_names(names(res), identical.to = c("a", "b", "c")) x = list(data.table(a = 1L, b = 1L), data.table(b = 2L)) res = map_dtc(x, identity) expect_data_table(res, nrows = 1, ncols = 3) expect_names(names(res), identical.to = c("a", "b", "b.1")) # check that map_dtc doesnt prefix colnames in result x = list(a = list(1, 2), b = list(3, 4)) expect_data_table(map_dtc(x, identity), nrows = 2, ncols = 2) # check that map_dtc doesn't prefix colnames in result x = list(foo = data.table(a = 1L, b = 1L), bar = data.table(c = 2L)) res = map_dtc(x, identity) expect_data_table(res, nrows = 1, ncols = 3) expect_names(names(res), identical.to = c("a", "b", "c")) x = list(foo = data.frame(a = 1L, b = 1L), c = 2) res = map_dtc(x, identity) expect_data_table(res, nrows = 1, ncols = 3) expect_names(names(res), identical.to = c("a", "b", "c")) }) test_that("map_if", { x = list(a = 1:3, b = c("a", "b"), c = runif(3)) out = map_if(x, is.numeric, length) expect_equal(out, set_names(list(3L, c("a", "b"), 3L), names(x))) x = iris out = map_if(x, is.numeric, sqrt) expect_equal(out$Sepal.Length, sqrt(x$Sepal.Length)) x = as.data.table(iris) out = map_if(x, is.numeric, sqrt) expect_equal(out$Sepal.Length, sqrt(x$Sepal.Length)) }) test_that("map_at", { x = iris x = map_at(x, c("Sepal.Length", "Sepal.Width"), as.integer) expect_data_frame(x, nrows = 150, ncols = 5) expect_equal(unname(map_chr(x, class)), c("integer", "integer", "numeric", "numeric", "factor")) x = as.data.table(iris) x = map_at(x, c("Sepal.Length", "Sepal.Width"), as.integer) expect_data_table(x, nrows = 150, ncols = 5) expect_equal(unname(map_chr(x, class)), c("integer", "integer", "numeric", "numeric", "factor")) }) test_that("keep", { x = list(a = 1:3, b = c("a", "b"), c = runif(3)) out = keep(x, is.numeric) expect_list(out, len = 2L) expect_named(out, c("a", "c")) x = iris out = keep(x, is.numeric) expect_data_frame(out, types = "numeric") x = as.data.table(iris) out = keep(x, is.numeric) expect_data_table(out, types = "numeric") }) test_that("discard", { x = list(a = 1:3, b = c("a", "b"), c = runif(3)) out = discard(x, is.numeric) expect_list(out, len = 1L) expect_named(out, "b") # list-level attributes are preserved (issue #148) x = list(a = 1, b = "tree") attr(x, "my_attr") = "some_value" out = discard(x, is.numeric) expect_identical(attr(out, "my_attr"), "some_value") expect_identical(names(out), "b") x = iris out = discard(x, is.numeric) expect_data_frame(out, types = "factor") x = as.data.table(iris) out = discard(x, is.numeric) expect_data_table(out, types = "factor") }) test_that("some/every", { x = list(a = 1:3, b = c("a", "b"), c = runif(3)) expect_true(some(x, is.numeric)) expect_false(every(x, is.numeric)) expect_false(some(x, is.complex)) expect_false(every(x, is.complex)) x = list(list(p = TRUE, x = 1), list(p = FALSE, x = 2)) expect_true(some(x, "p")) expect_false(every(x, "p")) }) test_that("detect", { x = list(a = 1:3, b = c("a", "b"), c = runif(3)) out = detect(x, is.numeric) expect_equal(out, 1:3) out = detect(x, is.character) expect_equal(out, c("a", "b")) out = detect(x, is.logical) expect_null(out) }) test_that("compact", { x = list(a = 1:3, b = c("a", "b"), c = NULL, d = NULL) out = compact(x) expect_identical(out, x[1:2]) x = list(a = 1:3, b = c("a", "b"), c = runif(3)) out = compact(x) expect_identical(out, x) }) test_that("pmap does not segfault (#56)", { expect_error(pmap(1:4, function(x) x), "list") }) test_that("walk", { .x = list(a = 1, b = 2) sq = function(x) x^2 expect_equal(walk(.x, sq), .x) }) test_that("iwalk", { .x = list(a = 1, b = 2) sq = function(x, name) x^2 expect_equal(iwalk(.x, sq), .x) }) test_that("pwalk", { .x = list(a = 1:3, b = 2) f = function(a, b) a + b expect_equal(pwalk(.x, f), .x) }) test_that("map_br / map_bc", { .x = list(1:3, 4:6, 7:9) expect_equal( map_bc(.x, identity), matrix(1:9, nrow = 3, byrow = FALSE) ) expect_equal( map_br(.x, identity), matrix(1:9, nrow = 3, byrow = TRUE) ) }) mlr3misc/tests/testthat/test_which_max.R0000644000176200001440000000407314455233002020140 0ustar liggesuserstest_that("which_max", { expect_identical(which_min(c(1, 9), ties_method = "first"), 1L) expect_identical(which_min(c(1, NA, 9), ties_method = "first", na_rm = TRUE), 1L) expect_identical(which_min(c(9, 1), ties_method = "first"), 2L) expect_identical(which_min(c(-9, -1), ties_method = "first"), 1L) expect_identical(which_min(c(-9, 1), ties_method = "first"), 1L) expect_identical(which_max(c(1, 9, 9), ties_method = "first"), 2L) expect_identical(which_max(c(1, 9, NA, 9), ties_method = "first", na_rm = TRUE), 2L) expect_identical(which_max(c(1, 9, 9), ties_method = "last"), 3L) expect_identical(which_max(3, ties_method = "first"), 1L) expect_identical(which_max(3, ties_method = "last"), 1L) expect_identical(which_max(c(9, 1, 9, 9), ties_method = "first"), 1L) expect_identical(which_max(c(9, 1, 9, 9), ties_method = "last"), 4L) expect_identical(which_min(integer(0)), integer(0)) expect_identical(which_max(integer(0)), integer(0)) expect_identical(which_min(logical()), integer(0)) expect_identical(which_max(logical()), integer(0)) expect_identical(which_min(NA, na_rm = TRUE), integer(0)) expect_identical(which_max(NA, na_rm = TRUE), integer(0)) expect_identical(which_min(c(NA, 1), na_rm = FALSE), NA_integer_) expect_identical(which_max(c(NA, 1), na_rm = FALSE), NA_integer_) expect_identical(which_min(NA_integer_), NA_integer_) expect_identical(which_max(NA_integer_), NA_integer_) expect_identical(which_min(NA_real_), NA_integer_) expect_identical(which_max(NA_real_), NA_integer_) }) test_that("na_rm", { expect_equal(which_max(NA_integer_, na_rm = TRUE), integer()) expect_equal(which_max(NA_integer_, na_rm = FALSE), NA_integer_) expect_equal(which_max(c(1L, NA_integer_), na_rm = FALSE), NA_integer_) expect_equal(which_max(c(1L, NA_integer_), na_rm = TRUE), 1L) expect_equal(which_max(NA_real_, na_rm = TRUE), integer()) expect_equal(which_max(NA_real_, na_rm = FALSE), NA_integer_) expect_equal(which_max(c(1, NA_real_), na_rm = FALSE), NA_integer_) expect_equal(which_max(c(1, NA_real_), na_rm = TRUE), 1L) }) mlr3misc/tests/testthat/test_distinct_values.R0000644000176200001440000000216015156722625021401 0ustar liggesuserstest_that("distinct_values", { x = factor(c(letters[1:2], NA), levels = letters[1:3]) expect_character(distinct_values(x), len = 2, any.missing = FALSE) expect_character(distinct_values(x, na_rm = FALSE), len = 3, any.missing = TRUE) expect_character(distinct_values(x, drop = FALSE), len = 3, any.missing = FALSE) expect_character(distinct_values(x, drop = FALSE, na_rm = FALSE), len = 4, any.missing = TRUE) x = c(TRUE, NA) expect_logical(distinct_values(x), len = 1, any.missing = FALSE) expect_logical(distinct_values(x, na_rm = FALSE), len = 2) expect_logical(distinct_values(x, drop = FALSE, na_rm = TRUE), len = 2, any.missing = FALSE) expect_logical(distinct_values(x, drop = FALSE, na_rm = FALSE), len = 3) x = c(1:3, NA) expect_integer(distinct_values(x, na_rm = TRUE, drop = TRUE), len = 3, any.missing = FALSE) expect_integer(distinct_values(x, na_rm = FALSE, drop = TRUE), len = 4, any.missing = TRUE) expect_integer(distinct_values(x, na_rm = TRUE, drop = FALSE), len = 3, any.missing = FALSE) expect_integer(distinct_values(x, na_rm = FALSE, drop = FALSE), len = 4, any.missing = TRUE) }) mlr3misc/tests/testthat/test_require_namespaces.R0000644000176200001440000000131415156722625022054 0ustar liggesuserstest_that("require_namespaces", { expect_equal(require_namespaces("mlr3misc"), "mlr3misc") expect_equal(require_namespaces("checkmate"), "checkmate") expect_error(require_namespaces("this_is_not_a_package999"), "not be loaded", class = "packageNotFoundError") expect_true(tryCatch( require_namespaces("this_is_not_a_package999"), packageNotFoundError = function(e) TRUE )) expect_equal( tryCatch( require_namespaces("this_is_not_a_package999"), packageNotFoundError = function(e) e$packages ), "this_is_not_a_package999" ) expect_true(require_namespaces("mlr3misc", quietly = TRUE)) expect_false(require_namespaces("this_is_not_a_package999", quietly = TRUE)) }) mlr3misc/tests/testthat/test_map_values.R0000644000176200001440000000051714455233002020324 0ustar liggesuserstest_that("map_values", { x = letters[1:5] old = c("b", "d", "z") new = c("x", "y", "1") expect_equal(map_values(x, old, new), c("a", "x", "c", "y", "e")) old = "m" new = "n" expect_equal(map_values(x, old, new), x) old = c("a", "b") new = "z" expect_equal(map_values(x, old, new), c("z", "z", "c", "d", "e")) }) mlr3misc/tests/testthat/test_compose.R0000644000176200001440000000027014455233002017631 0ustar liggesuserstest_that("compose", { f = compose(function(x) x + 1, function(x) x / 2) expect_equal(f(10), 6) f = compose(sqrt) expect_equal(f(4), 2) expect_error(compose(), "length") }) mlr3misc/tests/testthat/test_ids.R0000644000176200001440000000042314455233002016743 0ustar liggesuserstest_that("ids", { Foo = R6::R6Class("Foo", public = list(id = NULL, initialize = function(id) self$id = id), cloneable = TRUE) f1 = Foo$new("f1") f2 = Foo$new("f2") xs = list(f1, f2) expect_equal(ids(xs), c("f1", "f2")) expect_equal(ids(list()), character()) }) mlr3misc/tests/testthat/test_check_operators.R0000644000176200001440000000067114731230564021353 0ustar liggesuserstest_that("check operators", { # AND operator expect_true(TRUE %check&&% TRUE) expect_equal(TRUE %check&&% "error", "error") expect_equal("error" %check&&% TRUE, "error") expect_equal("error1" %check&&% "error2", "error1, and error2") # OR operator expect_true(TRUE %check||% TRUE) expect_true(TRUE %check||% "error") expect_true("error" %check||% TRUE) expect_equal("error1" %check||% "error2", "error1, or error2") }) mlr3misc/tests/testthat/test_invoke.R0000644000176200001440000000075414455233002017466 0ustar liggesuserstest_that("invoke", { expect_equal(invoke(identity, .args = list(1L)), 1L) foo = function(x, y) x + y expect_equal(invoke(foo, .args = list(x = 1, y = 2)), 3) expect_equal(invoke(foo, .args = list(x = 1), y = 2), 3) expect_equal(invoke(foo, x = 1, y = 2), 3) f = function(x) warning("foo") prev_warn = getOption("warn") expect_warning(f(1)) expect_warning(invoke(f, 1)) expect_error(invoke(f, 1, .opts = list(warn = 2))) expect_equal(getOption("warn"), prev_warn) }) mlr3misc/tests/testthat/setup.R0000644000176200001440000000037114455233002016267 0ustar liggesusersold_opts = options( warnPartialMatchArgs = TRUE, warnPartialMatchAttr = TRUE, warnPartialMatchDollar = TRUE ) # https://github.com/HenrikBengtsson/Wishlist-for-R/issues/88 old_opts = lapply(old_opts, function(x) if (is.null(x)) FALSE else x) mlr3misc/tests/testthat/test_encapsulate.R0000644000176200001440000001442015212015277020476 0ustar liggesuserstest_that("encapsulation works", { fun = function() { 1L } for (method in c("none", "evaluate", "callr", "mirai", "try")) { if (method != "none" && !requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, fun) log = res$log expect_identical(res$result, 1L) expect_number(res$elapsed, lower = 0) expect_data_table(res$log, ncols = 2) expect_names(names(log), permutation.of = c("class", "condition")) } }) test_that("messages and warnings are logged", { fun = function() { message("foo") warning(warningCondition("test", class = "WarningTest")) 99L } for (method in c("evaluate", "callr")) { if (method != "none" && !requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, fun) log = res$log expect_identical(res$result, 99L) expect_number(res$elapsed, lower = 0) expect_data_table(log, ncols = 2) expect_set_equal(as.character(log$class), c("output", "warning")) expect_class(log$condition[log$class == "warning"][[1]], "WarningTest") } }) test_that("errors are logged", { fun = function() { stop(errorCondition("foo", class = "ErrorTest")) } for (method in c("evaluate", "callr", "mirai", "try")) { if (!requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, fun) expect_null(res$result) expect_equal(as.character(res$log$class), "error") expect_class(res$log$condition[[1]], "ErrorTest") } }) test_that("segfaults are logged", { fun = function() { tools::pskill(Sys.getpid()) 1L } for (method in c("callr", "mirai")) { if (!requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, fun) expect_null(res$result) expect_equal(as.character(res$log$class), "error") } }) test_that("timeout", { f = function(x) { for (i in 1:10) { Sys.sleep(x) } 1 } expect_error(encapsulate("none", .f = f, .args = list(x = 1), .timeout = 1), "time limit") for (method in c("evaluate", "callr", "mirai")) { if (!requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, .f = f, .args = list(x = 1), .timeout = 1) expect_null(res$result) expect_true("error" %in% res$log$class) expect_class(res$log$condition[[1]], "Mlr3ErrorTimeout") } }) test_that(".timeout = 0 short-circuits with an immediate Mlr3ErrorTimeout", { f = function() 1L for (method in c("none", "try", "evaluate", "callr", "mirai")) { if (method != "none" && !requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, .f = f, .timeout = 0) expect_null(res$result, info = method) expect_equal(as.character(res$log$class), "error", info = method) expect_class(res$log$condition[[1]], "Mlr3ErrorTimeout", info = method) } }) test_that("try", { fun1 = function(...) { message("foo") } fun2 = function(...) { message("foo") } expect_message(encapsulate("try", function(...) message("foo"))) expect_warning(encapsulate("try", function(...) warning("foo"))) }) test_that("rng state is transferred", { rng_state = .GlobalEnv$.Random.seed on.exit({ .GlobalEnv$.Random.seed = rng_state }) fun = function() { sample(seq(1000), 1) } for (method in c("callr", "mirai")) { if (!requireNamespace(method, quietly = TRUE)) { next } # no seed res = encapsulate(method, fun) expect_number(res$result) set.seed(1, kind = "Mersenne-Twister") res = encapsulate(method, fun) expect_equal(res$result, 836) expect_equal(sample(seq(1000), 1), 679) set.seed(1, kind = "Mersenne-Twister") expect_equal(fun(), 836) expect_equal(sample(seq(1000), 1), 679) set.seed(1, kind = "Wichmann-Hill") res = encapsulate(method, fun) expect_equal(res$result, 309) expect_equal(sample(seq(1000), 1), 885) set.seed(1, kind = "Wichmann-Hill") expect_equal(fun(), 309) expect_equal(sample(seq(1000), 1), 885) set.seed(1, kind = "L'Ecuyer-CMRG") res = encapsulate(method, fun) expect_equal(res$result, 371) expect_equal(sample(seq(1000), 1), 359) set.seed(1, kind = "L'Ecuyer-CMRG") expect_equal(fun(), 371) expect_equal(sample(seq(1000), 1), 359) } }) test_that("seeds are applied", { fun = function() { sample(seq(1000), 1) } value = invoke(fun, .seed = 1) for (method in c("callr", "mirai")) { # "evaluate" if (!requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, fun, .seed = 1) expect_equal(res$result, value) } }) test_that("mirai daemons can be pre-started", { skip_if_not_installed("mirai") fun = function() { 1L } mirai::daemons(1, .compute = "local") expect_equal(mirai::status(.compute = "local")$connections, 1) on.exit({ mirai::daemons(0, .compute = "local") }) res = encapsulate("mirai", fun, .compute = "local") expect_equal(res$result, 1L) expect_equal(mirai::status(.compute = "local")$connections, 1) expect_equal(unname(mirai::status(.compute = "local")$mirai["completed"]), 1) }) test_that("mirai daemon is started if not running", { skip_if_not_installed("mirai") fun = function() { 1L } expect_equal(mirai::status()$connections, 0) res = encapsulate("mirai", fun) expect_equal(res$result, 1L) expect_equal(mirai::status()$connections, 0) }) test_that("condition objects are stored", { fun = function() { message("a") warning(simpleWarning("b")) stop(simpleError("c")) } for (method in c("evaluate", "callr", "mirai", "try")) { if (!requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, fun) expect_equal(as.character(res$log$class), c("output", "warning", "error")) expect_class(res$log$condition[[1]], "message") expect_class(res$log$condition[[2]], "warning") expect_class(res$log$condition[[3]], "error") } # data.table with 1 row fun = function() { mlr3misc::stopf("c") } for (method in c("evaluate", "callr", "mirai", "try")) { if (!requireNamespace(method, quietly = TRUE)) { next } res = encapsulate(method, fun) expect_equal(as.character(res$log$class), "error") expect_equal(res$log$condition[[1]], tryCatch(stopf("c"), error = identity)) } }) mlr3misc/tests/testthat.R0000644000176200001440000000017314455233002015127 0ustar liggesusersif (requireNamespace("testthat", quietly = TRUE)) { library("testthat") library("mlr3misc") test_check("mlr3misc") } mlr3misc/MD50000644000176200001440000003001415212172057012313 0ustar liggesusersfcc98264f56ac5bf2a9c77c29280b460 *DESCRIPTION 8c7124b70b447cb906cf06f7832e7a7e *NAMESPACE 5cdc0f954bbf15612ed61438afab516d *NEWS.md 964e79f1f109a31edd5b856876b2252d *R/Callback.R c4f287ced38c9d1e91326581f64f8fa8 *R/Context.R 19f668ed4a2320a022fd4e61cdafc0ed *R/Dictionary.R 62bb6f78b74382f76a4ab5afeafdc8e6 *R/as_factor.R 380df3f70175c60e01f7bbfc1d587621 *R/as_short_string.R 5bcce9e9e9fc4b5deebf4d6054fc73f8 *R/assert_ro_binding.R d0cf2e3b9f303dbc31493c38f49f3908 *R/calculate_hash.R f21936083fd4a2a9e1e268083dadd44b *R/capitalize.R 64e83774509b004700da8e8f2702e651 *R/cat_cli.R 05f0e6123f21cf8aa2c36a3b4f8462e5 *R/catn.R 99d82ec8bfc2c452dc2ce637ad5de2f0 *R/check_operators.R 2220927c6e90217dd950283e51c7aca6 *R/check_packages_installed.R ea25d1b8dd885375bfbc4e3876ded6fc *R/chunk.R 77507b2139bfa517ffe8a7b2c409f58f *R/compose.R f2f6aa75f52ee3f05824790aba77449f *R/compute_mode.R 857d1a563376d1a2116edca16176dfac *R/conditions.R b40147bb10b15cf4f2e22aa57d1b378f *R/count_missing.R 983c7b223cf1f356acc60f1d7108d68b *R/crate.R f5fa0bbd7ccb2f2fd4887352e6eb49a6 *R/cross_join.R 889dd49b57062adb2c50ddf39fd12ee8 *R/dictionary_sugar.R 7b756a4fc81256dd69aae118f0027875 *R/did_you_mean.R 1853c066eb3883126ec6db4f86562c91 *R/distinct_values.R de4699e4b289efe18b02cb00908e5bc6 *R/encapsulate.R 2dfb88744df94ffc355d13748dfe32e3 *R/enframe.R 6b3b083aecc14ac134cf0bc408073bd8 *R/extract_vars.R 40b04b882ad89c74a3264e5202d20292 *R/format_bib.R b9d58dc8cb184c43fa5fe05bf6381d49 *R/formulate.R 2b81fdd19366c8466afe4bba708bde20 *R/get_private.R 1c6ec6348c4c94126de6fb6707915ccd *R/get_seed.R 553101f0361979fcf4d93fbae5c16583 *R/has_element.R a361aec2e8468a1d9b3a40ce823bb24a *R/ids.R cd9c41d90047c369fe2041dda5df52f4 *R/insert_named.R ff73fbfd829d79c029c7004f11492c34 *R/invoke.R 314e21c0b4b7df06cfb2f109e4e0e076 *R/is_scalar_na.R 10d13fc60e79bd7f2dcae74febd318e4 *R/keep_in_bounds.R 88d4df45f61966206ef829ab4a9d7779 *R/leanify.R d2070ed866cf8b0916210d3a7ac97c57 *R/load_dataset.R 9b3a15a9b213b7ebf16350f3eba2d797 *R/map_values.R c7f7bab45c6be531032f10499f57f30e *R/modify.R 5a240e19005bdba3aabc587de47fe11e *R/named_list.R c8023b2bc7987973d366f5e413bc3c4f *R/named_vector.R 082b0d7910b7e8b02c559123976743ca *R/names2.R f2a2ef1462d7ca9b46b5bbd74282e758 *R/nin.R 3bc82f01281697c3b322a5b1cff2a43f *R/open_help.R e0539b1cc79812b8f3484c116706206a *R/printf.R 9aa824ac8c817030d770b995ef73274a *R/probe.R d0d7ceca57940b7ff62a1e752f72fb47 *R/purrr_map.R 63a2a3af7ec4909558cada031b1ebbce *R/rcbind.R 030ebe9a4a74f98d686d61d8db78b85f *R/rd_info.R fbf6a69a1e840420f310055da44cc523 *R/recycle_vector.R 046239ea123721986f43a5f5e49fc35a *R/register_namespace_callback.R 7dcb44fdb33065a1871241dc0d8d4f1e *R/remove_named.R 1f35cb74c4f7f8328ae12e6e108ecdb1 *R/reorder_vector.R 9b196239a131fa57046631f239dd5094 *R/require_namespaces.R 51bb9f68c4c353c22b79fd4516faf45f *R/rowwise_table.R b5e16237871c63f74c857ffce7e18af7 *R/seq.R f60ea60b4e888e5597d6d7f3f765c59c *R/set_class.R 67da503bf38bec8c7ad86fc0974a3402 *R/set_names.R af0fc09e7c8a6f3ed72e28da213508e8 *R/set_params.R efe79afffa095431a487807f3ee0c849 *R/shuffle.R c6707d4154e03bc78d98dc16f169a224 *R/str_collapse.R 487d401df5b2a18a5e48c86226e17107 *R/str_indent.R 5dbf32e69a32647cf1a7754dac4b7fbd *R/str_trunc.R d35aa2a55c0593a7325ec811073cc842 *R/strip_srcrefs.R 544c27323d92871e1fa192e87203ba31 *R/to_decimal.R 79a66ccb969c34a6836bcc55272e0136 *R/topo_sort.R 3230f8473d646f86eea8f5a712177611 *R/transpose.R 2eaf341d42c2ccf4080f5d3114eab23e *R/unnest.R dc1af591e2475e9d2898e6153122f070 *R/warn_deprecated.R c92df2710c8cb66a5f565a5672d68c0c *R/which_max.R 040765f76d3dec0e8b08a9f691d59244 *R/with_package.R 5fd81d4a8ef828a06f3d5ea038074872 *R/zzz.R ec9b41d79f0210a1da52f367cb7e0b6a *README.md 905223ff4bc9f52fea176d2d0e384055 *man/Callback.Rd 9bd30852060e62fcd491a6d09ba39e70 *man/Context.Rd c1ff6c45e014a90cd60e314bbc2ed9fe *man/Dictionary.Rd 7863ab62fb56ee0575b9feec49b50bc5 *man/as_callback.Rd 08dc6558e88d5e04ce842dbc7bd26344 *man/as_factor.Rd 9b4169afe82819c92bbc7dfbbd2de8d3 *man/as_short_string.Rd 0b5d1de4d39dd1a1787f7b3ce960d854 *man/assert_callback.Rd bfb05970d43261531de60945def40573 *man/assert_ro_binding.Rd d6894222efa8d1cfdb117376011e596e *man/calculate_hash.Rd 660c6e70d9db94271940536345fc5c90 *man/call_back.Rd 7a25699bd2b939a07794696fe77ec9a0 *man/capitalize.Rd 0b6565aee27516e26c8e17c113228dd3 *man/cat_cli.Rd cd2e514647cd23e56c6b9499292f72e9 *man/catn.Rd 594d6f8901e7949ea40c1062ae6cf186 *man/check_operators.Rd a4555a4ffea8c693d54553f140b31b70 *man/check_packages_installed.Rd 43f464bf89566e6796bcf2720957bd10 *man/chunk_vector.Rd f76468d2d45784fed269f3e9f7630bd4 *man/clbk.Rd 6b575b974f1d7d872b97a6e19849b3dc *man/compat-map.Rd b9557ac73208e4bbb59f5481147e94d3 *man/compose.Rd 3d232f6161a4fc5a00dbd260128cbcbb *man/compute_mode.Rd a90bfa642239e55b32275ce5f4ba324e *man/count_missing.Rd 4943940c9ced631a2c0fdd905f589c03 *man/crate.Rd 3953135aa9fa56912d9518ecc1119423 *man/cross_join.Rd 148a60db50e2f88119d4764204f93dfe *man/deprecated_binding.Rd 18ca7f11f23f0561826598fc5bc87500 *man/dictionary_sugar_get.Rd 64aea800ddbc4466ef41123cec569514 *man/dictionary_sugar_inc_get.Rd 2d0fe5c4d037b123ce92a7ccc142434e *man/did_you_mean.Rd 32676faf0159b7a32d84c6f6bf3caffa *man/distinct_values.Rd 453011f7121d8c04e63dbd06d4e4d450 *man/encapsulate.Rd 98291e06e5110578f2d99456855a19ba *man/enframe.Rd 60734ce0e6b17e809e7ecb0a84689704 *man/extract_vars.Rd 82e14b4c5103f6c7c22afbdb75cb5dfc *man/figures/logo.png 7997990b2e8c1095321fb6fb6658055a *man/format_bib.Rd 08b33b89d896704b220478cb016b7068 *man/formulate.Rd 677b3f0982428287dea4f7892d4b2260 *man/get_private-set.Rd 949060430a449703106ea2e78b405ea1 *man/get_private.Rd aa73e688abe17553f22b4f703d269804 *man/get_seed.Rd 2fe9548aeecc95633d4b320d84130377 *man/has_element.Rd fcd793c8004f6898e0252a33d20b51a2 *man/hash_input.Rd bd7002956701de52f50856fe8d981d5b *man/ids.Rd 767b2237220457a77c40e3c5e7cf3a21 *man/insert_named.Rd f898d3ab34b508c9974e6a26fa628d8b *man/invoke.Rd fd245796d67adfa92e3edc165437cdd7 *man/is_scalar_na.Rd 3642960792c78dfc7607f2bef33a511f *man/keep_in_bounds.Rd 30cfbbedd574463b9d67c5e517d326bd *man/leanify_r6.Rd 849d425307ba6289e4571d6cfb7e2219 *man/load_dataset.Rd 7b896536769a3e64630cd4e77a42defd *man/macros/cite.Rd d78c2b7deb793c2a52e6609b155acacd *man/map_values.Rd 5637847c14eb7db74d382f9c11b781bf *man/mlr3misc-package.Rd be6a8169371db7c01707cc696e718f0f *man/mlr_callbacks.Rd de84d5f01605722183c37949f1a5809d *man/mlr_conditions.Rd 27dbbc1a38307a78dd1b3eb3538eb4dc *man/modify_if.Rd ccfbe7f1083cff0e8549b2f5699c2c6e *man/named_list.Rd 9ff9dc718ccf25a806cd847cf6040f95 *man/named_vector.Rd 57937dfd4f59e5c39a157e7fb31c1169 *man/names2.Rd a004ef522d21c560382bbed075f94553 *man/nin.Rd 36a6e1850e1f662b74d76d01f8e1c8ce *man/open_help.Rd cde2820cc6400d25024aab531b88aff1 *man/printf.Rd f3155c1e7d341ca6dce811f48313a3fa *man/rcbind.Rd 214e96642d5cfba8663f5d462beb000d *man/rd_info.Rd 7928c20ac5e75505ffaf2bc84ca8437a *man/recycle_vectors.Rd d64159c7e4433c880c07f3048b007724 *man/register_namespace_callback.Rd 65e8b5bf1eb4d5ae26b334dfe51feed0 *man/reorder_vector.Rd 47a91334e8ef7f16cc15ef0763b13672 *man/require_namespaces.Rd fb05131f9b222b544b988e6ba05c6c0f *man/rowwise_table.Rd b3fbee8d25e596ad27d55c4a757a2548 *man/sequence_helpers.Rd 89a250676cf6339de09ba1974e57819b *man/set_class.Rd 3897f9aaa85a25ee4a95b45bea260297 *man/set_names.Rd 6edfacaff0a4f10a88b3cbd023671479 *man/set_params.Rd 2f42f10b5c7b872559a0d4a088b07868 *man/shuffle.Rd d4fe0ce3917f92456b9eeec227d8e161 *man/str_collapse.Rd a36b9293a22f658aeef2cc06dd4a09d9 *man/str_indent.Rd 9c73bd289bd8ef258792d40b958aec44 *man/str_trunc.Rd 06fb172ae3980e4ae6a8badcedb87028 *man/strip_srcrefs.Rd 0122e4b6b1fa692dd2b5513c9eae1399 *man/to_decimal.Rd f30fa56c2067122c83cbbe6f88012990 *man/topo_sort.Rd a8c3bdeba738138a165e297cfefdf113 *man/transpose_list.Rd 53052fccab047a87ab70899697f4f467 *man/unnest.Rd 079c77769512cdc7aabaaf295c426552 *man/warn_deprecated.Rd f708eed461f25834024c449d0ed2fed9 *man/which_min.Rd a5a5dc7c94f3aa1c4a13c7f59e1a8026 *man/with_package.Rd 5283fb10f1406f2f8d79816173b9ef3a *src/backports.h 8597f809752593f9e9f40104d7e2f8b2 *src/count_missing.c 8cc5c68b058bd8de4970b1468610349e *src/init.c d7df06965d29b109a72b1ae4ecf958dc *src/keep_in_bounds.c a49c5bdb4d00ef56235eca44b281ebc7 *src/to_decimal.c be94228fd357f44b10eab8f41f67d5df *src/which_max.c 74008e4b6e9ad9f08b7316629cec1507 *tests/testthat.R 51d37e647c0d1d16bef8efa09258d57b *tests/testthat/_snaps/conditions.md f5f468da7f167c30a7b0b240acfe4c15 *tests/testthat/_snaps/printf.md d78cfe5120d7431728f44612a3edfde7 *tests/testthat/helper.R b3d2c943238886c3d55c3e19256a04d8 *tests/testthat/setup.R 390e7a8b3437a82b11f614fd1c1976f1 *tests/testthat/teardown.R 4a67c249982811bb91d049e6fc624b7c *tests/testthat/test_Callback.R 7b64991968c0401dbabf78c63c69eb50 *tests/testthat/test_Context.R 2063ad18706f72a4dc514134a3632136 *tests/testthat/test_Dictionary.R e20f46c108dacc864630f7364e3bd593 *tests/testthat/test_as_factor.R 1838bcfda7603e93771c03430ad082ba *tests/testthat/test_as_short_string.R 3e05505981e8e2c3dbf4068de3431c0b *tests/testthat/test_check_operators.R 77926759d6fe5619c79890ebd4439b58 *tests/testthat/test_check_packages_installed.R e17796a8399c2e2cea0bee083c27be6d *tests/testthat/test_chunk.R 2346f6e4b7cfa7657848c24d007ff8a6 *tests/testthat/test_compose.R aa101fb18a2200b78ffeed12a07f2eb1 *tests/testthat/test_conditions.R 5b6a180e285a803628b1b043fde3ae2d *tests/testthat/test_count_missing.R 953e9010c27169ce0bc0da956ab416ce *tests/testthat/test_crate.R 1044966d1bc36bd4ee4d358ced40fc87 *tests/testthat/test_cross_join.R 3587b9f967ee47d4fd22b82ddeed5fc6 *tests/testthat/test_distinct_values.R 9a09faf58da42a620db472758d44c409 *tests/testthat/test_encapsulate.R 692bdab3b85aaba3a8e5920b33ad4c1c *tests/testthat/test_extract_vars.R 68ebe67c44cf09c625e26156fc13b035 *tests/testthat/test_format_bib.R a749fbf260d84ed2a629c8afe9f9ae77 *tests/testthat/test_formulate.R d635e4d56ae40d8b8a16829fa454193e *tests/testthat/test_get_private.R 78ad185cb23b6d2159224a6341cff934 *tests/testthat/test_get_seed.R 648315a06e22f27af1dddddb39a8ff58 *tests/testthat/test_has_element.R b00db35a8af89371c8c7b74ac554347a *tests/testthat/test_ids.R b7b071f80820f8a3009d0b94536ea946 *tests/testthat/test_insert.R 486a93959e37988495356993ee4ef56f *tests/testthat/test_invoke.R 2395039b0be956caefa57263c32d6031 *tests/testthat/test_is_scalar_na.R 422ed5acfbf0f35bb709cab4863c81f5 *tests/testthat/test_keep_in_bounds.R 37f8e25b826132dc238bcf23fbcb1fdc *tests/testthat/test_leanify.R 239591a552620b8ff5812d89e2444fd0 *tests/testthat/test_load_data.R 13b1e6240d0eaa328844cfa6bb129f5f *tests/testthat/test_map.R 7b576b13c646efc0688ff90cb4350d81 *tests/testthat/test_map_values.R 5de69c16284fffc35602c60c1ffe16b6 *tests/testthat/test_modify.R 67b2782bcafb774986fafcdb91f1fb08 *tests/testthat/test_named_list.R 47275d32938b206b715613680960fe00 *tests/testthat/test_named_vector.R 7abf438659fedfbb62b9fba58fe8b431 *tests/testthat/test_names2.R 5d6d495228ecf16c83e527766dc0e32a *tests/testthat/test_nin.R 03dde44a60e58f58f32a029c7f1dbcfc *tests/testthat/test_printf.R d5bb86d3ac0e65105f022ffdfa38edb9 *tests/testthat/test_rcbind.R 30bfa353e56a4f1bec5540429d0ffd63 *tests/testthat/test_recycle_vectors.R 9c307463610f6f7c3bdfaea7067fb389 *tests/testthat/test_reorder_vector.R b664e6e4eddc5af6c388b213380c5dae *tests/testthat/test_require_namespaces.R 1ea87b5d4a1de7130f5896b4d0602d38 *tests/testthat/test_rowwise_table.R b6f63ff30179092b9eda912ab6bc4001 *tests/testthat/test_seq.R 08b4bbc64bac39da55c2ddc580d728b4 *tests/testthat/test_set_names.R 59fac36911386f1b3261e0c19a1114a0 *tests/testthat/test_set_params.R 9dc892bccb33ecf5100a0e3da1819842 *tests/testthat/test_shuffle.R cc165b723006a6ad33e863489fdd94c6 *tests/testthat/test_str_trunc.R fb9bde4f74dd0101369a92b58dc1315e *tests/testthat/test_strip_srcrefs.R b5172af67801e3e111eff2fa8f23f237 *tests/testthat/test_to_decimal.R 802b5db533ddc5a51517fcf4974d20f7 *tests/testthat/test_topo_sort.R bc9494d06094b337d7fb861d6766a11b *tests/testthat/test_transpose.R 52497c4579f3a49f7691bf44fdc5dac5 *tests/testthat/test_unnest.R 0e30aa085d01c3bc813b5494833e2291 *tests/testthat/test_warn_deprecated.R 5d49a545b4eeb5f5c19dc4f7d3a698bc *tests/testthat/test_which_max.R c1e662b968f30b28e71a0a264007a4b0 *tests/testthat/test_with_package.R mlr3misc/R/0000755000176200001440000000000015212054132012177 5ustar liggesusersmlr3misc/R/is_scalar_na.R0000644000176200001440000000031714455233002014744 0ustar liggesusers#' @title Check for a Single Scalar Value #' #' @param x (`any`)\cr #' Argument to check. #' @return (`logical(1)`). #' @export is_scalar_na = function(x) { is.atomic(x) && length(x) == 1L && is.na(x) } mlr3misc/R/printf.R0000644000176200001440000000572015147263543013647 0ustar liggesusers#' @title Functions for Formatted Output and Conditions #' #' @description #' `catf()`, `messagef()`, `warningf()` and `stopf()` are wrappers around [base::cat()], #' [base::message()], [base::warning()] and [base::stop()], respectively. #' #' @section Errors and Warnings: #' Errors and warnings get the classes `mlr3{error, warning}` and also inherit from #' `simple{Error, Warning}`. #' It is possible to give errors and warnings their own class via the `class` argument. #' Doing this, allows to suppress selective conditions via calling handlers, see e.g. #' [`globalCallingHandlers`]. #' #' When a function throws such a condition that the user might want to disable, #' a section *Errors and Warnings* should be included in the function documentation, #' describing the condition and its class. #' #' @details #' For leanified R6 classes, the call included in the condition is the method call #' and not the call into the leanified method. #' #' @param msg (`character(1)`)\cr #' Format string passed to [base::sprintf()]. #' @param file (`character(1)`)\cr #' Passed to [base::cat()]. #' @param ... (`any`)\cr #' Arguments passed down to [base::sprintf()]. #' @param wrap (`integer(1)` | `logical(1)`)\cr #' If set to a positive integer, [base::strwrap()] is used to wrap the string to the provided width. #' If set to `TRUE`, the width defaults to `0.9 * getOption("width")`. #' If set to `FALSE`, wrapping is disabled (default). #' If wrapping is enabled, all whitespace characters (`[[:space:]]`) are converted to spaces, #' and consecutive spaces are converted to a single space. #' @param class (`character()`)\cr #' Class of the condition (for errors and warnings). #' #' @name printf #' @examples #' messagef(" #' This is a rather long %s #' on multiple lines #' which will get wrapped. #' ", "string", wrap = 15) NULL str_wrap = function(str, width = FALSE) { if (isFALSE(width)) { return(str) } if (isTRUE(width)) { width = as.integer(0.9 * getOption("width")) } else { assert_count(width) } paste0(strwrap(gsub("[[:space:]]+", " ", str), width = width), collapse = "\n") } #' @export #' @rdname printf catf = function(msg, ..., file = "", wrap = FALSE) { cat(paste0(str_wrap(sprintf(msg, ...), width = wrap), collapse = "\n"), "\n", sep = "", file = file) } #' @export #' @rdname printf messagef = function(msg, ..., wrap = FALSE, class = NULL) { message(str_wrap(sprintf(msg, ...), width = wrap)) } #' @export #' @rdname printf warningf = function(msg, ..., wrap = FALSE, class = NULL) { class = c(class, "Mlr3Warning", "warning", "condition") message = str_wrap(sprintf(msg, ...), width = wrap) warning(structure(list(message = as.character(message)), class = class)) } #' @export #' @rdname printf stopf = function(msg, ..., wrap = FALSE, class = NULL) { class = c(class, "Mlr3Error", "error", "condition") message = str_wrap(sprintf(msg, ...), width = wrap) stop(structure(list(message = as.character(message)), class = class)) } mlr3misc/R/Context.R0000644000176200001440000000476115156722625013776 0ustar liggesusers#' @title Context #' #' @description #' Context objects allow [Callback] objects to access and modify data. #' The following packages implement context subclasses: #' #' * `ContextOptimization` in \CRANpkg{bbotk}. #' * `ContextEval` in \CRANpkg{mlr3tuning}. #' * `ContextTorch` in [`mlr3torch`](https://github.com/mlr-org/mlr3torch) #' #' @details #' [Context] is an abstract base class. #' A subclass inherits from [Context]. #' Data is stored in public fields. #' Access to the data can be restricted with active bindings (see example). #' #' @export #' @examples #' library(data.table) #' library(R6) #' #' # data table with column x and y #' data = data.table(x = runif(10), y = sample(c("A", "B"), 10, replace = TRUE)) #' #' # context only allows to access column y #' ContextExample = R6Class("ContextExample", #' inherit = Context, #' public = list( #' data = NULL, #' #' initialize = function(data) { #' self$data = data #' } #' ), #' #' active = list( #' y = function(rhs) { #' if (missing(rhs)) return(self$data$y) #' self$data$y = rhs #' } #' ) #' ) #' #' context = ContextExample$new(data) #' #' # retrieve content of column y #' context$y #' #' # change content of column y to "C" #' context$y = "C" Context = R6::R6Class( "Context", public = list( #' @field id (`character(1)`)\cr #' Identifier of the object. #' Used in tables, plot and text output. id = NULL, #' @field label (`character(1)`)\cr #' Label for this object. #' Can be used in tables, plot and text output instead of the ID. label = NULL, #' @description #' Creates a new instance of this [R6][R6::R6Class] class. #' #' @param id (`character(1)`)\cr #' Identifier for the new instance. #' @param label (`character(1)`)\cr #' Label for the new instance. initialize = function(id, label = NA_character_) { self$id = assert_string(id, min.chars = 1L) self$label = assert_string(label, na.ok = TRUE) }, #' @description #' Format object as simple string. #' @param ... (ignored). format = function(...) { sprintf("<%s>", class(self)[1L]) }, #' @description #' Print object. print = function() { catn(format(self), if (is.null(self$label) || is.na(self$label)) "" else paste0(": ", self$label)) catn(str_indent( "* Modifiable objects:", setdiff(names(self), c(".__enclos_env__", "label", "id", "clone", "initialize", "print", "format")) )) } ) ) mlr3misc/R/str_collapse.R0000644000176200001440000000226315147263543015036 0ustar liggesusers#' @title Collapse Strings #' #' @description #' Collapse multiple strings into a single string. #' #' @param str (`character()`)\cr #' Vector of strings. #' @param sep (`character(1)`)\cr #' String used to collapse the elements of `x`. #' @param quote (`character()`)\cr #' Quotes to use around each element of `x`. #' #' Will be replicated to length 2. #' @param n (`integer(1)`)\cr #' Number of elements to keep from `x`. See [utils::head()]. #' @param ellipsis (`character(1)`)\cr #' If the string has to be shortened, this is signaled by appending `ellipsis` to `str`. Default is `" [...]"`. #' #' @return (`character(1)`). #' #' @export #' @examples #' str_collapse(letters, quote = "'", n = 5) str_collapse = function(str, sep = ", ", quote = character(), n = Inf, ellipsis = "[...]") { formatted = head(str, n) if (length(quote)) { assert_character(quote, min.len = 1L, max.len = 2L, any.missing = FALSE) formatted = if (length(quote) == 1L) { paste0(quote, formatted, quote) } else { formatted = paste0(quote[1L], formatted, quote[2L]) } } if (length(str) > n) { formatted = c(formatted, ellipsis) } paste0(formatted, collapse = sep) } mlr3misc/R/capitalize.R0000644000176200001440000000060114455233002014447 0ustar liggesusers#' @title Capitalize the First Letter of Strings #' #' @description #' Takes a character vector and changes the first letter of each element to #' uppercase. #' #' @param str (`character()`). #' #' @return Character vector, same length as `str`. #' @export #' @examples #' capitalize("foo bar") capitalize = function(str) { substr(str, 1L, 1L) = toupper(substr(str, 1L, 1L)) str } mlr3misc/R/rd_info.R0000644000176200001440000000350315156722625013763 0ustar liggesusers#' @title Helpers to Create Manual Pages #' #' @description #' `rd_info()` is an internal generic to generate Rd or markdown code to be used in manual pages. #' `rd_format_string()` and `rd_format_range()` are string functions to assist generating #' proper Rd code. #' #' @param obj (`any`)\cr #' Object of the respective class. #' @param ... (`any)`)\cr #' Additional arguments. #' #' @return `character()`, possibly with markdown code. #' @keywords Internal #' @export rd_info = function(obj, ...) { UseMethod("rd_info") } #' @rdname rd_info #' @param lower (`numeric(1)`)\cr #' Lower bound. #' @param upper (`numeric(1)`)\cr #' Upper bound. #' @export rd_format_range = function(lower, upper) { if (is.na(lower) || is.na(upper)) { return("-") } str = sprintf( "%s%s, %s%s", if (is.finite(lower)) "[" else "(", if (is.finite(lower)) c(lower, lower) else c("-\\infty", "-Inf"), if (is.finite(upper)) c(upper, upper) else c("\\infty", "Inf"), if (is.finite(upper)) "]" else ")" ) paste0("\\eqn{", str[1L], "}{", str[2L], "}") } #' @rdname rd_info #' @inheritParams str_collapse #' @export rd_format_string = function(str, quote = c("\\dQuote{", "}")) { if (length(str) == 0L) { return("-") } str_collapse(str, quote = quote) } #' @rdname rd_info #' @param packages (`character()`)\cr #' Vector of package names. #' @export rd_format_packages = function(packages) { if (length(packages) == 0L) { return("-") } base_pkgs = c( "base", "compiler", "datasets", "graphics", "grDevices", "grid", "methods", "parallel", "splines", "stats", "stats4", "tcltk", "tools", "translations", "utils" ) link = packages %nin% base_pkgs str_collapse(sprintf("%s%s%s", fifelse(link, "\\CRANpkg{", "'"), packages, fifelse(link, "}", "'"))) } mlr3misc/R/check_packages_installed.R0000644000176200001440000000254115156722625017316 0ustar liggesusers#' @title Check that packages are installed, without loading them #' #' @description #' Calls [find.package()] to check if the all packages are installed. #' #' @param pkgs (`character()`)\cr #' Packages to check. #' @param warn (`logical(1)`)\cr #' If `TRUE`, signals a warning of class `"packageNotFoundWarning"` about the missing packages. #' @param msg (`character(1)`)\cr #' Format of the warning message. Use `"%s"` as placeholder for the list of packages. #' @return (`logical()`) named with package names. `TRUE` if the respective package is installed, `FALSE` otherwise. #' @export #' @examples #' check_packages_installed(c("mlr3misc", "foobar"), warn = FALSE) #' #' # catch warning #' tryCatch(check_packages_installed(c("mlr3misc", "foobaaar")), #' packageNotFoundWarning = function(w) as.character(w)) check_packages_installed = function( pkgs, warn = TRUE, msg = "The following packages are required but not installed: %s" ) { pkgs = unique(assert_character(pkgs, any.missing = FALSE)) assert_flag(warn) found = setNames(map_lgl(pkgs, function(pkg) length(find.package(pkg, quiet = TRUE)) > 0L), pkgs) if (warn && !all(found)) { assert_string(msg) miss = pkgs[!found] warning(warningCondition( sprintf(msg, paste0(miss, collapse = ",")), packages = miss, class = "packageNotFoundWarning" )) } found } mlr3misc/R/names2.R0000644000176200001440000000142214455233002013511 0ustar liggesusers#' @title A Type-Stable names() Replacement #' #' @description #' A simple wrapper around [base::names()]. #' Returns a character vector even if no names attribute is set. #' Values `NA` and `""` are treated as missing and replaced with the value provided in `missing_val`. #' #' @param x (`any`)\cr #' Object. #' @param missing_val (`atomic(1)`)\cr #' Value to set for missing names. #' Default is `NA_character_`. #' #' @return (`character(length(x))`). #' @export #' @examples #' x = 1:3 #' names(x) #' names2(x) #' #' names(x)[1:2] = letters[1:2] #' names(x) #' names2(x, missing_val = "") names2 = function(x, missing_val = NA_character_) { n = names(x) if (is.null(n)) { return(rep.int(missing_val, length(x))) } replace(n, is.na(n) | !nzchar(n), missing_val) } mlr3misc/R/encapsulate.R0000644000176200001440000002475515212015277014652 0ustar liggesusers#' @title Encapsulate Function Calls #' #' @description #' Evaluates a function, capturing conditions and measuring elapsed time. #' There are currently five modes: #' #' * `"none"`: Runs the call in the current session. #' Conditions are signaled normally; no log is kept. #' Works well together with [traceback()]. #' * `"try"`: Like `"none"`, but catches errors and writes them to the log. #' Warnings and messages are still signaled. #' * `"evaluate"`: Uses \CRANpkg{evaluate} to capture errors, warnings, and messages into the log. #' Printed output is lost. #' * `"callr"`: Uses \CRANpkg{callr} to run the function in a fresh R session. #' Errors, warnings, and messages are captured into the log; printed output is lost. #' Protects the calling session from segfaults at the cost of session startup overhead. #' The RNG state is propagated back to the calling session after evaluation. #' * `"mirai"`: Uses \CRANpkg{mirai} to run the function on a daemon. #' Errors, warnings, and messages are captured into the log; printed output is lost. #' The daemon can be pre-started via `daemons(1)`; if none is running, a new session is started per call. #' Offers similar safety to `"callr"` with lower overhead when a daemon is reused across calls. #' The RNG state is propagated back to the calling session after evaluation. #' #' @param method (`character(1)`)\cr #' One of `"none"`, `"try"`, `"evaluate"`, `"callr"`, or `"mirai"`. #' @param .f (`function()`)\cr #' Function to call. #' @param .args (`list()`)\cr #' Named list of arguments passed to `.f`. #' @param .opts (named `list()`)\cr #' Options to set via [options()] before calling `.f`. Restored on exit. #' @param .pkgs (`character()`)\cr #' Packages to load via [requireNamespace()] before calling `.f`. #' @param .seed (`integer(1)`)\cr #' Random seed set via [set.seed()] before calling `.f`. #' If `NA` (default), the seed is not changed; #' for `"callr"` and `"mirai"` modes the current RNG state is forwarded instead. #' @param .timeout (`numeric(1)`)\cr #' Timeout in seconds (`Inf` for no limit). #' Uses [setTimeLimit()] for `"none"` and `"evaluate"`; #' passed natively to `callr::r()` and `mirai::mirai()` for the other modes. #' A value of `0` is treated as an already-elapsed deadline: #' `.f` is not evaluated and the result contains an immediate `Mlr3ErrorTimeout` in `log`. #' @param .compute (`character(1)`)\cr #' Compute profile for `"mirai"` mode. Passed to `mirai::mirai()` as `.compute`. #' @return Named `list()` with three elements: #' * `"result"`: return value of `.f`, or `NULL` if an error was caught. #' * `"elapsed"`: elapsed time in seconds, measured via [proc.time()]. #' * `"log"`: `data.table()` with columns `"class"` (ordered factor with levels #' `"output"`, `"warning"`, `"error"`) and `"condition"` (list of condition objects). #' Messages are classified as `"output"` for historical reasons. #' Empty when no conditions were captured. #' @export #' @examples #' f = function(n) { #' message("hi from f") #' if (n > 5) { #' stop("n must be <= 5") #' } #' runif(n) #' } #' #' encapsulate("none", f, list(n = 1), .seed = 1) #' #' if (requireNamespace("evaluate", quietly = TRUE)) { #' encapsulate("evaluate", f, list(n = 1), .seed = 1) #' } #' #' if (requireNamespace("callr", quietly = TRUE)) { #' encapsulate("callr", f, list(n = 1), .seed = 1) #' } encapsulate = function( method, .f, .args = list(), .opts = list(), .pkgs = character(), .seed = NA_integer_, .timeout = Inf, .compute = "default" ) { assert_choice(method, c("none", "try", "evaluate", "mirai", "callr")) assert_list(.args, names = "unique") assert_list(.opts, names = "unique") assert_character(.pkgs, any.missing = FALSE) assert_count(.seed, na.ok = TRUE) assert_number(.timeout, lower = 0) log = NULL if (.timeout == 0) { # a zero timeout means the deadline has already elapsed log = data.table( class = factor("error", levels = c("output", "warning", "error"), ordered = TRUE), condition = list(error_timeout(signal = FALSE)) ) return(list(result = NULL, log = log, elapsed = 0)) } if (method %in% c("none", "try")) { require_namespaces(.pkgs) now = proc.time()[3L] if (method == "none") { result = invoke(.f, .args = .args, .opts = .opts, .seed = .seed, .timeout = .timeout) } else { result = try(invoke(.f, .args = .args, .opts = .opts, .seed = .seed, .timeout = .timeout)) if (inherits(result, "try-error")) { condition = if (grepl("reached elapsed time limit", result, fixed = TRUE)) { error_timeout(signal = FALSE) } else { x = attr(result, "condition") attr(x, "call") = NULL x } # try only catches errors; warnings and messages are signaled log = data.table(class = "error", condition = list(condition)) result = NULL } } elapsed = proc.time()[3L] - now } else if (method == "evaluate") { require_namespaces(c("evaluate", .pkgs)) now = proc.time()[3L] result = NULL log = evaluate::evaluate( "result <- invoke(.f, .args = .args, .opts = .opts, .seed = .seed, .timeout = .timeout)", stop_on_error = 1L, new_device = FALSE, include_timing = FALSE ) elapsed = proc.time()[3L] - now log = parse_evaluate(log) } else if (method == "mirai") { require_namespaces("mirai") # mirai does not copy the RNG state, so we need to do it manually .rng_state = if (is.na(.seed)) .GlobalEnv$.Random.seed .timeout = if (is.finite(.timeout)) .timeout * 1000 now = proc.time()[3L] result = mirai::collect_mirai(mirai::mirai( { suppressPackageStartupMessages({ lapply(.pkgs, requireNamespace) }) # restore RNG state from parent R session if (!is.null(.rng_state)) { assign(".Random.seed", .rng_state, envir = globalenv()) } conditions = NULL result = withCallingHandlers( tryCatch(mlr3misc::invoke(.f, .args = .args, .opts = .opts, .seed = .seed), error = function(e) { conditions <<- c(conditions, list(e)) NULL }), warning = function(w) { conditions <<- c(conditions, list(w)) invokeRestart("muffleWarning") }, message = function(m) { conditions <<- c(conditions, list(m)) invokeRestart("muffleMessage") } ) # copy new RNG state back to parent R session list(result = result, rng_state = if (is.na(.seed)) .GlobalEnv$.Random.seed, conditions = conditions) }, .args = list(.f = .f, .args = .args, .opts = .opts, .pkgs = .pkgs, .seed = .seed, .rng_state = .rng_state), .timeout = .timeout, .compute = .compute )) elapsed = proc.time()[3L] - now log = NULL if (mirai::is_error_value(result)) { conditions = if (unclass(result) == 5) { list(error_timeout(signal = FALSE)) } else { list(result) } result = NULL } else { # restore RNG state from mirai session if (!is.null(result$rng_state)) { assign(".Random.seed", result$rng_state, envir = globalenv()) } conditions = result$conditions result = result$result } log = conditions_to_log(conditions) } else { # method == "callr" require_namespaces("callr") # callr does not copy the RNG state, so we need to do it manually .rng_state = .GlobalEnv$.Random.seed now = proc.time()[3L] result = try( callr::r( callr_wrapper, args = list(.f = .f, .args = .args, .opts = .opts, .pkgs = .pkgs, .seed = .seed, .rng_state = .rng_state), timeout = .timeout ), silent = TRUE ) elapsed = proc.time()[3L] - now log = NULL if (inherits(result, "try-error")) { condition = attr(result, "condition") if (inherits(condition, "callr_timeout_error")) { condition = error_timeout(signal = FALSE) } log = data.table(class = "error", condition = list(condition)) result = NULL } else { if (!is.null(result$rng_state)) { assign(".Random.seed", result$rng_state, envir = globalenv()) } log = conditions_to_log(result$conditions) result = result$result } } if (is.null(log)) { log = data.table(class = character(), condition = list()) } if (nrow(log)) { log$condition = if (length(log$condition) == 1L) list(log$condition) else log$condition } log$class = factor(log$class, levels = c("output", "warning", "error"), ordered = TRUE) list(result = result, log = log, elapsed = elapsed) } parse_evaluate = function(log) { extract = function(x) { if (inherits(x, "message")) { return(list(class = "output", condition = list(x))) } if (inherits(x, "warning")) { return(list(class = "warning", condition = list(x))) } if (inherits(x, "error")) { if (grepl("reached elapsed time limit", x$message, fixed = TRUE)) { x = error_timeout(signal = FALSE) } return(list(class = "error", condition = list(x))) } NULL } log = map_dtr(log[-1L], extract) if (ncol(log) == 0L) NULL else log } conditions_to_log = function(conditions) { if (is.null(conditions)) { return(data.table(class = character(), condition = list())) } cls = function(x) { if (inherits(x, "error")) { "error" } else if (inherits(x, "warning")) { "warning" } else if (inherits(x, "errorValue")) { "error" } else { "output" } } log = map_dtr(conditions, function(x) { list(class = cls(x), condition = list(x)) }) log } callr_wrapper = function(.f, .args, .opts, .pkgs, .seed, .rng_state) { suppressPackageStartupMessages({ lapply(.pkgs, requireNamespace) }) options(.opts) if (!is.na(.seed)) { set.seed(.seed) } # restore RNG state from parent R session if (!is.null(.rng_state) && is.na(.seed)) { assign(".Random.seed", .rng_state, envir = globalenv()) } conditions = NULL result = withCallingHandlers( tryCatch(do.call(.f, .args), error = function(e) { conditions <<- c(conditions, list(e)) NULL }), warning = function(w) { conditions <<- c(conditions, list(w)) invokeRestart("muffleWarning") }, message = function(m) { conditions <<- c(conditions, list(m)) invokeRestart("muffleMessage") } ) # copy new RNG state back to parent R session list(result = result, rng_state = .GlobalEnv$.Random.seed, conditions = conditions) } mlr3misc/R/strip_srcrefs.R0000644000176200001440000000144115156722625015232 0ustar liggesusers#' @title Strip source references from objects #' #' @description #' Source references can make objects unexpectedly large and are undesirable in many situations. #' As \CRANpkg{renv} installs packages with the `--with-keep.source` option, #' we sometimes need to remove source references from objects. #' Methods should remove source references from the input, but should otherwise leave the input unchanged. #' #' @param x (`any`)\cr #' The object to strip of source references. #' @param ... (`any`)\cr #' Additional arguments to the method. #' #' @keywords internal #' @export strip_srcrefs = function(x, ...) { UseMethod("strip_srcrefs") } #' @export strip_srcrefs.default = function(x, ...) { x } #' @export strip_srcrefs.function = function(x, ...) { attr(x, "srcref") = NULL x } mlr3misc/R/map_values.R0000644000176200001440000000151714455233002014465 0ustar liggesusers#' @title Replace Elements of Vectors with New Values #' #' @description #' Replaces all values in `x` which match `old` with values in `new`. #' Values are matched with [base::match()]. #' #' @param x (`vector())`. #' @param old (`vector()`)\cr #' Vector with values to replace. #' @param new (`vector()`)\cr #' Values to replace with. #' Will be forced to the same length as `old` with [base::rep_len()]. #' #' @return (`vector()`) of the same length as `x`. #' @export #' @examples #' x = letters[1:5] #' #' # replace all "b" with "_b_", and all "c" with "_c_" #' old = c("b", "c") #' new = c("_b_", "_c_") #' map_values(x, old, new) map_values = function(x, old, new) { assert_atomic_vector(x) assert_atomic_vector(old) assert_atomic_vector(new) i = match(x, old, nomatch = 0L) x[i != 0L] = rep_len(new, length(old))[i] x } mlr3misc/R/check_operators.R0000644000176200001440000000204015170404765015507 0ustar liggesusers#' @title Logical Check Operators #' #' @description #' Logical AND and OR operators for `check_*`-functions from [`checkmate`][`checkmate::checkmate`]. #' #' @param lhs,rhs (`function()`)\cr #' `check_*`-functions that return either `TRUE` or an error message as a `character(1)`. #' #' @return Either `TRUE` or a `character(1)`. #' #' @name check_operators #' @examples #' library(checkmate) #' #' x = c(0, 1, 2, 3) #' check_numeric(x) %check&&% check_names(names(x), "unnamed") # is TRUE #' check_numeric(x) %check&&% check_true(all(x < 0)) # fails #' #' check_numeric(x) %check||% check_character(x) # is TRUE #' check_number(x) %check||% check_flag(x) # fails NULL #' @export #' @rdname check_operators # nolint next `%check&&%` = function(lhs, rhs) { if (!isTRUE(lhs) && !isTRUE(rhs)) { return(paste0(lhs, ", and ", rhs)) } if (isTRUE(lhs)) rhs else lhs } #' @export #' @rdname check_operators # nolint next `%check||%` = function(lhs, rhs) { if (!isTRUE(lhs) && !isTRUE(rhs)) { return(paste0(lhs, ", or ", rhs)) } TRUE } mlr3misc/R/catn.R0000644000176200001440000000105415147263543013266 0ustar liggesusers#' @title Function for Formatted Output #' #' @description #' Wrapper around [base::cat()] with a line break. #' Elements are converted to character and concatenated with [base::paste0()]. #' If a vector is passed, elements are collapsed with line breaks. #' #' @param ... (`any`)\cr #' Arguments passed down to [base::paste0()]. #' @param file (`character(1)`)\cr #' Passed to [base::cat()]. #' #' @export #' @examples #' catn(c("Line 1", "Line 2")) catn = function(..., file = "") { cat(paste0(..., collapse = "\n"), "\n", sep = "", file = file) } mlr3misc/R/set_params.R0000644000176200001440000000232715170404765014502 0ustar liggesusers#' @title Modify Values of a Parameter Set #' #' @description Convenience function to modify (or overwrite) the values of a [paradox::ParamSet]. #' #' @param .ps ([paradox::ParamSet])\cr #' The parameter set whose values are changed. #' @param ... (`any`) #' Named parameter values. #' @param .values (`list()`) #' Named list with parameter values. #' @param .insert (`logical(1)`)\cr #' Whether to insert the values (old values are being kept, if not overwritten), or to discard the #' old values. Is TRUE by default. #' #' @export #' @examples #' if (requireNamespace("paradox")) { #' param_set = paradox::ps(a = paradox::p_dbl(), b = paradox::p_dbl()) #' param_set$values$a = 0 #' set_params(param_set, a = 1, .values = list(b = 2), .insert = TRUE) #' set_params(param_set, a = 3, .insert = FALSE) #' set_params(param_set, b = 4, .insert = TRUE) #' } set_params = function(.ps, ..., .values = list(), .insert = TRUE) { dots = list(...) assert_list(dots, names = "unique") assert_list(.values, names = "unique") assert_disjunct(names(dots), names(.values)) new_values = c(dots, .values) if (.insert) { .ps$values = insert_named(.ps$values, new_values) } else { .ps$values = new_values } .ps } mlr3misc/R/compose.R0000644000176200001440000000137615147263543014015 0ustar liggesusers#' @title Composition of Functions #' #' @description #' Composes two or more functions into a single function. #' The returned function calls all provided functions in reverse order: #' The return value of the last function serves as input #' for the next to last function, and so on. #' #' @param ... (`functions`)\cr #' Functions to compose. #' #' @return (`function()`) which calls the functions provided via `...` #' in reverse order. #' #' @export #' @examples #' f = compose(function(x) x + 1, function(x) x / 2) #' f(10) compose = function(...) { funs = rev(lapply(list(...), match.fun)) assert_list(funs, min.len = 1L) function(...) { out = funs[[1L]](...) for (f in tail(funs, length(funs) - 1L)) { out = f(out) } out } } mlr3misc/R/calculate_hash.R0000644000176200001440000000313715156722625015306 0ustar liggesusers#' @title Calculate a Hash for Multiple Objects #' #' @description #' Calls [digest::digest()] using the 'xxhash64' algorithm after applying [`hash_input`] to each object. #' To customize the hashing behaviour, you can overwrite [`hash_input`] for specific classes. #' For `data.table` objects, [`hash_input`] is applied to all columns, so you can overwrite [`hash_input`] for #' columns of a specific class. #' Objects that don't have a specific method are hashed as is. #' #' @param ... (`any`)\cr #' Objects to hash. #' #' @return (`character(1)`). #' @export #' @examples #' calculate_hash(iris, 1, "a") calculate_hash = function(...) { digest(lapply(list(...), hash_input), algo = "xxhash64") } #' Hash Input #' #' Returns the part of an object to be used to calculate its hash. #' #' @param x (`any`)\cr #' Object for which to retrieve the hash input. #' @export hash_input = function(x) { UseMethod("hash_input") } #' @describeIn hash_input #' The formals and the body are returned in a `list()`. #' This ensures that the bytecode or parent environment are not included. #' in the hash. #' @export hash_input.function = function(x) { list(formals(x), as.character(body(x))) } #' @describeIn hash_input #' The data.table is converted to a regular list and `hash_input()` is applied to all elements. #' The conversion to a list ensures that keys and indices are not included in the hash. #' @export #' @method hash_input data.table hash_input.data.table = function(x) { lapply(as.list(x), hash_input) } #' @describeIn hash_input #' Returns the object as is. #' @export hash_input.default = function(x) { x } mlr3misc/R/open_help.R0000644000176200001440000000071114455233002014275 0ustar liggesusers#' @title Opens a Manual Page #' #' @description #' Simply opens a manual page specified in "package::topic" syntax. #' #' @param man (`character(1)`)\cr #' Manual page to open in "package::topic" syntax. #' @return Nothing. #' @export open_help = function(man) { if (!test_string(man)) { message("No help available") return(invisible()) } parts = strsplit(man, split = "::", fixed = TRUE)[[1L]] match.fun("help")(parts[2L], parts[1L]) } mlr3misc/R/crate.R0000644000176200001440000000250415170404765013437 0ustar liggesusers#' @title Isolate a Function from its Environment #' #' @description #' Put a function in a "lean" environment that does not carry unnecessary baggage with it (e.g. references to datasets). #' #' @param .fn (`function()`)\cr #' function to crate #' @param ... (`any`)\cr #' The objects, which should be visible inside `.fn`. #' @param .parent (`environment`)\cr #' Parent environment to look up names. Default to [topenv()]. #' @param .compile (`logical(1)`)\cr #' Whether to jit-compile the function. #' In case the function is already compiled. #' If the input function `.fn` is compiled, this has no effect, and the output function will always be compiled. #' #' @export #' @examples #' meta_f = function(z) { #' x = 1 #' y = 2 #' crate(function() { #' c(x, y, z) #' }, x) #' } #' x = 100 #' y = 200 #' z = 300 #' f = meta_f(1) #' f() crate = function(.fn, ..., .parent = topenv(parent.frame()), .compile = TRUE) { assert_flag(.compile) .compile = .compile || is_compiled(.fn) nn = map_chr(substitute(list(...)), as.character)[-1L] environment(.fn) = list2env(setNames(list(...), nn), parent = .parent) if (.compile) { .fn = compiler::cmpfun(.fn) } .fn } is_compiled = function(x) { tryCatch( { capture.output(compiler::disassemble(x)) TRUE }, error = function(e) FALSE ) } mlr3misc/R/cross_join.R0000644000176200001440000000125014640003436014475 0ustar liggesusers#' @title Cross-Join for data.table #' #' @description #' A safe version of [data.table::CJ()] in case a column is called #' `sorted` or `unique`. #' #' @param dots (named `list()`)\cr #' Vectors to cross-join. #' @param sorted (`logical(1)`)\cr #' See [data.table::CJ()]. #' @param unique (`logical(1)`)\cr #' See [data.table::CJ()]. #' @return [data.table::data.table()]. #' @export #' @examples #' cross_join(dots = list(sorted = 1:3, b = letters[1:2])) cross_join = function(dots, sorted = TRUE, unique = FALSE) { assert_list(dots, names = "unique") nn = names(dots) tab = invoke(CJ, sorted = sorted, unique = unique, .args = unname(dots)) setnames(tab, nn)[] } mlr3misc/R/str_trunc.R0000644000176200001440000000147414455233002014356 0ustar liggesusers#' @title Truncate Strings #' #' @description #' `str_trunc()` truncates a string to a given width. #' #' @param str (`character()`)\cr #' Vector of strings. #' @param width (`integer(1)`)\cr #' Width of the output. #' @param ellipsis (`character(1)`)\cr #' If the string has to be shortened, this is signaled by appending `ellipsis` to `str`. Default is `"[...]"`. #' #' @return (`character()`). #' @export #' @examples #' str_trunc("This is a quite long string", 20) str_trunc = function(str, width = 0.9 * getOption("width"), ellipsis = "[...]") { str = as.character(str) ellipsis = assert_string(ellipsis) nc_ellipsis = nchar(ellipsis) width = assert_int(width, lower = nc_ellipsis) ind = (!is.na(str) & nchar(str) > width) replace(str, ind, paste0(substr(str[ind], 1L, width - nc_ellipsis), ellipsis)) } mlr3misc/R/seq.R0000644000176200001440000000167114455233002013122 0ustar liggesusers#' @title Sequence Construction Helpers #' #' @description #' `seq_row()` creates a sequence along the number of rows of `x`, #' `seq_col()` a sequence along the number of columns of `x`. #' `seq_len0()` and `seq_along0()` are the 0-based counterparts to [base::seq_len()] and #' [base::seq_along()]. #' #' @param x (`any`)\cr #' Arbitrary object. Used to query its rows, cols or length. #' @param n (`integer(1)`)\cr #' Length of the sequence. #' @name sequence_helpers #' @examples #' seq_len0(3) NULL #' @export #' @rdname sequence_helpers seq_row = function(x) { seq_len(nrow(x)) } #' @export #' @rdname sequence_helpers seq_col = function(x) { seq_len(ncol(x)) } #' @export #' @rdname sequence_helpers seq_len0 = function(n) { n = assert_int(n, coerce = TRUE) if (n >= 1L) 0L:(n - 1L) else integer(0L) } #' @export #' @rdname sequence_helpers seq_along0 = function(x) { n = length(x) if (n >= 1L) 0L:(n - 1L) else integer(0L) } mlr3misc/R/has_element.R0000644000176200001440000000112015156722625014620 0ustar liggesusers#' @title Check if an Object is Element of a List #' #' @description #' Simply checks if a list contains a given object. #' #' * NB1: Objects are compared with identity. #' * NB2: Only use this on lists with complex objects, for simpler structures there are faster operations. #' * NB3: Clones of R6 objects are not detected. #' #' @inheritParams map #' @param .y (`any`)\cr #' Object to test for. #' @export #' @examples #' has_element(list(1, 2, 3), 1) has_element = function(.x, .y) { for (i in seq_along(.x)) { if (identical(.x[[i]], .y)) { return(TRUE) } } FALSE } mlr3misc/R/as_factor.R0000644000176200001440000000177214455233002014275 0ustar liggesusers#' @title Convert to Factor #' #' @description #' Converts a vector to a [factor()] and ensures that levels are #' in the order of the provided levels. #' #' @param x (atomic `vector()`)\cr #' Vector to convert to factor. #' @param levels (`character()`)\cr #' Levels of the new factor. #' @param ordered (`logical(1)`)\cr #' If `TRUE`, create an ordered factor. #' @return (`factor()`). #' @export #' @examples #' x = factor(c("a", "b")) #' y = factor(c("a", "b"), levels = c("b", "a")) #' #' # x with the level order of y #' as_factor(x, levels(y)) #' #' # y with the level order of x #' as_factor(y, levels(x)) as_factor = function(x, levels, ordered = is.ordered(x)) { assert_flag(ordered) levels = unique(as.character(levels)) levels = levels[!is.na(levels)] if (is.factor(x)) { if (!identical(levels(x), levels) || ordered != is.ordered(x)) { x = factor(x, levels = levels, ordered = ordered) } } else { x = factor(as.character(x), levels = levels, ordered = ordered) } x } mlr3misc/R/distinct_values.R0000644000176200001440000000352214455233002015527 0ustar liggesusers#' @title Get Distinct Values #' #' @description #' Extracts the distinct values of an atomic vector, with the possibility to drop levels #' and remove missing values. #' #' @param x (atomic `vector()`). #' @param drop :: `logical(1)`\cr #' If `TRUE`, only returns values which are present in `x`. #' If `FALSE`, returns all levels for [factor()] and [ordered()], as well as #' `TRUE` and `FALSE` for [logical()]s. #' @param na_rm :: `logical(1)`\cr #' If `TRUE`, missing values are removed from the vector of distinct values. #' #' @return (atomic `vector()`) with distinct values in no particular order. #' @export #' @examples #' # for factors: #' x = factor(c(letters[1:2], NA), levels = letters[1:3]) #' distinct_values(x) #' distinct_values(x, na_rm = FALSE) #' distinct_values(x, drop = FALSE) #' distinct_values(x, drop = FALSE, na_rm = FALSE) #' #' # for logicals: #' distinct_values(TRUE, drop = FALSE) #' #' # for numerics: #' distinct_values(sample(1:3, 10, replace = TRUE)) distinct_values = function(x, drop = TRUE, na_rm = TRUE) { assert_flag(drop) assert_flag(na_rm) UseMethod("distinct_values") } #' @export distinct_values.default = function(x, drop = TRUE, na_rm = TRUE) { lvls = unique(x) if (na_rm) { lvls = lvls[!is.na(lvls)] } lvls } #' @export distinct_values.logical = function(x, drop = TRUE, na_rm = TRUE) { if (!drop) { lvls = c(TRUE, FALSE) if (!na_rm && anyMissing(x)) { lvls = c(lvls, NA) } } else { lvls = unique(x) if (na_rm) { lvls = lvls[!is.na(lvls)] } } lvls } #' @export distinct_values.factor = function(x, drop = TRUE, na_rm = TRUE) { if (drop) { lvls = as.character(unique(x)) if (na_rm) { lvls = lvls[!is.na(lvls)] } } else { lvls = levels(x) if (!na_rm && anyMissing(x)) { lvls = c(lvls, NA_character_) } } lvls } mlr3misc/R/count_missing.R0000644000176200001440000000071314455233002015207 0ustar liggesusers#' @title Count Missing Values in a Vector #' #' @description #' Same as `sum(is.na(x))`, but without the allocation. #' #' @param x [`vector()`]\cr #' Supported are logical, integer, double, complex and string vectors. #' @return (`integer(1)`) number of missing values. #' #' @useDynLib mlr3misc c_count_missing #' @export #' @examples #' count_missing(c(1, 2, NA, 4, NA)) count_missing = function(x) { .Call(c_count_missing, x, PACKAGE = "mlr3misc") } mlr3misc/R/keep_in_bounds.R0000644000176200001440000000154214455233002015313 0ustar liggesusers#' @title Remove All Elements Out Of Bounds #' #' @description #' Filters vector `x` to only keep elements which are in bounds `[lower, upper]`. #' This is equivalent to the following, but tries to avoid unnecessary allocations: #' ``` #' x[!is.na(x) & x >= lower & x <= upper] #' ``` #' Currently only works for integer `x`. #' #' @param x (`integer()`)\cr #' Vector to filter. #' @param lower (`integer(1)`)\cr #' Lower bound. #' @param upper (`integer(1)`)\cr #' Upper bound. #' @return (integer()) with only values in `[lower, upper]`. #' @useDynLib mlr3misc c_keep_in_bounds #' @export #' @examples #' keep_in_bounds(sample(20), 5, 10) keep_in_bounds = function(x, lower, upper) { assert_integer(x) lower = assert_int(lower, coerce = TRUE) upper = assert_int(upper, coerce = TRUE) .Call(c_keep_in_bounds, x, lower, upper, PACKAGE = "mlr3misc") } mlr3misc/R/warn_deprecated.R0000644000176200001440000000556515156722625015504 0ustar liggesusers#' @title Give a Warning about a Deprecated Function, Argument, or Active Binding #' #' @description #' Generates a warning when a deprecated function, argument, or active binding #' is used or accessed. A warning will only be given once per session, and all #' deprecation warnings can be suppressed by setting the option #' `mlr3.warn_deprecated = FALSE`. #' #' The warning is of the format #' "what is deprecated and will be removed in the future." #' #' Use the `deprecated_binding()` helper function to create an active binding #' that generates a warning when accessed. #' @param what (`character(1)`)\cr #' A description of the deprecated entity. This should be somewhat descriptive, #' e.g. `"Class$method()"` or `"Argument 'foo' of Class$method()"`.\cr #' The `what` is used to determine if the warning has already been given, so #' it should be unique for each deprecated entity. #' @keywords internal #' @export warn_deprecated = function(what) { assert_string(what) if (getOption("mlr3.warn_deprecated", TRUE) && !exists(what, envir = deprecated_warning_given_db)) { warning_mlr3(paste0(what, " is deprecated and will be removed in the future."), class = "Mlr3WarningDeprecated") assign(what, TRUE, envir = deprecated_warning_given_db) } } deprecated_warning_given_db = new.env(parent = emptyenv()) #' @title Create an Active Binding that Generates a Deprecation Warning #' #' @description #' Creates an active binding that generates a warning when accessed, using #' `warn_deprecated()`. The active binding will otherwise be read-only. #' #' @param what (`character(1)`)\cr #' A description of the deprecated binding. Should be of the form `"Class$field"`. #' @param value (any)\cr #' The value of the active binding. This should be an expression that will #' be evaluated in the context of the active binding. It could, for example, #' refer to `self`. #' @examples #' MyClass = R6::R6Class("MyClass", public = list(), #' active = list( #' foo = deprecated_binding("MyClass$foo", "bar") #' ) #' ) #' mco = MyClass$new() #' mco$foo #' @keywords internal #' @export deprecated_binding = function(what, value) { assert_string(what) # build the function-expression that should be evaluated in the parent frame. fnq = substitute( function(rhs) { # don't throw a warning if we are converting the R6-object to a list, e.g. # when all.equals()-ing it. if (!identical(sys.call(-1)[[1]], quote(as.list.environment))) { warn_deprecated(what) } ## 'value' could be an expression that gets substituted here, which we only want to evaluate once x = value if (!missing(rhs) && !identical(rhs, x)) { error_mlr3(sprintf("%s read-only.", what)) } x }, # we substitute the 'what' constant directly, but the 'value' as expression. env = list(what = what, value = substitute(value)) ) eval.parent(fnq) } mlr3misc/R/load_dataset.R0000644000176200001440000000224215156722625014766 0ustar liggesusers#' @title Retrieve a Single Data Set #' #' @description #' Loads a data set with name `id` from package `package` and returns it. #' If the package is not installed, an error with condition "packageNotFoundError" is raised. #' The name of the missing packages is stored in the condition as `packages`. #' #' @param id (`character(1)`)\cr #' Name of the data set. #' @param package (`character(1)`)\cr #' Package to load the data set from. #' @param keep_rownames (`logical(1)`)\cr #' Keep possible row names (default: `FALSE`). #' #' @export #' @examples #' head(load_dataset("iris", "datasets")) load_dataset = function(id, package, keep_rownames = FALSE) { assert_string(id) assert_string(package) assert_flag(keep_rownames) if (!length(find.package(package, quiet = TRUE))) { msg = sprintf("Please install package '%s' for data set '%s'", package, id) stop(errorCondition(msg, packages = package, class = "packageNotFoundError")) } ee = new.env(parent = emptyenv(), hash = FALSE) data(list = id, package = package, envir = ee) data = ee[[id]] if (!keep_rownames && (is.data.frame(data) || is.matrix(data))) { rownames(data) = NULL } data } mlr3misc/R/recycle_vector.R0000644000176200001440000000152114455233002015334 0ustar liggesusers#' @title Recycle List of Vectors to Common Length #' #' @description #' Repeats all vectors of a list `.x` to the length of the longest vector #' using [rep()] with argument `length.out`. #' This operation will only work #' if the length of the longest vectors is an integer multiple of all shorter #' vectors, and will throw an exception otherwise. #' #' @param .x (`list()`). #' @return (`list()`) with vectors of same size. #' @export #' @examples #' recycle_vectors(list(a = 1:3, b = 2)) recycle_vectors = function(.x) { assert_list(.x, min.len = 1L) n = lengths(.x) n_max = max(n) if (n_max == 0L) { return(.x) } if (any(n == 0L) || any(n_max %% n > 0L)) { stop("Cannot recycle vectors to common length") } ii = which(n != n_max) if (length(ii)) { .x[ii] = lapply(.x[ii], rep, length.out = n_max) } .x } mlr3misc/R/set_names.R0000644000176200001440000000163214455233002014305 0ustar liggesusers#' @title Set Names #' #' @description #' Sets the names (or colnames) of `x` to `nm`. #' If `nm` is a function, it is used to transform the already existing names of `x`. #' #' @param x (`any`.)\cr #' Object to set names for. #' @param nm (`character()` | `function()`)\cr #' New names, or a function which transforms already existing names. #' @param ... (`any`)\cr #' Passed down to `nm` if `nm` is a function. #' #' @return `x` with updated names. #' #' @export #' @examples #' x = letters[1:3] #' #' # name x with itself: #' x = set_names(x) #' print(x) #' #' # convert names to uppercase #' x = set_names(x, toupper) #' print(x) set_names = function(x, nm = x, ...) { if (is.function(nm)) { nm = map_chr(names2(x), nm) } names(x) = nm x } #' @rdname set_names #' @export set_col_names = function(x, nm, ...) { if (is.function(nm)) { nm = map_chr(names2(x), nm) } colnames(x) = nm x } mlr3misc/R/reorder_vector.R0000644000176200001440000000162414455233002015354 0ustar liggesusers#' @title Reorder Vector According to Second Vector #' #' @description #' Returns an integer vector to order vector `x` according to vector `y`. #' #' @param x (`vector())`. #' @param y (`vector()`). #' @param na_last (`logical(1)`)\cr #' What to do with values in `x` which are not in `y`? #' * `NA`: Extra values are removed. #' * `FALSE`: Extra values are moved to the beginning of the new vector. #' * `TRUE`: Extra values are moved to the end of the new vector. #' @return (`integer()`). #' @export #' @examples #' # x subset of y #' x = c("b", "a", "c", "d") #' y = letters #' x[reorder_vector(x, y)] #' #' # y subset of x #' y = letters[1:3] #' x[reorder_vector(x, y)] #' x[reorder_vector(x, y, na_last = TRUE)] #' x[reorder_vector(x, y, na_last = FALSE)] reorder_vector = function(x, y, na_last = NA) { assert_flag(na_last, na.ok = TRUE) order(match(x, y), na.last = na_last, method = "radix") } mlr3misc/R/Callback.R0000644000176200001440000001531315170404765014037 0ustar liggesusers#' @title Callback #' #' @include named_list.R #' #' @description #' Callbacks allow to customize the behavior of processes in mlr3 packages. #' The following packages implement callbacks: #' #' * `CallbackOptimization` in \CRANpkg{bbotk}. #' * `CallbackTuning` in \CRANpkg{mlr3tuning}. #' * `CallbackTorch` in [`mlr3torch`](https://github.com/mlr-org/mlr3torch) #' #' @details #' [Callback] is an abstract base class. #' A subclass inherits from [Callback] and adds stages as public members. #' Names of stages should start with `"on_"`. #' For each subclass a function should be implemented to create the callback. #' For an example on how to implement such a function see `callback_optimization()` in \CRANpkg{bbotk}. #' Callbacks are executed at stages using the function [call_back()]. #' A [Context] defines which information can be accessed from the callback. #' #' @examples #' library(R6) #' #' # implement callback subclass #' CallbackExample = R6Class("CallbackExample", #' inherit = mlr3misc::Callback, #' public = list( #' on_stage_a = NULL, #' on_stage_b = NULL, #' on_stage_c = NULL #' ) #' ) #' @export Callback = R6Class( "Callback", public = list( #' @field id (`character(1)`)\cr #' Identifier of the callback. id = NULL, #' @field label (`character(1)`)\cr #' Label for this object. #' Can be used in tables, plot and text output instead of the ID. label = NULL, #' @field man (`character(1)`)\cr #' String in the format `[pkg]::[topic]` pointing to a manual page for this object. #' Defaults to `NA`, but can be set by child classes. man = NULL, #' @field state (named `list()`)\cr #' A callback can write data into the state. state = named_list(), #' @description #' Creates a new instance of this [R6][R6::R6Class] class. #' #' @param id (`character(1)`)\cr #' Identifier for the new instance. #' @param label (`character(1)`)\cr #' Label for the new instance. #' @param man (`character(1)`)\cr #' String in the format `[pkg]::[topic]` pointing to a manual page for this object. #' The referenced help package can be opened via method `$help()`. initialize = function(id, label = NA_character_, man = NA_character_) { self$id = assert_string(id) self$label = assert_string(label, na.ok = TRUE) self$man = assert_string(man, na.ok = TRUE) }, #' @description #' Helper for print outputs. #' @param ... (ignored). format = function(...) { sprintf("<%s:%s>", class(self)[1L], self$id) }, #' @description #' Printer. #' @param ... (ignored). print = function(...) { catn(format(self), if (is.null(self$label) || is.na(self$label)) "" else paste0(": ", self$label)) # get methods that start with "on_" and discard null catn(str_indent("* Active Stages:", names(compact(as.list(self)[grep("^on_.*", names(self), value = TRUE)])))) }, #' @description #' Opens the corresponding help page referenced by field `$man`. help = function() { open_help(self$man) }, #' @description #' Call the specific stage for a given context. #' #' @param stage (`character(1)`)\cr #' stage. #' @param context (`Context`)\cr #' Context. call = function(stage, context) { if (!is.null(self[[stage]])) { self[[stage]](self, context) } } ) ) #' @title Convert to a Callback #' #' @description #' Convert object to a [Callback] or a list of [Callback]. #' #' @param x (`any`)\cr #' Object to convert. #' @param ... (`any`)\cr #' Additional arguments. #' #' @return [Callback]. #' @export as_callback = function(x, ...) { UseMethod("as_callback") } #' @rdname as_callback #' @param clone (`logical(1)`)\cr #' If `TRUE`, ensures that the returned object is not the same as the input `x`. #' @export as_callback.Callback = function(x, clone = FALSE, ...) { if (clone) x$clone(deep = TRUE) else x } #' @rdname as_callback #' @export as_callbacks = function(x, clone = FALSE, ...) { UseMethod("as_callbacks") } #' @rdname as_callback #' @export as_callbacks.NULL = function(x, ...) { list() } #' @rdname as_callback #' @export as_callbacks.list = function(x, clone = FALSE, ...) { callbacks = lapply(x, as_callback, clone = clone, ...) set_names(callbacks, map(callbacks, "id")) } #' @rdname as_callback #' @export as_callbacks.Callback = function(x, clone = FALSE, ...) { set_names(list(if (clone) x$clone(deep = TRUE) else x), x$id) } #' @title Call Callbacks #' #' @description #' Call list of callbacks with context at specific stage. #' #' @keywords internal #' @export call_back = function(stage, callbacks, context) { if (!length(callbacks)) { return(invisible(NULL)) } assert_class(context, "Context") walk(callbacks, function(callback) callback$call(stage, context)) invisible(NULL) } #' @title Dictionary of Callbacks #' #' @include Dictionary.R #' #' @description #' A simple [mlr3misc::Dictionary] storing objects of class [Callback]. #' Each callback has an associated help page, see `mlr_callbacks_[id]`. #' #' This dictionary can get populated with additional callbacks by add-on packages. #' As a convention, the key should start with the name of the package, i.e. `package.callback`. #' #' For a more convenient way to retrieve and construct learners, see [clbk()]/[clbks()]. #' #' @export mlr_callbacks = R6Class("DictionaryCallbacks", inherit = Dictionary, cloneable = FALSE)$new() #' @title Syntactic Sugar for Callback Construction #' #' @name clbk #' #' @description #' Functions to retrieve callbacks from [mlr_callbacks] and set parameters in one go. #' #' @param .key (`character(1)`)\cr #' Key of the object to construct. #' @param ... (named `list()`)\cr #' Named arguments passed to the state of the callback. #' #' @seealso Callback call_back #' #' @export clbk = function(.key, ...) { callback = dictionary_sugar_get(mlr_callbacks, .key) callback$state = list(...) callback } #' @rdname clbk #' #' @param .keys (`character()`)\cr #' Keys of the objects to construct. #' #' @export clbks = function(.keys) { dictionary_sugar_mget(mlr_callbacks, .keys) } #' @title Assertions for Callbacks #' #' @description #' Assertions for [Callback] class. #' #' @param callback ([Callback]). #' @param null_ok (`logical(1)`)\cr #' If `TRUE`, `NULL` is allowed. #' #' @return [Callback] | List of [Callback]s. #' @export assert_callback = function(callback, null_ok = FALSE) { if (null_ok && is.null(callback)) { return(invisible(NULL)) } assert_class(callback, "Callback") invisible(callback) } #' @export #' @param callbacks (list of [Callback]). #' @rdname assert_callback assert_callbacks = function(callbacks) { invisible(lapply(callbacks, assert_callback)) } mlr3misc/R/set_class.R0000644000176200001440000000055215170404762014317 0ustar liggesusers#' @title Set the Class #' #' @description #' Simple wrapper for `class(x) = classes`. #' #' @param x (`any`). #' @param classes (`character()`)\cr #' Vector of new class names. #' #' @return Object `x`, with updated class attribute. #' @export #' @examples #' set_class(list(), c("foo1", "foo2")) set_class = function(x, classes) { class(x) = classes x } mlr3misc/R/conditions.R0000644000176200001440000001172315150001274014477 0ustar liggesusers#' @title Error Classes #' @name mlr_conditions #' @description #' Condition classes for mlr3. #' #' @section Formatting: #' It is also possible to use formatting options as defined in [`cli::cli_bullets`]. #' #' @section Errors: #' * `error_mlr3()` for the base `Mlr3Error` class. #' * `error_config()` for the `Mlr3ErrorConfig` class, which signals that a user has misconfigured #' something (e.g. invalid learner configuration). #' * `error_input()` for the `Mlr3ErrorInput` class, which signals that an invalid input was provided. #' * `error_timeout()` for the `Mlr3ErrorTimeout`, signalling a timeout (encapsulation). #' * `error_learner()` for the `Mlr3ErrorLearner`, signalling a learner error. #' * `error_learner_train()` for the `Mlr3ErrorLearner`, signalling a learner training error. #' * `error_learner_predict()` for the `Mlr3ErrorLearner`, signalling a learner prediction error. #' #' @section Warnings: #' * `warning_mlr3()` for the base `Mlr3Warning` class. #' * `warning_config()` for the `Mlr3WarningConfig` class, which signals that a user might have #' misconfigured something. #' * `warning_input()` for the `Mlr3WarningInput` if an invalid input might have been provided. #' #' @param msg (`character(1)`)\cr #' Error message. #' @param ... (any)\cr #' Passed to [`sprintf()`]. #' @param class (`character`)\cr #' Additional class(es). #' @param parent (`condition` or `NULL`)\cr #' Parent condition for error chaining. When provided, the parent error is displayed #' below the current error message. #' @param signal (`logical(1)`)\cr #' If `FALSE`, the condition object is returned instead of being signaled. #' @export error_config = function(msg, ..., class = NULL, parent = NULL, signal = TRUE) { error_mlr3(msg, ..., class = "Mlr3ErrorConfig", parent = parent, signal = signal) } #' @rdname mlr_conditions #' @export error_input = function(msg, ..., class = NULL, parent = NULL, signal = TRUE) { error_mlr3(msg, ..., class = "Mlr3ErrorInput", parent = parent, signal = signal) } #' @rdname mlr_conditions #' @export error_timeout = function(signal = TRUE) { error_mlr3("reached elapsed time limit", class = "Mlr3ErrorTimeout", signal = signal) } #' @rdname mlr_conditions #' @export error_mlr3 = function(msg, ..., class = NULL, parent = NULL, signal = TRUE) { assert_class(parent, "condition", null.ok = TRUE) cond = errorCondition(sprintf(msg, ...), class = c(class, "Mlr3Error")) cond$raw_message = cond$message cond$parent = parent cond$message = format(cond) if (signal) { return(stop(cond)) } cond } #' @rdname mlr_conditions #' @export warning_mlr3 = function(msg, ..., class = NULL, signal = TRUE) { cond = warningCondition(sprintf(msg, ...), class = c(class, "Mlr3Warning")) cond$message = format(cond) if (signal) { return(warning(cond)) } cond } #' @rdname mlr_conditions #' @export warning_config = function(msg, ..., class = NULL, signal = TRUE) { warning_mlr3(msg, ..., class = c(class, "Mlr3WarningConfig"), signal = signal) } #' @rdname mlr_conditions #' @export warning_input = function(msg, ..., class = NULL, signal = TRUE) { warning_mlr3(msg, ..., class = c(class, "Mlr3WarningInput"), signal = signal) } #' @export format.Mlr3Error = function(x, ...) { raw = x$raw_message %||% x$message message = if (!is.null(names(raw))) { # error message is already a cli list msg = c(raw, paste0("Class: ", class(x)[1L])) names(msg) = c(names(raw), ">") cli::format_bullets_raw(msg) } else { cli::format_bullets_raw(c( "x" = raw, ">" = paste0("Class: ", class(x)[1L]) )) } if (!is.null(x$parent)) { parent_msg = if (inherits(x$parent, "Mlr3Error")) { trimws(format(x$parent), which = "both") } else { conditionMessage(x$parent) } parent_lines = paste0(" ", strsplit(parent_msg, "\n")[[1L]]) message = c(message, "Caused by:", parent_lines) } paste0("\n", paste0(message, collapse = "\n"), "\n") } #' @export format.Mlr3Warning = function(x, ...) { message = if (!is.null(names(x$message))) { msg = c(x$message, paste0("Class: ", class(x)[1L])) names(msg) = c(names(x$message), ">") cli::format_bullets_raw(msg) } else { cli::format_bullets_raw(c( "x" = x$message, ">" = paste0("Class: ", class(x)[1L]) )) } paste0("\n", paste0(message, collapse = "\n"), "\n") } #' @rdname mlr_conditions #' @export error_learner = function(msg, ..., class = NULL, parent = NULL, signal = TRUE) { error_mlr3(msg, ..., class = c(class, "Mlr3ErrorLearner"), parent = parent, signal = signal) } #' @rdname mlr_conditions #' @export error_learner_train = function(msg, ..., class = NULL, parent = NULL, signal = TRUE) { error_learner(msg, ..., class = c(class, "Mlr3ErrorLearnerTrain"), parent = parent, signal = signal) } #' @rdname mlr_conditions #' @export error_learner_predict = function(msg, ..., class = NULL, parent = NULL, signal = TRUE) { error_learner(msg, ..., class = c(class, "Mlr3ErrorLearnerPredict"), parent = parent, signal = signal) } mlr3misc/R/ids.R0000644000176200001440000000057214455233002013110 0ustar liggesusers#' @title Extract ids from a List of Objects #' #' @description #' None. #' #' @param xs (`list()`)\cr #' Every element must have a slot 'id'. #' #' @return (`character()`). #' @export #' @examples #' xs = list(a = list(id = "foo", a = 1), bar = list(id = "bar", a = 2)) #' ids(xs) ids = function(xs) { vapply(xs, "[[", "id", FUN.VALUE = NA_character_, USE.NAMES = FALSE) } mlr3misc/R/str_indent.R0000644000176200001440000000146214455233002014501 0ustar liggesusers#' @title Indent Strings #' #' @description #' Formats a text block for printing. #' #' @param initial (`character(1)`)\cr #' Initial string, passed to [strwrap()]. #' @param str (`character()`)\cr #' Vector of strings. #' @param width (`integer(1)`)\cr #' Width of the output. #' @param exdent (`integer(1)`)\cr #' Indentation of subsequent lines in paragraph. #' @param ... (`any`)\cr #' Additional parameters passed to [str_collapse()]. #' #' @return (`character()`). #' @export #' @examples #' cat(str_indent("Letters:", str_collapse(letters), width = 25), sep = "\n") str_indent = function(initial, str, width = 0.9 * getOption("width"), exdent = 2L, ...) { if (length(str) == 0L) { str = "-" } strwrap(str_collapse(str, ...), initial = paste0(initial, " "), exdent = exdent, width = width) } mlr3misc/R/zzz.R0000644000176200001440000000057515013603635013175 0ustar liggesusers#' @import data.table #' @import checkmate #' @importFrom utils head tail adist #' @importFrom stats setNames as.formula terms runif #' @importFrom R6 R6Class is.R6 #' @importFrom digest digest #' @importFrom methods formalArgs hasArg #' @importFrom utils capture.output "_PACKAGE" .onLoad = function(libname, pkgname) { # nocov start backports::import(pkgname) } # nocov end mlr3misc/R/to_decimal.R0000644000176200001440000000126015170404762014434 0ustar liggesusers#' @title Convert a Vector of Bits to a Decimal Number #' #' @description #' Converts a logical vector from binary to decimal. #' The bit vector may have any length, the last position is the least significant, i.e. #' bits are multiplied with `2^(n-1)`, `2^(n-2)`, ..., `2^1`, `2^0` where `n` is the #' length of the bit vector. #' #' @param bits (`logical()`)\cr #' Logical vector of input values. Missing values are not allowed. #' If `bits` is longer than 30 elements, an exception is raised. #' #' @return (`integer(1)`). #' #' @useDynLib mlr3misc c_to_decimal #' @export to_decimal = function(bits) { bits = as.logical(bits) .Call(c_to_decimal, bits, PACKAGE = "mlr3misc") } mlr3misc/R/Dictionary.R0000644000176200001440000001561215211476443014450 0ustar liggesusers#' @title Key-Value Storage #' #' @description #' A key-value store for [R6::R6] objects. #' On retrieval of an object, the following applies: #' #' * If the object is a `R6ClassGenerator`, it is initialized with `new()`. #' * If the object is a function, it is called and must return an instance of a [R6::R6] object. #' * If the object is an instance of a R6 class, it is returned as-is. #' #' Default argument required for construction can be stored alongside their constructors by passing them to `$add()`. #' #' @section S3 methods: #' * `as.data.table(d)`\cr #' [Dictionary] -> [data.table::data.table()]\cr #' Converts the dictionary to a [data.table::data.table()]. #' #' @family Dictionary #' @export #' @examples #' library(R6) #' item1 = R6Class("Item", public = list(x = 1)) #' item2 = R6Class("Item", public = list(x = 2)) #' d = Dictionary$new() #' d$add("a", item1) #' d$add("b", item2) #' d$add("c", item1$new()) #' d$keys() #' d$get("a") #' d$mget(c("a", "b")) Dictionary = R6::R6Class( "Dictionary", public = list( #' @field items (`environment()`)\cr #' Stores the items of the dictionary items = NULL, #' @description #' Construct a new Dictionary. initialize = function() { self$items = new.env(parent = emptyenv()) }, #' @description #' Format object as simple string. #' @param ... (ignored). format = function(...) { sprintf("<%s>", class(self)[1L]) }, #' @description #' Print object. print = function() { keys = self$keys() catf(sprintf("%s with %i stored values", format(self), length(keys))) catf(str_indent("Keys:", keys)) }, #' @description #' Returns all keys which comply to the regular expression `pattern`. #' If `pattern` is `NULL` (default), all keys are returned. #' #' @param pattern (`character(1)`). #' #' @return `character()` of keys. keys = function(pattern = NULL) { keys = ls(self$items, all.names = TRUE) if (!is.null(pattern)) { assert_string(pattern) keys = keys[grepl(pattern, keys)] } keys }, #' @description #' Returns a logical vector with `TRUE` at its i-th position if the i-th key exists. #' #' @param keys (`character()`). #' #' @return `logical()`. has = function(keys) { assert_character(keys, min.chars = 1L, any.missing = FALSE) set_names(map_lgl(keys, exists, envir = self$items, inherits = FALSE), keys) }, #' @description #' Retrieves object with key `key` from the dictionary. #' Additional arguments must be named and are passed to the constructor of the stored object. #' #' @param key (`character(1)`). #' #' @param ... (`any`)\cr #' Passed down to constructor. #' #' @param .prototype (`logical(1)`)\cr #' Whether to construct a prototype object. #' #' @return Object with corresponding key. get = function(key, ..., .prototype = FALSE) { assert_string(key, min.chars = 1L) assert_flag(.prototype) args = list(...) if (.prototype) { args = insert_named(self$prototype_args(key), args) } invoke(dictionary_get, self = self, key = key, .args = args) }, #' @description #' Returns objects with keys `keys` in a list named with `keys`. #' Additional arguments must be named and are passed to the constructors of the stored objects. #' #' @param keys (`character()`). #' #' @param ... (`any`)\cr #' Passed down to constructor. #' #' @return Named `list()` of objects with corresponding keys. mget = function(keys, ...) { assert_character(keys, min.chars = 1L, any.missing = FALSE) set_names(lapply(keys, self$get, ...), keys) }, #' @description #' Adds object `value` to the dictionary with key `key`, potentially overwriting a previously stored item. #' Additional arguments in `...` must be named and are passed as default arguments to `value` during construction. #' #' @param key (`character(1)`). #' #' @param value (`any`). #' #' @param ... (`any`)\cr #' Passed down to constructor. #' #' @param .prototype_args (`list()`)\cr #' List of arguments to construct a prototype object. #' Can be used when objects have construction arguments without defaults. #' #' @return `Dictionary`. add = function(key, value, ..., .prototype_args = list()) { assert_string(key, min.chars = 1L) assert(check_class(value, "R6ClassGenerator"), check_r6(value), check_function(value)) dots = assert_list(list(...), names = "unique", .var.name = "additional arguments passed to Dictionary") assert_list(.prototype_args, names = "unique", .var.name = "prototype arguments") assign(x = key, value = list(value = value, pars = dots, prototype_args = .prototype_args), envir = self$items) # nolint invisible(self) }, #' @description #' Removes objects from the dictionary. #' #' @param keys (`character()`)\cr #' Keys of objects to remove. #' #' @return `Dictionary`. remove = function(keys) { i = wf(!self$has(keys)) if (length(i)) { stopf("Element with key '%s' not found!%s", keys[i], did_you_mean(keys[i], self$keys())) } rm(list = keys, envir = self$items) invisible(self) }, #' @description #' Returns the arguments required to construct a simple prototype of the object. #' #' @param key (`character(1)`)\cr #' Key of object to query for required arguments. #' #' @return `list()` of prototype arguments prototype_args = function(key) { assert_string(key, min.chars = 1L) self$items[[key]][["prototype_args"]] } ) ) dictionary_get = function(self, key, ..., .dicts_suggest = NULL) { obj = dictionary_retrieve_item(self, key, .dicts_suggest) dots = assert_list(list(...), names = "unique", .var.name = "arguments passed to Dictionary") dictionary_initialize_item(key, obj, dots) } dictionary_retrieve_item = function(self, key, dicts_suggest = NULL) { obj = get0(key, envir = self$items, inherits = FALSE, ifnotfound = NULL) if (is.null(obj)) { stopf( "Element with key '%s' not found in %s!%s%s", key, class(self)[1L], did_you_mean(key, self$keys()), did_you_mean_dicts(key, dicts_suggest) ) } obj } dictionary_initialize_item = function(key, obj, cargs = list()) { cargs = c(cargs[is.na(names2(cargs))], insert_named(obj$pars, cargs[!is.na(names2(cargs))])) constructor = obj$value if (inherits(constructor, "R6ClassGenerator")) { do.call(constructor$new, cargs) } else if (is.function(constructor)) { do.call(constructor, cargs) } else if (is.R6(constructor) && exists("clone", envir = constructor)) { constructor$clone(deep = TRUE) } else { constructor } } #' @export as.data.table.Dictionary = function(x, ...) { setkeyv(as.data.table(list(key = x$keys())), "key")[] } mlr3misc/R/get_seed.R0000644000176200001440000000100415156722625014114 0ustar liggesusers#' @title Get the Random Seed #' #' @description #' Retrieves the current random seed (`.Random.seed` in the global environment), #' and initializes the RNG first, if necessary. #' #' @return `integer()`. Depends on the [base::RNGkind()]. #' @export #' @examples #' str(get_seed()) get_seed = function() { seed = get0(".Random.seed", globalenv(), mode = "integer", inherits = FALSE) if (is.null(seed)) { runif(1L) seed = get0(".Random.seed", globalenv(), mode = "integer", inherits = FALSE) } seed } mlr3misc/R/cat_cli.R0000644000176200001440000000102115147263543013731 0ustar liggesusers#' @title Function to transform message to output #' #' @description #' Wrapper around [cli::cli_format_method()]. #' Uses [base::cat()] to transform the printout from a message to an output with a line break. #' #' @param expr (`any`)\cr #' Expression that calls `cli_*` methods, [base::cat()] or [base::print()] to format an object's printout. #' #' @export #' @examples #' cat_cli({ #' cli::cli_h1("Heading") #' cli::cli_li(c("x", "y")) #' }) cat_cli = function(expr) { cat(cli::cli_format_method(expr), sep = "\n") } mlr3misc/R/as_short_string.R0000644000176200001440000000400115170404762015540 0ustar liggesusers#' @title Convert R Object to a Descriptive String #' #' @description #' This function is intended to convert any R object to a short descriptive string, #' e.g. in [base::print()] functions. #' #' The following rules apply: #' #' * if `x` is `atomic()` with length 0 or 1: printed as-is. #' * if `x` is `atomic()` with length greater than 1, `x` is collapsed with `","`, #' and the resulting string is truncated to `trunc_width` characters. #' * if `x` is an expression: converted to character. #' * Otherwise: the class is printed. #' #' If `x` is a list, the above rules are applied (non-recursively) to its elements. #' #' @param x (`any`)\cr #' Arbitrary object. #' @param width (`integer(1)`)\cr #' Truncate strings to width `width`. #' @param num_format (`character(1)`)\cr #' Used to format numerical scalars via [base::sprintf()]. #' @return (`character(1)`). #' @export #' @examples #' as_short_string(list(a = 1, b = NULL, "foo", c = 1:10)) as_short_string = function(x, width = 30L, num_format = "%.4g") { # convert non-list object to string convert = function(x) { cl = class(x)[1L] if (is.atomic(x) && !is.null(x) && length(x) == 0L) { string = sprintf("%s(0)", cl) } else { string = switch( cl, numeric = paste0(sprintf(num_format, x), collapse = ","), integer = paste0(as.character(x), collapse = ","), logical = paste0(as.character(x), collapse = ","), character = paste0(x, collapse = ","), factor = paste0(as.character(x), collapse = ","), ordered = paste0(as.character(x), collapse = ","), expression = as.character(x), sprintf("<%s>", cl) ) } str_trunc(string, width = width) } width = assert_int(width, coerce = TRUE) # handle only lists and not any derived data types if (class(x)[1L] == "list") { if (length(x) == 0L) { return("list()") } ns = names2(x, missing_val = "") ss = lapply(x, convert) toString(paste0(ns, "=", ss)) } else { convert(x) } } mlr3misc/R/remove_named.R0000644000176200001440000000137315170404765015005 0ustar liggesusers#' @export #' @rdname insert_named remove_named = function(x, nn) { if (length(nn) == 0L) { return(x) } assert_character(nn, any.missing = FALSE) UseMethod("remove_named") } #' @export remove_named.default = function(x, nn) { assert_vector(x, names = "unique") x[setdiff(names(x), nn)] } #' @export #' @rdname insert_named remove_named.environment = function(x, nn) { rm(list = intersect(ls(envir = x, all.names = TRUE), nn), envir = x) x } #' @export #' @rdname insert_named remove_named.data.frame = function(x, nn) { nn = setdiff(names(x), nn) x[, nn, drop = FALSE] } #' @export #' @rdname insert_named remove_named.data.table = function(x, nn) { nn = intersect(nn, names(x)) if (length(nn)) { x[, (nn) := NULL][] } x } mlr3misc/R/chunk.R0000644000176200001440000000356215156722625013460 0ustar liggesusers#' @title Chunk Vectors #' #' @description #' Chunk atomic vectors into parts of roughly equal size. #' `chunk()` takes a vector length `n` and returns an integer with chunk numbers. #' `chunk_vector()` uses [base::split()] and `chunk()` to split an atomic vector into chunks. #' #' @param x (`vector()`)\cr #' Vector to split into chunks. #' @param chunk_size (`integer(1)`)\cr #' Requested number of elements in each chunk. #' Mutually exclusive with `n_chunks` and `props`. #' @param n_chunks (`integer(1)`)\cr #' Requested number of chunks. #' Mutually exclusive with `chunk_size` and `props`. #' @param shuffle (`logical(1)`)\cr #' If `TRUE`, permutes the order of `x` before chunking. #' #' @return `chunk()` returns a `integer()` of chunk indices, #' `chunk_vector()` a `list()` of `integer` vectors. #' @export #' @examples #' x = 1:11 #' #' ch = chunk(length(x), n_chunks = 2) #' table(ch) #' split(x, ch) #' #' chunk_vector(x, n_chunks = 2) #' #' chunk_vector(x, n_chunks = 3, shuffle = TRUE) chunk_vector = function(x, n_chunks = NULL, chunk_size = NULL, shuffle = TRUE) { assert_atomic_vector(x) unname(split(x, chunk(length(x), n_chunks, chunk_size, shuffle))) } #' @param n (`integer(1)`)\cr #' Length of vector to split. #' @rdname chunk_vector #' @export chunk = function(n, n_chunks = NULL, chunk_size = NULL, shuffle = TRUE) { assert_count(n) if (!xor(is.null(n_chunks), is.null(chunk_size))) { stop("You must provide either 'n_chunks' (x)or 'chunk_size'") } assert_count(n_chunks, positive = TRUE, null.ok = TRUE) assert_count(chunk_size, positive = TRUE, null.ok = TRUE) assert_flag(shuffle) if (n == 0L) { return(integer(0L)) } if (is.null(n_chunks)) { n_chunks = (n %/% chunk_size + (n %% chunk_size > 0L)) } chunks = as.integer((seq.int(0L, n - 1L) %% min(n_chunks, n))) + 1L if (shuffle) shuffle(chunks) else sort(chunks) } mlr3misc/R/invoke.R0000644000176200001440000000444315061011103013613 0ustar liggesusers#' @title Invoke a Function Call #' #' @description #' An alternative interface for [do.call()], similar to the deprecated function in \pkg{purrr}. #' This function tries hard to not evaluate the passed arguments too eagerly which is #' important when working with large R objects. #' #' It is recommended to pass all arguments named in order to not rely on positional #' argument matching. #' #' @param .f (`function()`)\cr #' Function to call. #' @param ... (`any`)\cr #' Additional function arguments passed to `.f`. #' @param .args (`list()`)\cr #' Additional function arguments passed to `.f`, as (named) `list()`. #' These arguments will be concatenated to the arguments provided via `...`. #' @param .opts (named `list()`)\cr #' List of options which are set before the `.f` is called. #' Options are reset to their previous state afterwards. #' @param .seed (`integer(1)`)\cr #' Random seed to set before invoking the function call. #' Gets reset to the previous seed on exit. #' @param .timeout (`numeric(1)`)\cr #' Timeout in seconds. Uses [setTimeLimit()]. Note that timeouts are only #' triggered on a user interrupt, not in compiled code. #' @export #' @examples #' invoke(mean, .args = list(x = 1:10)) #' invoke(mean, na.rm = TRUE, .args = list(1:10)) invoke = function(.f, ..., .args = list(), .opts = list(), .seed = NA_integer_, .timeout = Inf) { if (length(.opts)) { assert_list(.opts, names = "unique") old_opts = options(.opts) if (getRversion() < "3.6.0") { # fix for resetting some debug options # https://github.com/HenrikBengtsson/Wishlist-for-R/issues/88 nn = intersect(c("warnPartialMatchArgs", "warnPartialMatchAttr", "warnPartialMatchDollar"), names(old_opts)) nn = nn[map_lgl(old_opts[nn], is.null)] old_opts[nn] = FALSE } on.exit(options(old_opts), add = TRUE) } if (is.finite(assert_number(.timeout, lower = 0))) { setTimeLimit(elapsed = .timeout, transient = TRUE) on.exit(setTimeLimit(cpu = Inf, elapsed = Inf, transient = FALSE), add = TRUE) } if (!is.na(.seed)) { prev_seed = get_seed() on.exit(assign(".Random.seed", prev_seed, globalenv()), add = TRUE) set.seed(.seed) } call = match.call(expand.dots = FALSE) expr = as.call(c(list(call[[2L]]), call$..., .args)) eval.parent(expr, n = 1L) } mlr3misc/R/compute_mode.R0000644000176200001440000000160214455233002015004 0ustar liggesusers#' @title Compute The Mode #' #' @description #' Computes the mode (most frequent value) of an atomic vector. #' #' @param x (`vector()`). #' @param ties_method (`character(1)`)\cr #' Handling of ties. One of "first", "last" or "random" to return the first tied value, #' the last tied value, or a randomly selected tied value, respectively. #' @param na_rm (`logical(1)`)\cr #' If `TRUE`, remove missing values prior to computing the mode. #' @return (`vector(1)`): mode value. #' @export #' @examples #' compute_mode(c(1, 1, 1, 2, 2, 2, 3)) #' compute_mode(c(1, 1, 1, 2, 2, 2, 3), ties_method = "last") #' compute_mode(c(1, 1, 1, 2, 2, 2, 3), ties_method = "random") compute_mode = function(x, ties_method = "random", na_rm = TRUE) { assert_atomic_vector(x) if (na_rm) { x = x[!is.na(x)] } as.data.table(x)[, .N, by = list(x)][which_max(get("N"), ties_method = ties_method)]$x } mlr3misc/R/named_vector.R0000644000176200001440000000107414455233002014775 0ustar liggesusers#' @title Create a Named Vector #' #' @description #' Creates a simple atomic vector with `init` as values. #' #' @param nn (`character()`)\cr #' Names of new vector #' @param init (`atomic`)\cr #' All vector elements are initialized to this value. #' @return (named `vector()`). #' @export #' @examples #' named_vector(c("a", "b"), NA) #' named_vector(character()) named_vector = function(nn = character(0L), init = NA) { assert_character(nn, any.missing = FALSE) assert_atomic(init, len = 1L) res = rep(init, length.out = length(nn)) names(res) = nn res } mlr3misc/R/register_namespace_callback.R0000644000176200001440000000316415211524571020012 0ustar liggesusers#' @title Registers a Callback on Namespace load/unLoad Events #' #' @description #' Register a function `callback` to be called after a namespace is loaded. #' Calls `callback` once if the namespace has already been loaded before and #' also adds an unload-hook that removes the load hook. #' #' @param pkgname (`character(1)`)\cr #' Name of the package which registers the callback. #' @param namespace (`character(1)`)\cr #' Namespace to react on. #' @param callback (`function()`)\cr #' Function to call on namespace load. #' The callback is invoked without arguments, so it can be defined as `function()` or `function(...)`. #' Any arguments passed by the hook caller (e.g. `package` and `lib_path` from `pkgload`) are discarded. #' #' @return `NULL`. #' @export register_namespace_callback = function(pkgname, namespace, callback) { assert_string(pkgname) assert_string(namespace) assert_function(callback) load_hook = function(...) callback() remove_hook = function(event) { hooks = getHook(event) pkgnames = vapply( hooks, function(x) { ee = environment(x) if (isNamespace(ee)) environmentName(ee) else environment(x)$pkgname }, NA_character_ ) setHook(event, hooks[pkgnames != pkgname], action = "replace") } remove_hooks = function(...) { remove_hook(packageEvent(namespace, "onLoad")) remove_hook(packageEvent(pkgname, "onUnload")) } if (isNamespaceLoaded(namespace)) { callback() } setHook(packageEvent(namespace, "onLoad"), load_hook, action = "append") setHook(packageEvent(pkgname, "onUnload"), remove_hooks, action = "append") } mlr3misc/R/shuffle.R0000644000176200001440000000105614455233002013763 0ustar liggesusers#' @title Safe Version of Sample #' #' @description #' A version of `sample()` which does not treat positive scalar integer `x` differently. #' See example. #' #' @param x (`vector()`)\cr #' Vector to sample elements from. #' @param n (`integer()`)\cr #' Number of elements to sample. #' @param ... (`any`)\cr #' Arguments passed down to [base::sample.int()]. #' #' @export #' @examples #' x = 2:3 #' sample(x) #' shuffle(x) #' #' x = 3 #' sample(x) #' shuffle(x) shuffle = function(x, n = length(x), ...) { x[sample.int(length(x), size = n, ...)] } mlr3misc/R/dictionary_sugar.R0000644000176200001440000001600315170404765015706 0ustar liggesusers#' @title A Quick Way to Initialize Objects from Dictionaries #' #' @description #' Given a [Dictionary], retrieve objects with provided keys. #' * `dictionary_sugar_get()` to retrieve a single object with key `.key`. #' * `dictionary_sugar_mget()` to retrieve a list of objects with keys `.keys`. #' * `dictionary_sugar()` is deprecated in favor of `dictionary_sugar_get()`. #' * If `.key` or `.keys` is missing, the dictionary itself is returned. #' #' Arguments in `...` must be named and are consumed in the following order: #' #' 1. All arguments whose names match the name of an argument of the constructor #' are passed to the `$get()` method of the [Dictionary] for construction. #' 2. All arguments whose names match the name of a parameter of the [paradox::ParamSet] of the #' constructed object are set as parameters. If there is no [paradox::ParamSet] in `obj$param_set`, this #' step is skipped. #' 3. All remaining arguments are assumed to be regular fields of the constructed R6 instance, and #' are assigned via [`<-`]. #' #' @param dict ([Dictionary]). #' @param .key (`character(1)`)\cr #' Key of the object to construct. #' @param .keys (`character()`)\cr #' Keys of the objects to construct. #' @param ... (`any`)\cr #' See description. #' @param .dicts_suggest (named `list()`) #' Named list of [dictionaries][Dictionary] used to look up suggestions for `.key` if `.key` does not exist in `dict`. #' #' @return [R6::R6Class()] #' #' @examples #' library(R6) #' item = R6Class("Item", public = list(x = 0)) #' d = Dictionary$new() #' d$add("key", item) #' dictionary_sugar_get(d, "key", x = 2) #' #' @export dictionary_sugar_get = function(dict, .key, ..., .dicts_suggest = NULL) { assert_class(dict, "Dictionary") if (missing(.key)) { return(dict) } assert_string(.key) assert_list( .dicts_suggest, "Dictionary", any.missing = FALSE, min.len = 1, unique = TRUE, names = "named", null.ok = TRUE ) if (...length() == 0L) { return(dictionary_get(dict, .key, .dicts_suggest = .dicts_suggest)) } dots = assert_list(list(...), .var.name = "additional arguments passed to Dictionary") assert_list(dots[!is.na(names2(dots))], names = "unique", .var.name = "named arguments passed to Dictionary") obj = dictionary_retrieve_item(dict, .key, .dicts_suggest) if (length(dots) == 0L) { return(assert_r6(dictionary_initialize_item(.key, obj))) } # pass args to constructor and remove them constructor_args = get_constructor_formals(obj$value) ii = is.na(names2(dots)) | names2(dots) %in% constructor_args instance = assert_r6(dictionary_initialize_item(.key, obj, dots[ii])) dots = dots[!ii] # set params in ParamSet if (length(dots) && exists("param_set", envir = instance, inherits = FALSE)) { param_ids = instance$param_set$ids() ii = names(dots) %in% param_ids if (any(ii)) { instance$param_set$values = insert_named(instance$param_set$values, dots[ii]) dots = dots[!ii] } } else { param_ids = character() } # remaining args go into fields if (length(dots)) { ndots = names(dots) for (i in seq_along(dots)) { nn = ndots[[i]] if (!exists(nn, envir = instance, inherits = FALSE)) { stopf( "Cannot set argument '%s' for '%s' (not a constructor argument, not a parameter, not a field).%s", nn, class(instance)[1L], did_you_mean(nn, c(constructor_args, param_ids, setdiff(names(instance), ".__enclos_env__"))) ) } instance[[nn]] = dots[[i]] } } instance } #' @rdname dictionary_sugar_get #' @export dictionary_sugar = dictionary_sugar_get #' @rdname dictionary_sugar_get #' @export dictionary_sugar_mget = function(dict, .keys, ..., .dicts_suggest = NULL) { if (missing(.keys)) { return(dict) } objs = lapply(.keys, dictionary_sugar_get, dict = dict, .dicts_suggest = .dicts_suggest, ...) if (!is.null(names(.keys))) { nn = names2(.keys) ii = which(!is.na(nn)) for (i in ii) { objs[[i]]$id = nn[i] } } names(objs) = map_chr(objs, "id") objs } get_constructor_formals = function(x) { if (inherits(x, "R6ClassGenerator")) { # recursively search for class constructor while (is.null(x$public_methods$initialize)) { x = x$get_inherit() if (is.null(x)) { return(character()) } } return(names2(formals(x$public_methods$initialize))) } if (is.function(x)) { return(names2(formals(x))) } character() } fields = function(x) { c(setdiff(names(x$public_methods), c("initialize", "clone", "print", "format")), names(x$active)) } #' @title A Quick Way to Initialize Objects from Dictionaries with Incremented ID #' #' @description #' Convenience wrapper around [dictionary_sugar_get] and [dictionary_sugar_mget] to allow easier avoidance of ID #' clashes which is useful when the same object is used multiple times and the ids have to be unique. #' Let `` be the key of the object to retrieve. When passing the `_` to this #' function, where `` is any natural number, the object with key `` is retrieved and the #' suffix `_` is appended to the id after the object is constructed. #' #' @param dict ([Dictionary])\cr #' Dictionary from which to retrieve an element. #' @param .key (`character(1)`)\cr #' Key of the object to construct - possibly with a suffix of the form `_` which will be appended to the id. #' @param .keys (`character()`)\cr #' Keys of the objects to construct - possibly with suffixes of the form `_` which will be appended to the ids. #' @param ... (`any`)\cr #' See description of [mlr3misc::dictionary_sugar]. #' @param .dicts_suggest (named `list()`) #' Named list of [dictionaries][Dictionary] used to look up suggestions for `.key` if `.key` does not exist in `dict`. #' #' @return An element from the dictionary. #' #' @examples #' d = Dictionary$new() #' d$add("a", R6::R6Class("A", public = list(id = "a"))) #' d$add("b", R6::R6Class("B", public = list(id = "c"))) #' obj1 = dictionary_sugar_inc_get(d, "a_1") #' obj1$id #' #' obj2 = dictionary_sugar_inc_get(d, "b_1") #' obj2$id #' #' objs = dictionary_sugar_inc_mget(d, c("a_10", "b_2")) #' map(objs, "id") #' #' @export dictionary_sugar_inc_get = function(dict, .key, ..., .dicts_suggest = NULL) { m = regexpr("_\\d+$", .key) if (attr(m, "match.length") == -1L) { return(dictionary_sugar_get(dict = dict, .key = .key, ..., .dicts_suggest = .dicts_suggest)) } split = regmatches(.key, m, invert = NA)[[1L]] newkey = split[[1L]] suffix = split[[2L]] obj = dictionary_sugar_get(dict = dict, .key = newkey, ..., .dicts_suggest = .dicts_suggest) obj$id = paste0(obj$id, suffix) obj } #' @rdname dictionary_sugar_inc_get #' @export dictionary_sugar_inc_mget = function(dict, .keys, ..., .dicts_suggest = NULL) { objs = lapply(.keys, dictionary_sugar_inc_get, dict = dict, ..., .dicts_suggest = .dicts_suggest) if (!is.null(names(.keys))) { nn = names2(.keys) ii = which(!is.na(nn)) for (i in ii) { objs[[i]]$id = nn[i] } } names(objs) = map_chr(objs, "id") objs } mlr3misc/R/rcbind.R0000644000176200001440000000173115212054132013565 0ustar liggesusers#' @title Bind Columns by Reference #' #' @description #' Performs [base::cbind()] on [data.tables][data.table::data.table()], possibly by reference. #' #' @param x ([data.table::data.table()])\cr #' [data.table::data.table()] to add columns to. #' @param y ([data.table::data.table()])\cr #' [data.table::data.table()] to take columns from. #' #' @return ([data.table::data.table()]): Updated `x` . #' @export #' @examples #' x = data.table::data.table(a = 1:3, b = 3:1) #' y = data.table::data.table(c = runif(3)) #' rcbind(x, y) rcbind = function(x, y) { assert_data_table(x) assert_data_table(y) if (ncol(x) == 0L) { return(y) } if (ncol(y) == 0L) { return(x) } if (nrow(x) != nrow(y)) { stopf("Tables have different number of rows (x: %i, y: %i)", nrow(x), nrow(y)) } nn = names(y) dup = nn[nn %in% names(x)] if (length(dup)) { stopf("Duplicated names: %s", str_collapse(dup)) } # nolint next ..y = NULL x[, (nn) := ..y][] } mlr3misc/R/with_package.R0000644000176200001440000000173415147263543014774 0ustar liggesusers#' @title Execute code with a modified search path #' #' @description #' Attaches a package to the search path (if not already attached), executes code and #' eventually removes the package from the search path again, restoring the previous state. #' #' Note that this function is deprecated in favor of the (now fixed) version in \CRANpkg{withr}. #' #' @param package (`character(1)`)\cr #' Name of the package to attach. #' @param code (`expression`)\cr #' Code to run. #' @param ... (`any`)\cr #' Additional arguments passed to [library()]. #' @return Result of the evaluation of `code`. #' @seealso \CRANpkg{withr} package. #' @export with_package = function(package, code, ...) { is_attached = package %in% .packages() if (!is_attached) { suppressPackageStartupMessages({ get("library")(package, warn.conflicts = FALSE, character.only = TRUE, quietly = TRUE, ...) }) on.exit(detach(paste0("package:", package), character.only = TRUE)) } force(code) } mlr3misc/R/require_namespaces.R0000644000176200001440000000255715170404765016224 0ustar liggesusers#' @title Require Multiple Namespaces #' #' @description #' Packages are loaded (not attached) via [base::requireNamespace()]. #' If at least one package can not be loaded, an exception of class "packageNotFoundError" is raised. #' The character vector of missing packages is stored in the condition as `packages`. #' #' @param pkgs (`character()`)\cr #' Packages to load. #' @param msg (`character(1)`)\cr #' Message to print on error. Use `"%s"` as placeholder for the list of packages. #' @param quietly (`logical(1)`)\cr #' If `TRUE` then returns `TRUE` if all packages are loaded, otherwise `FALSE`. #' #' #' @return (`character()`) of loaded packages (invisibly). #' @export #' @examples #' require_namespaces("mlr3misc") #' #' # catch condition, return missing packages #' tryCatch(require_namespaces(c("mlr3misc", "foobaaar")), #' packageNotFoundError = function(e) e$packages) require_namespaces = function(pkgs, msg = "The following packages could not be loaded: %s", quietly = FALSE) { pkgs = unique(assert_character(pkgs, any.missing = FALSE)) ii = which(!map_lgl(pkgs, requireNamespace, quietly = TRUE)) if (length(ii)) { if (quietly) { return(FALSE) } msg = sprintf(msg, toString(pkgs[ii])) stop(errorCondition(msg, packages = pkgs[ii], class = "packageNotFoundError")) } else if (quietly) { TRUE } else { invisible(pkgs) } } mlr3misc/R/rowwise_table.R0000644000176200001440000000253415156722625015214 0ustar liggesusers#' @title Row-Wise Constructor for 'data.table' #' #' @description #' Similar to the \CRANpkg{tibble} function `tribble()`, this function #' allows to construct tabular data in a row-wise fashion. #' #' The first arguments passed as formula will be interpreted as column names. #' The remaining arguments will be put into the resulting table. #' #' @param ... (`any`)\cr #' Arguments: Column names in first rows as formulas (with empty left hand side), #' then the tabular data in the following rows. #' @param .key (`character(1)`)\cr #' If not `NULL`, set the key via [data.table::setkeyv()] after constructing the #' table. #' #' @return [data.table::data.table()]. #' @export #' @examples #' rowwise_table( #' ~a, ~b, #' 1, "a", #' 2, "b" #' ) rowwise_table = function(..., .key = NULL) { dots = list(...) for (i in seq_along(dots)) { if (!inherits(dots[[i]], "formula")) { ncol = i - 1L break } } if (ncol == 0L) { stop("No column names provided") } n = length(dots) - ncol if (n %% ncol != 0L) { stop("Data is not rectangular") } tab = lapply(seq_len(ncol), function(i) simplify2array(dots[seq(from = ncol + i, to = length(dots), by = ncol)])) tab = setnames(setDT(tab), map_chr(head(dots, ncol), function(x) attr(terms(x), "term.labels"))) if (!is.null(.key)) { setkeyv(tab, .key) } tab } mlr3misc/R/modify.R0000644000176200001440000000302614455233002013615 0ustar liggesusers#' @title Selectively Modify Elements of a Vector #' #' @description #' Modifies elements of a vector selectively, similar to the functions in \CRANpkg{purrr}. #' #' `modify_if()` applies a predicate function `.p` to all elements of `.x` #' and applies `.f` to those elements of `.x` where `.p` evaluates to `TRUE`. #' #' `modify_at()` applies `.f` to those elements of `.x` selected via `.at`. #' #' @param .x (`vector()`). #' @param .p (`function()`)\cr #' Predicate function. #' @param .f (`function()`)\cr #' Function to apply on `.x`. #' @param .at ((`integer()` | `character()`))\cr #' Index vector to select elements from `.x`. #' @param ... (`any`)\cr #' Additional arguments passed to `.f`. #' @export #' @examples #' x = modify_if(iris, is.factor, as.character) #' str(x) #' #' x = modify_at(iris, 5, as.character) #' x = modify_at(iris, "Sepal.Length", sqrt) #' str(x) modify_if = function(.x, .p, .f, ...) { UseMethod("modify_if") } #' @export modify_if.default = function(.x, .p, .f, ...) { sel = probe(.x, .p) .x[sel] = map(.x[sel], .f, ...) .x } #' @export modify_if.data.table = function(.x, .p, .f, ...) { sel = names(which(probe(.x, .p))) .x[, (sel) := lapply(.SD, .f, ...), .SDcols = sel][] } #' @export #' @rdname modify_if modify_at = function(.x, .at, .f, ...) { UseMethod("modify_at") } #' @export modify_at.default = function(.x, .at, .f, ...) { .x[.at] = map(.x[.at], .f, ...) .x } #' @export modify_at.data.table = function(.x, .at, .f, ...) { .x[, (.at) := lapply(.SD, .f, ...), .SDcols = .at][] } mlr3misc/R/leanify.R0000644000176200001440000001176515156722625014003 0ustar liggesusers#' @title Leanifies a Method #' #' @description #' Moves a single method of an R6Class Generator to its package namespace. #' The R6Class's method is reduced to a call to the moved function. #' #' This creates a function named `.____` inside `env`. #' #' leanificate_method is called by [leanify_r6] for each function of an [R6] class. #' #' Leanification also removes the `"srcref"` attribute of functions (sets it to `NULL`), because #' 1) it is incorrect and #' 2) srcrefs can lead to exploding object sizes. #' #' However, because `roxygen2` needs the srcrefs to create the documentation for R6 classes, leanification #' is skipped during `roxygenize()`, i.e. when the `ROXYGEN_PKG` environment variable is set. #' #' @param cls (`R6ClassGenerator`)\cr #' R6Class object (i.e. R6 object generator) to modify. #' @param name (`character(1)`)\cr #' Name of the function #' @param env (`environment`)\cr #' The target environment where the function should be stored. #' Should be either `cls$parent_env` or one of its parent environments, #' otherwise the stump function will not find the moved (original code) function. #' @return NULL #' @noRd leanificate_method = function(cls, fname, env = cls$parent_env) { cname = cls$classname # find out where the function is stored: public, private, active. This is also # relevant for the `cls$set()` call at the end: we need to set the function to # the right protection kind as it was before. for (function_kind_container in c("public_methods", "private_methods", "active")) { fn = cls[[function_kind_container]][[fname]] if (!is.null(fn)) break } if (is.null(fn)) { stop(sprintf("Could not find function %s in class %s", fname, cname)) } exportfname = sprintf(".__%s__%s", cname, fname) origformals = formals(fn) origattributes = attributes(fn) formals(fn) = c(pairlist(self = substitute(), private = substitute(), super = substitute()), formals(fn)) attributes(fn) = origattributes assign(exportfname, fn, env) replacingfn = eval(call( "function", origformals, as.call(c(list(as.symbol(exportfname)), sapply(names(formals(fn)), as.symbol, simplify = FALSE))) )) environment(replacingfn) = environment(fn) function_kind = switch( function_kind_container, public_methods = "public", private_methods = "private", active = "active" ) # We remove the srcref (which exists when installing with option --with-keep.source) because: # (1) incorrect rendering of leanified functions # (2) use up memory unnecessarily origattributes$srcref = NULL attributes(replacingfn) = origattributes cls$set(function_kind, fname, replacingfn, overwrite = TRUE) } #' @title Move all methods of an R6 Class to an environment #' #' @description #' `leanify_r6` moves the content of an [`R6::R6Class`]'s functions to an environment, #' usually the package's namespace, to save space during serialization of R6 objects. #' `leanify_package` move all methods of *all* R6 Classes to an environment. #' #' The function in the class (i.e. the object generator) is replaced by a stump #' function that does nothing except calling the original function that now resides #' somewhere else. #' #' It is possible to call this function after the definition of an [R6::R6] #' class inside a package, but it is preferred to use [leanify_package()] #' to just leanify all [R6::R6] classes inside a package. #' #' @param cls ([R6::R6Class])\cr #' Class generator to modify. #' @param env (`environment`)\cr #' The target environment where the function should be stored. #' This should be either `cls$parent_env` (default) or one of its #' parent environments, otherwise the stump function will not find the moved #' (original code) function. #' @return `NULL`. #' @export leanify_r6 = function(cls, env = cls$parent_env) { assert_class(cls, "R6ClassGenerator") assert_environment(env) for (assignwhich in c("public_methods", "private_methods", "active")) { for (fname in names(cls[[assignwhich]])) { leanificate_method(cls, fname, env = env) } } } #' @rdname leanify_r6 #' #' @param pkg_env :: `environment`\cr #' The namespace from which to leanify all R6 classes. Does not have to be a #' package namespace, but this is the intended usecase. #' @param skip_if :: `function`\cr #' Function with one argument: Is called for each individual [`R6::R6Class`]. #' If it returns `TRUE`, the class is skipped. Default function evaluating to `FALSE` #' always (i.e. skipping no classes). #' @export leanify_package = function(pkg_env = parent.frame(), skip_if = function(x) FALSE) { assert_environment(pkg_env) assert_function(skip_if) # otherwise creation of R6 docs fails pkg = Sys.getenv("ROXYGEN_PKG") if (nzchar(pkg)) { messagef("Skipping leanification of package '%s' during roxygenize.", pkg) return(NULL) } for (varname in names(pkg_env)) { content = get(varname, envir = pkg_env, inherits = FALSE) if (R6::is.R6Class(content) && !isTRUE(skip_if(content))) { leanify_r6(content) } } } mlr3misc/R/probe.R0000644000176200001440000000022114455233002013427 0ustar liggesusersprobe = function(.x, .p, ...) { if (is.logical(.p)) { stopifnot(length(.p) == length(.x)) .p } else { map_lgl(.x, .p, ...) } } mlr3misc/R/transpose.R0000644000176200001440000000123314455233002014342 0ustar liggesusers#' @title Transpose lists of lists #' #' @description #' Transposes a list of list, and turns it inside out, similar to the #' function `transpose()` in package \CRANpkg{purrr}. #' #' @param .l (`list()` of `list()`). #' #' @return `list()`. #' @export #' @examples #' x = list(list(a = 2, b = 3), list(a = 5, b = 10)) #' str(x) #' str(transpose_list(x)) #' #' # list of data frame rows: #' transpose_list(iris[1:2, ]) transpose_list = function(.l) { assert(check_list(.l), check_data_frame(.l)) if (length(.l) == 0L) { return(list()) } res = .mapply(list, .l, list()) if (length(res) == length(.l[[1L]])) { names(res) = names(.l[[1L]]) } res } mlr3misc/R/unnest.R0000644000176200001440000000367715212054132013653 0ustar liggesusers#' @title Unnest List Columns #' #' @description #' Transforms list columns to separate columns, possibly by reference. #' The original columns are removed from the returned table. #' All non-atomic objects in the list columns are expanded to new list columns. #' #' @param x ([data.table::data.table()])\cr #' [data.table::data.table()] with columns to unnest. #' @param cols (`character()`)\cr #' Column names of list columns to operate on. #' @param prefix (`logical(1)` | `character(1)`)\cr #' String to prefix the new column names with. #' Use `"{col}"` (without the quotes) as placeholder for the original column name. #' #' @return ([data.table::data.table()]). #' @export #' @examples #' x = data.table::data.table( #' id = 1:2, #' value = list(list(a = 1, b = 2), list(a = 2, b = 2)) #' ) #' print(x) #' unnest(data.table::copy(x), "value") #' unnest(data.table::copy(x), "value", prefix = "{col}.") unnest = function(x, cols, prefix = NULL) { assert_data_table(x) assert_subset(cols, names(x)) assert_string(prefix, null.ok = TRUE) for (col in intersect(cols, names(x))) { values = x[[col]] if (!is.list(values)) { next } tmp = rbindlist2(values) if (!is.null(prefix)) { setnames(tmp, paste0(gsub("{col}", col, prefix, fixed = TRUE), names(tmp))) } # rcbind checks for duplicated column names x = rcbind(remove_named(x, col), tmp) } x[] } rbindlist2 = function(values) { new_cols = rbindlist( lapply(values, function(row) { n = lengths(row) # to preserve the row, we need at least one value if (all(n == 0L)) { return(list("__rbindlist2_dummy__" = NA)) } # wrap non-atomics or multi-element atomics into an extra list ii = which(!map_lgl(row, is.atomic) | n > 1L) if (length(ii)) { row[ii] = lapply(row[ii], list) } row }), fill = TRUE, use.names = TRUE ) remove_named(new_cols, "__rbindlist2_dummy__") } mlr3misc/R/nin.R0000644000176200001440000000051414455233002013111 0ustar liggesusers#' @title Negated in-operator #' #' @description #' This operator is equivalent to `!(x %in% y)`. #' #' @param x (`vector()`)\cr #' Values that should not be in `y`. #' @param y (`vector()`)\cr #' Values to match against. #' @usage x \%nin\% y #' @rdname nin #' @export "%nin%" = function(x, y) { !match(x, y, nomatch = 0L) } mlr3misc/R/topo_sort.R0000644000176200001440000000476715170404762014403 0ustar liggesusers#' @title Topological Sorting of Dependency Graphs #' #' @description #' Topologically sort a graph, where we are passed node labels and a list of direct #' parents for each node, as labels, too. #' A node can be 'processed' if all its parents have been 'processed', #' and hence occur at previous indices in the resulting sorting. #' Returns a table, in topological row order for IDs, and an entry `depth`, #' which encodes the topological layer, starting at 0. #' So nodes with `depth == 0` are the ones with no dependencies, #' and the one with maximal `depth` are the ones on which nothing else depends on. #' #' @param nodes ([data.table::data.table()])\cr #' Has 2 columns: #' * `id` of type `character`, contains all node labels. #' * `parents` of type `list` of `character`, contains all direct parents label of `id`. #' #' @return ([data.table::data.table()]) with columns `id`, `depth`, sorted topologically for IDs. #' @export #' @examples #' nodes = rowwise_table( #' ~id, ~parents, #' "a", "b", #' "b", "c", #' "c", character() #' ) #' topo_sort(nodes) topo_sort = function(nodes) { assert_data_table(nodes, ncols = 2L, types = c("character", "list")) assert_names(names(nodes), identical.to = c("id", "parents")) assert_list(nodes$parents, types = "character") assert_subset(unlist(nodes$parents, use.names = FALSE), nodes$id) nodes = copy(nodes) # copy ref to be sure n = nrow(nodes) # sort nodes with few parent to start nodes = nodes[order(lengths(get("parents")), decreasing = FALSE)] nodes[, `:=`(topo = NA_integer_, depth = NA_integer_)] # cols for topo-index and depth layer in sort j = 1L topo_count = 1L depth_count = 0L while (topo_count <= n) { # if element is not sorted and has no deps (anymore), we sort it in if (is.na(nodes$topo[j]) && length(nodes$parents[[j]]) == 0L) { set(nodes, i = j, j = "topo", value = topo_count) topo_count = topo_count + 1L set(nodes, i = j, j = "depth", value = depth_count) } j = (j %% n) + 1L # inc j, but wrap around end if (j == 1L) { # we wrapped, lets remove nodes of current layer from deps layer = nodes[list(depth_count), "id", on = "depth", nomatch = NULL][[1L]] if (length(layer) == 0L) { stop("Cycle detected, this is not a DAG!") } set(nodes, i = NULL, j = "parents", value = map(nodes$parents, function(x) setdiff(x, layer))) depth_count = depth_count + 1L } } nodes[order(get("topo")), c("id", "depth")] # sort by topo, and then remove topo-col } mlr3misc/R/formulate.R0000644000176200001440000000261715156722625014346 0ustar liggesusers#' @title Create Formulas #' #' @description #' Given the left-hand side and right-hand side as character vectors, generates a new #' [stats::formula()]. #' #' @param lhs (`character()`)\cr #' Left-hand side of formula. Multiple elements will be collapsed with `" + "`. #' @param rhs (`character()`)\cr #' Right-hand side of formula. Multiple elements will be collapsed with `" + "`. #' @param env (`environment()`)\cr #' Environment for the new formula. Defaults to `NULL`. #' @param quote (`character(1)`)\cr #' Which side of the formula to quote? #' Subset of `("left", "right")`, defaulting to `"right"`. #' @return [stats::formula()]. #' @export #' @examples #' formulate("Species", c("Sepal.Length", "Sepal.Width")) #' formulate(rhs = c("Sepal.Length", "Sepal.Width")) formulate = function(lhs = character(), rhs = character(), env = NULL, quote = "right") { assert_subset(quote, choices = c("left", "right")) lhs = as.character(lhs, any.missing = FALSE) rhs = as.character(rhs, any.missing = FALSE) if (length(lhs) == 0L) { lhs = "" } else if ("left" %in% quote) { lhs = paste0("`", lhs, "`") } if (length(rhs) == 0L) { rhs = "1" } else if ("right" %in% quote && !identical(rhs, ".") && !identical(rhs, "1")) { rhs = paste0("`", rhs, "`") } f = as.formula(sprintf("%s ~ %s", paste0(lhs, collapse = " + "), paste0(rhs, collapse = " + "))) environment(f) = env f } mlr3misc/R/extract_vars.R0000644000176200001440000000112314455233002015027 0ustar liggesusers#' @title Extract Variables from a Formula #' #' @description #' Given a [formula()] `f`, returns all variables used on the left-hand side and #' right-hand side of the formula. #' #' @param f (`formula()`). #' #' @return (`list()`) with elements `"lhs"` and `"rhs"`, both `character()`. #' @export #' @examples #' extract_vars(Species ~ Sepal.Width + Sepal.Length) #' extract_vars(Species ~ .) extract_vars = function(f) { assert_formula(f) res = named_list(c("lhs", "rhs")) res$lhs = if (length(f) == 2L) character(0L) else all.vars(f[[2L]]) res$rhs = all.vars(f[[length(f)]]) res } mlr3misc/R/assert_ro_binding.R0000644000176200001440000000070614731230564016032 0ustar liggesusers#' @title Assertion for Active Bindings in R6 Classes #' #' @description #' This assertion is intended to be called in active bindings of an #' [R6::R6Class] which does not allow assignment. #' If `rhs` is not missing, an exception is raised. #' #' @param rhs (`any`)\cr #' If not missing, an exception is raised. #' #' @return Nothing. #' @export assert_ro_binding = function(rhs) { if (!missing(rhs)) { stop("Field/Binding is read-only") } } mlr3misc/R/get_private.R0000644000176200001440000000260014731230564014643 0ustar liggesusers#' @title Extract Private Fields of R6 Objects #' #' @description #' Provides access to the private members of [R6::R6Class] objects. #' #' @param x (`any`)\cr #' Object to extract the private members from. #' #' @return `environment()` of private members, or `NULL` if `x` is not an R6 object. #' @export #' @examples #' library(R6) #' item = R6Class("Item", private = list(x = 1))$new() #' get_private(item)$x get_private = function(x) { if (!inherits(x, "R6")) { return(NULL) } x[[".__enclos_env__"]][["private"]] } #' @title Assign Value to Private Field #' #' @description #' Convenience function to assign a value to a private field of an [R6::R6Class] instance. #' #' @param x (`any`)\cr #' Object whose private field should be modified. #' @param which (character(1))\cr #' Private field that is being modified. #' @param value (`any`)\cr #' Value to assign to the private field. #' #' @return The R6 instance x, modified in-place. If it is not an R6 instance, NULL is returned. #' @export #' @examples #' library(R6) #' item = R6Class("Item", private = list(x = 1))$new() #' get_private(item)$x #' get_private(item, "x") = 2L #' get_private(item)$x `get_private<-` = function(x, which, value) { if (!inherits(x, "R6")) { return(NULL) } assert_character(which, len = 1L, any.missing = FALSE, min.chars = 1L) x[[".__enclos_env__"]][["private"]][[which]] = value x } mlr3misc/R/named_list.R0000644000176200001440000000075315170404765014464 0ustar liggesusers#' @title Create a Named List #' #' @param nn (`character()`)\cr #' Names of new list. #' @param init (`any`)\cr #' All list elements are initialized to this value. #' @return (named `list()`). #' @export #' @examples #' named_list(c("a", "b")) #' named_list(c("a", "b"), init = 1) named_list = function(nn = character(0L), init = NULL) { assert_character(nn, any.missing = FALSE) x = vector("list", length(nn)) if (!is.null(init)) { x[] = list(init) } names(x) = nn x } mlr3misc/R/which_max.R0000644000176200001440000000271014455233002014274 0ustar liggesusers#' @title Index of the Minimum/Maximum Value, with Correction for Ties #' #' @description #' Works similar to [base::which.min()]/[base::which.max()], but corrects for ties. #' Missing values are treated as `Inf` for `which_min` and as `-Inf` for `which_max()`. #' #' @param x (`numeric()`)\cr #' Numeric vector. #' @param ties_method (`character(1)`)\cr #' Handling of ties. One of "first", "last" or "random" (default) to return the first index, #' the last index, or a random index of the minimum/maximum values. #' @param na_rm (`logical(1)`)\cr #' Remove NAs before computation? #' #' @return (`integer()`): Index of the minimum/maximum value. #' Returns an empty integer vector for empty input vectors and vectors with no non-missing values #' (if `na_rm` is `TRUE`). #' Returns `NA` if `na_rm` is `FALSE` and at least one `NA` is found in `x`. #' @export #' @examples #' x = c(2, 3, 1, 3, 5, 1, 1) #' which_min(x, ties_method = "first") #' which_min(x, ties_method = "last") #' which_min(x, ties_method = "random") #' #' which_max(x) #' which_max(integer(0)) #' which_max(NA) #' which_max(c(NA, 1)) which_min = function(x, ties_method = "random", na_rm = FALSE) { x = if (is.logical(x)) !x else -x which_max(x, ties_method, na_rm) } #' @rdname which_min #' @useDynLib mlr3misc c_which_max #' @export which_max = function(x, ties_method = "random", na_rm = FALSE) { assert_flag(na_rm) .Call(c_which_max, x, ties_method, na_rm, PACKAGE = "mlr3misc") } mlr3misc/R/insert_named.R0000644000176200001440000000351715170404765015016 0ustar liggesusers#' @title Insert or Remove Named Elements #' #' @description #' Insert elements from `y` into `x` by name, or remove elements from `x` by name. #' Works for vectors, lists, environments and data frames and data tables. #' Objects with reference semantic (`environment()` and [data.table::data.table()]) might be modified in-place. #' #' @param x (`vector()` | `list()` | `environment()` | [data.table::data.table()])\cr #' Object to insert elements into, or remove elements from. #' Changes are by-reference for environments and data tables. #' @param y (`list()`)\cr #' List of elements to insert into `x`. #' @param nn (`character()`)\cr #' Character vector of elements to remove. #' #' @return Modified object. #' @export #' @examples #' x = list(a = 1, b = 2) #' insert_named(x, list(b = 3, c = 4)) #' remove_named(x, "b") insert_named = function(x, y) { if (length(y) == 0L) { return(x) } assert_names(names(y), type = "unique") UseMethod("insert_named") } #' @export #' @rdname insert_named insert_named.NULL = function(x, y) { if (!test_named(y)) { stopf("insert_named(NULL, y) failed: 'y' is unnamed") } y } #' @export #' @rdname insert_named insert_named.default = function(x, y) { assert_vector(x, names = "unique") x[names(y)] = y x } #' @export #' @rdname insert_named insert_named.environment = function(x, y) { for (nn in names(y)) { assign(nn, y[[nn]], envir = x) } x } #' @export #' @rdname insert_named insert_named.data.frame = function(x, y) { if (ncol(x) > 0L) { x[names(y)] = as.list(y) as.data.frame(x) } else { as.data.frame(y) } } #' @export #' @rdname insert_named insert_named.data.table = function(x, y) { if (ncol(x) > 0L) { # nolint next ..y = y x[, names(..y) := ..y][] } else { # null data.table, we cannot assign with `:=` as.data.table(y) } } mlr3misc/R/did_you_mean.R0000644000176200001440000000703615156722625015004 0ustar liggesusers#' @title Suggest Alternatives #' #' @description #' Helps to suggest alternatives from a list of strings, based on the string similarity in [utils::adist()]. #' #' @param str (`character(1)`)\cr #' String. #' @param candidates (`character()`)\cr #' Candidate strings. #' @return (`character(1)`). Either a phrase suggesting one or more candidates from `candidates`, #' or an empty string if no close match is found. #' @export #' @examples #' did_you_mean("yep", c("yes", "no")) did_you_mean = function(str, candidates) { suggestions = find_suggestions(str, candidates, threshold = 0.2, max_candidates = 3L, ret_distances = FALSE) if (!length(suggestions)) { return("") } sprintf(" Did you mean %s?", str_collapse(suggestions, quote = "'", sep = " / ")) } # @title Suggest Alternatives from Given Dictionaries # # @description # Helps to suggest alternatives for a given key based on the keys of given dictionaries. # # @param key (`character(1)`) \cr # Key to look for in `dicts`. # @param dicts (named `list()`)\cr # Named list of [dictionaries][Dictionary]. # @param max_candidates_dicts (`integer(1)`) \cr # Maximum number of dictionaries for which suggestions are outputted. # @return (`character(1)`). Either a phrase suggesting one or more keys based on the dictionaries in `dicts`, # or an empty string if no close match is found. did_you_mean_dicts = function(key, dicts, max_candidates_dicts = 3L) { # No message if no dictionaries are given if (is.null(dicts)) { return("") } suggestions = character(0) min_distance_per_dict = numeric(0) for (i in seq_along(dicts)) { # Get distances and the corresponding entries for the current dictionary distances = find_suggestions(key, dicts[[i]]$keys(), ret_distances = TRUE) entries = names(distances) # Handle the case of no matches: skip the dictionary if (!length(entries)) { next } # Record the closest distance min_distance_per_dict[[length(min_distance_per_dict) + 1]] = min(distances) # Create a suggestion message for the current dictionary suggestions[[length(suggestions) + 1]] = sprintf( "%s: %s", names(dicts)[[i]], str_collapse(entries, quote = "'", sep = " / ") ) } # Order the suggestions by their closest match suggestions = suggestions[order(min_distance_per_dict)] # Only show the 3 dictionaries with the best matches suggestions = head(suggestions, max_candidates_dicts) # If no valid suggestions, return an empty string if (!length(suggestions)) { return("") } # add \n sprintf("\nSimilar entries in other dictionaries:\n %s", str_collapse(suggestions, sep = "\n ")) } # @title Find Suggestions # # @param str (`character(1)`)\cr # String. # @param candidates (`character()`)\cr # Candidate strings. # @param threshold (`numeric(1)`)\cr # Percentage value of characters when sorting `candidates` by distance # @param max_candidates (`integer(1)`)\cr # Maximum number of candidates to return. # @param ret_similarity (`logical(1)`)\cr # Return similarity values instead of names. # @return (`character(1)`). Either suggested candidates from `candidates` or an empty string if no close match is found. find_suggestions = function(str, candidates, threshold = 0.2, max_candidates = 3L, ret_distances = FALSE) { candidates = unique(candidates) D = set_names(adist(str, candidates, ignore.case = TRUE, partial = TRUE)[1L, ], candidates) sorted = head(sort(D[D <= ceiling(threshold * nchar(str))]), max_candidates) if (ret_distances) { sorted } else { names(sorted) } } mlr3misc/R/enframe.R0000644000176200001440000000245214455233002013745 0ustar liggesusers#' @title Convert a Named Vector into a data.table and Vice Versa #' #' @description #' `enframe()` returns a [data.table::data.table()] with two columns: #' The names of `x` (or `seq_along(x)` if unnamed) and the values of `x`. #' #' `deframe()` converts a two-column data.frame to a named vector. #' If the data.frame only has a single column, an unnamed vector is returned. #' #' #' @param x (`vector()` (`enframe()`) or `data.frame()` (`deframe()`))\cr #' Vector to convert to a [data.table::data.table()]. #' @param name (`character(1)`)\cr #' Name for the first column with names. #' @param value (`character(1)`)\cr #' Name for the second column with values. #' #' @return [data.table::data.table()] or named `vector`. #' @export #' @examples #' x = 1:3 #' enframe(x) #' #' x = set_names(1:3, letters[1:3]) #' enframe(x, value = "x_values") enframe = function(x, name = "name", value = "value") { if (is.environment(x)) { x = as.list(x) } dt = data.table(names(x) %??% seq_along(x), unname(x)) setnames(dt, c(name, value))[] } #' @rdname enframe #' @export deframe = function(x) { assert_data_frame(x) nc = ncol(x) if (nc == 1L) { x[[1L]] } else if (nc == 2L) { setNames(x[[2L]], x[[1L]]) } else { stopf("Data frame must have 1 or 2 columns, but has %i columns", nc) } } mlr3misc/R/purrr_map.R0000644000176200001440000002403015170404765014346 0ustar liggesusers#' @title Apply Functions in the spirit of 'purrr' #' #' @description #' `map`-like functions, similar to the ones implemented in \CRANpkg{purrr}: #' #' * `map()` returns the results of `.f` applied to `.x` as list. #' If `.f` is not a function, `map` will call `[[` on all elements of `.x` using the value of `.f` as index. #' * `imap()` applies `.f` to each value of `.x` (passed as first argument) and its name (passed as second argument). #' If `.x` does not have names, a sequence along `.x` is passed as second argument instead. #' * `pmap()` expects `.x` to be a list of vectors of equal length, and then applies `.f` to the first element of #' each vector of `.x`, then the second element of `.x`, and so on. #' * `map_if()` applies `.f` to each element of `.x` where the predicate `.p` evaluates to `TRUE`. #' * `map_at()` applies `.f` to each element of `.x` referenced by `.at`. All other elements remain unchanged. #' * `keep()` keeps those elements of `.x` where predicate `.p` evaluates to `TRUE`. #' * `discard()` discards those elements of `.x` where predicate `.p` evaluates to `TRUE`. #' * `compact()` discards elements of `.x` that are `NULL`. #' * `every()` is `TRUE` if predicate `.p` evaluates to `TRUE` for each `.x`. #' * `some()` is `TRUE` if predicate `.p` evaluates to `TRUE` for at least one `.x`. #' * `detect()` returns the first element where predicate `.p` evaluates to `TRUE`. #' * `walk()`, `iwalk()` and `pwalk()` are the counterparts to `map()`, `imap()` and `pmap()`, but #' just visit (or change by reference) the elements of `.x`. They return input `.x` invisibly. #' #' #' Additionally, the functions `map()`, `imap()` and `pmap()` have type-safe variants with the following suffixes: #' #' * `*_lgl()` returns a `logical(length(.x))`. #' * `*_int()` returns a `integer(length(.x))`. #' * `*_dbl()` returns a `double(length(.x))`. #' * `*_chr()` returns a `character(length(.x))`. #' * `*_br()` returns an object where the results of `.f` are put together with [base::rbind()]. #' * `*_bc()` returns an object where the results of `.f` are put together with [base::cbind()]. #' * `*_dtr()` returns a [data.table::data.table()] where the results of `.f` are put together #' in an [base::rbind()] fashion. #' * `*_dtc()` returns a [data.table::data.table()] where the results of `.f` are put #' together in an [base::cbind()] fashion. #' #' @param .x (`list()` | atomic `vector()`). #' @param .f (`function()` | `character()` | `integer()`)\cr #' Function to apply, or element to extract by name (if `.f` is `character()`) or position (if `.f` is `integer()`). #' @param .p (`function()` | `logical()`)\cr #' Predicate function. #' @param .at (`character()` | `integer()` | `logical()`)\cr #' Index vector. #' @param ... (`any`)\cr #' Additional arguments passed down to `.f` or `.p`. #' @param .fill (`logical(1)`)\cr #' Passed down to [data.table::rbindlist()]. #' @param .idcol (`logical(1)`)\cr #' Passed down to [data.table::rbindlist()]. #' #' @name compat-map NULL #' @export #' @rdname compat-map map = function(.x, .f, ...) { if (is.function(.f)) { lapply(.x, .f, ...) } else { lapply(.x, `[[`, .f, ...) } } map_mold = function(.x, .f, .value, ...) { out = if (is.function(.f)) { vapply(.x, .f, FUN.VALUE = .value, USE.NAMES = FALSE, ...) } else { vapply(.x, `[[`, .f, FUN.VALUE = .value, USE.NAMES = FALSE, ...) } setNames(out, names(.x)) } mapply_list = function(.f, .dots, .args = list()) { # assertions to avoid segfault (#56) assert_function(.f) assert_list(.args) stopifnot(is.list(.dots)) # also allow data.frame alike objects .mapply(.f, .dots, .args) } #' @export #' @rdname compat-map map_lgl = function(.x, .f, ...) { map_mold(.x, .f, NA, ...) } #' @export #' @rdname compat-map map_int = function(.x, .f, ...) { map_mold(.x, .f, NA_integer_, ...) } #' @export #' @rdname compat-map map_dbl = function(.x, .f, ...) { map_mold(.x, .f, NA_real_, ...) } #' @export #' @rdname compat-map map_chr = function(.x, .f, ...) { map_mold(.x, .f, NA_character_, ...) } #' @export #' @rdname compat-map map_br = function(.x, .f, ...) { do.call(rbind, map(.x, .f, ...)) } #' @export #' @rdname compat-map map_bc = function(.x, .f, ...) { do.call(cbind, map(.x, .f, ...)) } #' @export #' @rdname compat-map map_dtr = function(.x, .f, ..., .fill = FALSE, .idcol = NULL) { rbindlist(unname(map(.x, .f, ...)), use.names = TRUE, fill = .fill, idcol = .idcol) } #' @export #' @rdname compat-map map_dtc = function(.x, .f, ...) { cols = map(.x, .f, ...) j = map_lgl(cols, function(x) !is.null(dim(x)) && !is.null(colnames(x))) names(cols)[j] = "" do.call(data.table, c(cols, list(check.names = TRUE))) } #' @export #' @rdname compat-map pmap = function(.x, .f, ...) { mapply_list(.f, .x, list(...)) } #' @export #' @rdname compat-map pmap_lgl = function(.x, .f, ...) { out = mapply_list(.f, .x, list(...)) tryCatch(as.vector(out, "logical"), warning = function(w) stop("Cannot convert to logical")) } #' @export #' @rdname compat-map pmap_int = function(.x, .f, ...) { out = mapply_list(.f, .x, list(...)) tryCatch(as.vector(out, "integer"), warning = function(w) stop("Cannot convert to integer")) } #' @export #' @rdname compat-map pmap_dbl = function(.x, .f, ...) { out = mapply_list(.f, .x, list(...)) tryCatch(as.vector(out, "double"), warning = function(w) stop("Cannot convert to double")) } #' @export #' @rdname compat-map pmap_chr = function(.x, .f, ...) { out = mapply_list(.f, .x, list(...)) tryCatch(as.vector(out, "character"), warning = function(w) stop("Cannot convert to character")) } #' @export #' @rdname compat-map pmap_dtr = function(.x, .f, ..., .fill = FALSE, .idcol = NULL) { out = mapply_list(.f, .x, list(...)) rbindlist(out, use.names = TRUE, fill = .fill, idcol = .idcol) } #' @export #' @rdname compat-map pmap_dtc = function(.x, .f, ...) { out = mapply_list(.f, .x, list(...)) do.call(data.table, out) } #' @export #' @rdname compat-map imap = function(.x, .f, ...) { .nn = names(.x) %??% seq_along(.x) setNames(mapply_list(.f, list(.x, .nn), list(...)), names(.x)) } #' @export #' @rdname compat-map imap_lgl = function(.x, .f, ...) { .nn = names(.x) %??% seq_along(.x) setNames(pmap_lgl(c(list(.x, .nn)), .f), names(.x)) } #' @export #' @rdname compat-map imap_int = function(.x, .f, ...) { .nn = names(.x) %??% seq_along(.x) setNames(pmap_int(c(list(.x, .nn)), .f), names(.x)) } #' @export #' @rdname compat-map imap_dbl = function(.x, .f, ...) { .nn = names(.x) %??% seq_along(.x) setNames(pmap_dbl(c(list(.x, .nn)), .f), names(.x)) } #' @export #' @rdname compat-map imap_chr = function(.x, .f, ...) { .nn = names(.x) %??% seq_along(.x) setNames(pmap_chr(c(list(.x, .nn)), .f), names(.x)) } #' @export #' @rdname compat-map imap_dtr = function(.x, .f, ..., .fill = FALSE, .idcol = NULL) { rbindlist(imap(.x, .f, ...), use.names = TRUE, fill = .fill, idcol = .idcol) } #' @export #' @rdname compat-map imap_dtc = function(.x, .f, ...) { do.call(data.table, imap(.x, .f, ...)) } #' @export #' @rdname compat-map keep = function(.x, .f, ...) { UseMethod("keep") } #' @export keep.default = function(.x, .f, ...) { .x[probe(.x, .f, ...)] } #' @export keep.data.frame = function(.x, .f, ...) { .x[, probe(.x, .f, ...), drop = FALSE] } #' @export keep.data.table = function(.x, .f, ...) { .x[, probe(.x, .f, ...), with = FALSE] } #' @export #' @rdname compat-map discard = function(.x, .p, ...) { UseMethod("discard") } #' @export discard.default = function(.x, .p, ...) { .sel = probe(.x, .p, ...) out = .x[is.na(.sel) | !.sel] # Preserve list-level attributes (subsetting with [ drops them) attrs = attributes(.x) attrs[["names"]] = names(out) attributes(out) = attrs out } #' @export discard.data.frame = function(.x, .p, ...) { .sel = probe(.x, .p, ...) .x[, is.na(.sel) | !.sel, drop = FALSE] } #' @export discard.data.table = function(.x, .p, ...) { .sel = probe(.x, .p, ...) .x[, is.na(.sel) | !.sel, with = FALSE] } #' @export #' @rdname compat-map compact = function(.x) { .x[as.logical(lengths(.x))] } #' @export #' @rdname compat-map map_if = function(.x, .p, .f, ...) { UseMethod("map_if") } #' @export #' @rdname compat-map map_if.default = function(.x, .p, .f, ...) { .matches = probe(.x, .p) .x[.matches] = map(.x[.matches], .f, ...) .x } #' @export map_if.data.frame = function(.x, .p, .f, ...) { .matches = probe(.x, .p) .x[, .matches] = map(.x[, .matches, drop = FALSE], .f, ...) .x } #' @export map_if.data.table = function(.x, .p, .f, ...) { .matches = which(probe(.x, .p)) if (length(.matches)) { .x = copy(.x) for (j in .matches) { set(.x, j = j, value = .f(.x[[j]])) } } .x } #' @export #' @rdname compat-map map_at = function(.x, .at, .f, ...) { UseMethod("map_at") } #' @export map_at.default = function(.x, .at, .f, ...) { .x[.at] = map(.x[.at], .f, ...) .x } #' @export map_at.data.table = function(.x, .at, .f, ...) { if (length(.at)) { .x = copy(.x) for (j in .at) { set(.x, j = j, value = .f(.x[[j]])) } } .x } #' @export #' @rdname compat-map every = function(.x, .p, ...) { ok = all(map_lgl(.x, .p, ...), na.rm = FALSE) !is.na(ok) && ok } #' @export #' @rdname compat-map some = function(.x, .p, ...) { any(map_lgl(.x, .p, ...), na.rm = TRUE) } #' @export #' @rdname compat-map detect = function(.x, .p, ...) { for (i in seq_along(.x)) { .res = .p(.x[[i]], ...) if (!is.na(.res) && .res) { return(.x[[i]]) } } NULL } #' @export #' @rdname compat-map walk = function(.x, .f, ...) { for (.xi in .x) { .f(.xi, ...) } invisible(.x) } #' @export #' @rdname compat-map iwalk = function(.x, .f, ...) { .nn = names(.x) %??% seq_along(.x) for (.i in seq_along(.x)) { .f(.x[[.i]], .nn[.i], ...) } invisible(.x) } #' @export #' @rdname compat-map pwalk = function(.x, .f, ...) { # a loop is too slow here, so we wrap the function and NULL the return value # this allows the GC to collect the return values of the function calls .wrapper = function(...) { .f(...) NULL } pmap(.x, .wrapper, ...) invisible(.x) } mlr3misc/R/format_bib.R0000644000176200001440000000341514635030076014442 0ustar liggesusers#' Format Bibentries in Roxygen #' #' @description #' Operates on a named list of [bibentry()] entries and formats them nicely for #' documentation with \CRANpkg{roxygen2}. #' #' * `format_bib()` is intended to be called in the `@references` section and #' prints the complete entry using [toRd()]. #' * `cite_bib()` returns the family name of the first author (if available, falling back #' to the complete author name if not applicable) and the year in format #' `"[LastName] (YYYY)"`. #' #' @param ... (`character()`)\cr #' One or more names of bibentries. #' @param bibentries (named `list()`)\cr #' Named list of bibentries. #' @param envir (`environment`)\cr #' Environment to lookup `bibentries` if not provided. #' #' @return (`character(1)`). #' #' @export #' @examples #' bibentries = list(checkmate = citation("checkmate"), R = citation()) #' format_bib("checkmate") #' format_bib("R") #' cite_bib("checkmate") #' cite_bib("checkmate", "R") format_bib = function(..., bibentries = NULL, envir = parent.frame()) { if (is.null(bibentries)) { bibentries = get("bibentries", envir = envir) } assert_list(bibentries, "bibentry", names = "unique") str = map_chr(list(...), function(entry) tools::toRd(bibentries[[entry]])) paste0(str, collapse = "\n\n") } #' @export #' @rdname format_bib cite_bib = function(..., bibentries = NULL, envir = parent.frame()) { if (is.null(bibentries)) { bibentries = get("bibentries", envir = envir) } assert_list(bibentries, "bibentry", names = "unique") str = map_chr(list(...), function(entry) { x = bibentries[[entry]] sprintf("%s (%s)", x$author[[1L]]$family %??% x$author[[1L]], x$year) }) if (length(str) >= 3L) { str = c(toString(head(str, -1L)), tail(str, 1L)) } paste0(str, collapse = " and ") } mlr3misc/src/0000755000176200001440000000000015212055657012602 5ustar liggesusersmlr3misc/src/which_max.c0000644000176200001440000000616614455233002014714 0ustar liggesusers#define R_NO_REMAP #include #include #include typedef enum { TM_RANDOM, TM_FIRST, TM_LAST } ties_method_t; static ties_method_t translate_ties_method(SEXP ties_method_) { const char * str = CHAR(STRING_ELT(ties_method_, 0)); if (strcmp(str, "random") == 0) return TM_RANDOM; if (strcmp(str, "first") == 0) return TM_FIRST; if (strcmp(str, "last") == 0) return TM_LAST; Rf_error("Unknown ties method '%s'", str); } static int which_max_int(const int * x, const R_len_t nx, ties_method_t ties_method, Rboolean na_rm) { int max_index = -2; int max_value = INT_MIN; R_len_t ties = 1; for (R_len_t i = 0; i < nx; i++) { int xi = x[i]; if (xi == NA_INTEGER) { if (!na_rm) { return NA_INTEGER; } } else if (xi > max_value) { max_index = i; max_value = xi; ties = 1; } else if (xi == max_value) { switch(ties_method) { case TM_RANDOM: ties++; if (ties * unif_rand() < 1.) { max_index = i; } break; case TM_FIRST: break; case TM_LAST: max_index = i; break; } } } return max_index + 1; } static int which_max_dbl(const double * x, const R_len_t nx, ties_method_t ties_method, Rboolean na_rm) { int max_index = -2; double max_value = -DBL_MAX; R_len_t ties = 1; for (R_len_t i = 0; i < nx; i++) { double xi = x[i]; if (ISNAN(xi)) { if (!na_rm) { return NA_INTEGER; } } else if (xi > max_value) { max_index = i; max_value = xi; ties = 1; } else if (xi == max_value) { switch(ties_method) { case TM_RANDOM: ties++; if (ties * unif_rand() < 1.) { max_index = i; } break; case TM_FIRST: break; case TM_LAST: max_index = i; break; } } } return max_index + 1; } SEXP c_which_max(SEXP x_, SEXP ties_method_, SEXP na_rm_) { int index; ties_method_t ties_method = translate_ties_method(ties_method_); if (ties_method == TM_RANDOM) GetRNGstate(); switch(TYPEOF(x_)) { case LGLSXP: index = which_max_int(LOGICAL(x_), Rf_length(x_), ties_method, LOGICAL(na_rm_)[0]); break; case INTSXP: index = which_max_int(INTEGER(x_), Rf_length(x_), ties_method, LOGICAL(na_rm_)[0]); break; case REALSXP: index = which_max_dbl(REAL(x_), Rf_length(x_), ties_method, LOGICAL(na_rm_)[0]); break; default: Rf_error("Unsupported vector type in which_max(). Supported are logical and numerical vectors."); } if (ties_method == TM_RANDOM) PutRNGstate(); if (index == -1) { return Rf_allocVector(INTSXP, 0); } return Rf_ScalarInteger(index); } mlr3misc/src/to_decimal.c0000644000176200001440000000111114455233002015026 0ustar liggesusers#define R_NO_REMAP #include #include SEXP c_to_decimal(SEXP _bits) { const R_len_t n = Rf_length(_bits); const int * bits = LOGICAL(_bits); if (n > 30) { Rf_error("to_decimal() only works for vectors with <= 30 elements"); } int power = 1 << n; int out = 0; for (R_len_t i = 0; i < n; i++) { power >>= 1; if (bits[i] == NA_LOGICAL) { Rf_error("Bit vector contains missing values"); } if (bits[i]) { out += power; } } return Rf_ScalarInteger(out); } mlr3misc/src/init.c0000644000176200001440000000125514455233002013702 0ustar liggesusers#define R_NO_REMAP #include #include #include #include extern SEXP c_count_missing(SEXP); extern SEXP c_keep_in_bounds(SEXP, SEXP, SEXP); extern SEXP c_which_max(SEXP, SEXP, SEXP); extern SEXP c_to_decimal(SEXP); static const R_CallMethodDef CallEntries[] = { {"c_count_missing", (DL_FUNC) &c_count_missing, 1}, {"c_keep_in_bounds", (DL_FUNC) &c_keep_in_bounds, 3}, {"c_which_max", (DL_FUNC) &c_which_max, 3}, {"c_to_decimal", (DL_FUNC) &c_to_decimal, 1}, {NULL, NULL, 0} }; void R_init_mlr3misc(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } mlr3misc/src/keep_in_bounds.c0000644000176200001440000000166015170404762015733 0ustar liggesusers#define R_NO_REMAP #include #include SEXP c_keep_in_bounds(SEXP s_in, SEXP s_lower, SEXP s_upper) { const int *x = INTEGER(s_in); const int ll = Rf_asInteger(s_lower); const int lu = Rf_asInteger(s_upper); const R_len_t n = Rf_length(s_in); R_len_t i, j; // count the number of elements within bounds int count = 0; for (i = 0; i < n; i++) if (x[i] != NA_INTEGER && x[i] >= ll && x[i] <= lu) count++; // if all ok, immediately return without alloc and copy if (count == n) return(s_in); // create a new vector to store the filtered elements SEXP s_out = Rf_protect(Rf_allocVector(INTSXP, count)); int *out = INTEGER(s_out); // Copy the elements within bounds to the new vector j = 0; for (i = 0; i < n; i++) { if (x[i] != NA_INTEGER && x[i] >= ll && x[i] <= lu) out[j++] = x[i]; } Rf_unprotect(1); return s_out; } mlr3misc/src/backports.h0000644000176200001440000000052614455233002014734 0ustar liggesusers#include #include #ifndef LOGICAL_RO #define LOGICAL_RO(x) ((const int *) LOGICAL(x)) #endif #ifndef INTEGER_RO #define INTEGER_RO(x) ((const int *) INTEGER(x)) #endif #ifndef REAL_RO #define REAL_RO(x) ((const double *) REAL(x)) #endif #ifndef COMPLEX_RO #define COMPLEX_RO(x) ((const Rcomplex *) COMPLEX(x)) #endif mlr3misc/src/count_missing.c0000644000176200001440000000450214455233002015616 0ustar liggesusers#define R_NO_REMAP #include #include #include #include "backports.h" static R_xlen_t count_missing_logical(SEXP x) { #if defined(R_VERSION) && R_VERSION >= R_Version(3, 6, 0) if (LOGICAL_NO_NA(x)) return 0; #endif const R_xlen_t n = Rf_xlength(x); const int * xp = LOGICAL_RO(x); R_xlen_t count = 0; for (R_xlen_t i = 0; i < n; i++) { if (xp[i] == NA_LOGICAL) count++; } return count; } static R_xlen_t count_missing_integer(SEXP x) { #if defined(R_VERSION) && R_VERSION >= R_Version(3, 5, 0) if (INTEGER_NO_NA(x)) return 0; #endif const R_xlen_t n = Rf_xlength(x); const int * xp = INTEGER_RO(x); R_xlen_t count = 0; for (R_xlen_t i = 0; i < n; i++) { if (xp[i] == NA_INTEGER) count++; } return count; } static R_xlen_t count_missing_double(SEXP x) { #if defined(R_VERSION) && R_VERSION >= R_Version(3, 5, 0) if (REAL_NO_NA(x)) return 0; #endif const R_xlen_t n = Rf_xlength(x); const double * xp = REAL_RO(x); R_xlen_t count = 0; for (R_xlen_t i = 0; i < n; i++) { if (ISNAN(xp[i])) count++; } return count; } static R_xlen_t count_missing_complex(SEXP x) { const R_xlen_t n = Rf_xlength(x); const Rcomplex * xp = COMPLEX_RO(x); R_xlen_t count = 0; for (R_xlen_t i = 0; i < n; i++) { if (ISNAN((xp[i]).r) || ISNAN((xp[i]).i)) count++; } return count; } static R_xlen_t count_missing_string(SEXP x) { #if defined(R_VERSION) && R_VERSION >= R_Version(3, 5, 0) if (STRING_NO_NA(x)) return 0; #endif const R_xlen_t nx = Rf_xlength(x); R_xlen_t count = 0; for (R_xlen_t i = 0; i < nx; i++) { if (STRING_ELT(x, i) == NA_STRING) count++; } return count; } SEXP c_count_missing(SEXP x) { switch(TYPEOF(x)) { case LGLSXP: return Rf_ScalarInteger(count_missing_logical(x)); case INTSXP: return Rf_ScalarInteger(count_missing_integer(x)); case REALSXP: return Rf_ScalarInteger(count_missing_double(x)); case CPLXSXP: return Rf_ScalarInteger(count_missing_complex(x)); case STRSXP: return Rf_ScalarInteger(count_missing_string(x)); default: Rf_error("Object of type '%s' not supported", Rf_type2char(TYPEOF(x))); } } mlr3misc/NAMESPACE0000644000176200001440000001063415211524655013234 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(as.data.table,Dictionary) S3method(as_callback,Callback) S3method(as_callbacks,"NULL") S3method(as_callbacks,Callback) S3method(as_callbacks,list) S3method(discard,data.frame) S3method(discard,data.table) S3method(discard,default) S3method(distinct_values,default) S3method(distinct_values,factor) S3method(distinct_values,logical) S3method(format,Mlr3Error) S3method(format,Mlr3Warning) S3method(hash_input,"function") S3method(hash_input,data.table) S3method(hash_input,default) S3method(insert_named,"NULL") S3method(insert_named,data.frame) S3method(insert_named,data.table) S3method(insert_named,default) S3method(insert_named,environment) S3method(keep,data.frame) S3method(keep,data.table) S3method(keep,default) S3method(map_at,data.table) S3method(map_at,default) S3method(map_if,data.frame) S3method(map_if,data.table) S3method(map_if,default) S3method(modify_at,data.table) S3method(modify_at,default) S3method(modify_if,data.table) S3method(modify_if,default) S3method(remove_named,data.frame) S3method(remove_named,data.table) S3method(remove_named,default) S3method(remove_named,environment) S3method(strip_srcrefs,"function") S3method(strip_srcrefs,default) export("%check&&%") export("%check||%") export("%nin%") export("get_private<-") export(Callback) export(Context) export(Dictionary) export(as_callback) export(as_callbacks) export(as_factor) export(as_short_string) export(assert_callback) export(assert_callbacks) export(assert_ro_binding) export(calculate_hash) export(call_back) export(capitalize) export(cat_cli) export(catf) export(catn) export(check_packages_installed) export(chunk) export(chunk_vector) export(cite_bib) export(clbk) export(clbks) export(compact) export(compose) export(compute_mode) export(count_missing) export(crate) export(cross_join) export(deframe) export(deprecated_binding) export(detect) export(dictionary_sugar) export(dictionary_sugar_get) export(dictionary_sugar_inc_get) export(dictionary_sugar_inc_mget) export(dictionary_sugar_mget) export(did_you_mean) export(discard) export(distinct_values) export(encapsulate) export(enframe) export(error_config) export(error_input) export(error_learner) export(error_learner_predict) export(error_learner_train) export(error_mlr3) export(error_timeout) export(every) export(extract_vars) export(format_bib) export(formulate) export(get_private) export(get_seed) export(has_element) export(hash_input) export(ids) export(imap) export(imap_chr) export(imap_dbl) export(imap_dtc) export(imap_dtr) export(imap_int) export(imap_lgl) export(insert_named) export(invoke) export(is_scalar_na) export(iwalk) export(keep) export(keep_in_bounds) export(leanify_package) export(leanify_r6) export(load_dataset) export(map) export(map_at) export(map_bc) export(map_br) export(map_chr) export(map_dbl) export(map_dtc) export(map_dtr) export(map_if) export(map_int) export(map_lgl) export(map_values) export(messagef) export(mlr_callbacks) export(modify_at) export(modify_if) export(named_list) export(named_vector) export(names2) export(open_help) export(pmap) export(pmap_chr) export(pmap_dbl) export(pmap_dtc) export(pmap_dtr) export(pmap_int) export(pmap_lgl) export(pwalk) export(rcbind) export(rd_format_packages) export(rd_format_range) export(rd_format_string) export(rd_info) export(recycle_vectors) export(register_namespace_callback) export(remove_named) export(reorder_vector) export(require_namespaces) export(rowwise_table) export(seq_along0) export(seq_col) export(seq_len0) export(seq_row) export(set_class) export(set_col_names) export(set_names) export(set_params) export(shuffle) export(some) export(stopf) export(str_collapse) export(str_indent) export(str_trunc) export(strip_srcrefs) export(to_decimal) export(topo_sort) export(transpose_list) export(unnest) export(walk) export(warn_deprecated) export(warning_config) export(warning_input) export(warning_mlr3) export(warningf) export(which_max) export(which_min) export(with_package) import(checkmate) import(data.table) importFrom(R6,R6Class) importFrom(R6,is.R6) importFrom(digest,digest) importFrom(methods,formalArgs) importFrom(methods,hasArg) importFrom(stats,as.formula) importFrom(stats,runif) importFrom(stats,setNames) importFrom(stats,terms) importFrom(utils,adist) importFrom(utils,capture.output) importFrom(utils,head) importFrom(utils,tail) useDynLib(mlr3misc,c_count_missing) useDynLib(mlr3misc,c_keep_in_bounds) useDynLib(mlr3misc,c_to_decimal) useDynLib(mlr3misc,c_which_max) mlr3misc/NEWS.md0000644000176200001440000002037615212054344013111 0ustar liggesusers# mlr3misc 0.22.0 * feat: `as_short_string()` now prints factor values (#173). * fix: `Dictionary`'s `remove()` now shows the correct key in the "did you mean" suggestion of its error message (#171). * fix: `encapsulate()` now short-circuits when `.timeout = 0` and returns an immediate `Mlr3ErrorTimeout` log entry instead of silently disabling timeout enforcement. * fix: `keep_in_bounds()` now has a consistent integer return type in its C call (#172). * perf: `rcbind()` uses `%in%` instead of `intersect()` for its name check (#175). * fix: `register_namespace_callback()` now wraps the user callback so it can be invoked by hook callers that pass `package` and `lib_path` arguments (e.g. `pkgload::load_all()`), which previously caused "unused arguments" errors (#180). * perf: `topo_sort()` uses `set()` for faster updates (#174). * perf: `unnest()` caches the `lengths()` call (#178). # mlr3misc 0.21.0 * docs: Clarify the behavior of `encapsulate()` regarding stored conditions and output. * fix: `encapsulate()` with `"evaluate"` now respects `.seed` and `.opts`. * refactor: `encapsulate()` with `"evaluate"` no longer stores output, consistent with other encapsulation methods. * refactor: Messages in `encapsulate()` logs are now stored as `condition` objects instead of `character`. * feat: `Mlr3Error` objects now support storing parent conditions. # mlr3misc 0.20.0 * fix: `unnest()` now works with vector-valued elements. * feat: Add `warn_deprecated()`. * BREAKING CHANGE: Remove `"msg"` column from encapsulate logs. * fix: `discard()` no longer removes attributes. * perf: Use `data.table::fifelse()` instead of `ifelse()`. # mlr3misc 0.19.0 * feat: Added various new functions for improved error handling. * feat: `encapsulate()` now returns the specific condition objects along the logs, allowing for improved error handling on the caller side. # mlr3misc 0.18.0 * feat: Added `"mirai"` as encapsulation method to `encapsulate()`. # mlr3misc 0.17.0 * feat: `as_callbacks()` returns a list named by the callback ids now. * feat: Added logical operators `%check&&%` and `%check||%` for `check_*`-functions from `checkmate` (moved here from `mlr3pipelines`). * feat: Added helper `cat_cli()`. * fix: Default `dicts_suggest = NULL` for `dictionary_get_item()` and `dictionary_retrieve_item()` for backward compatibility. * fix: Wrong assert in `dictionary_sugar_inc_get`. * feat: Functions `warningf()` and `stopf()` now have a `class` argument and also add the additional class `mlr3warning` and `mlr3error`, respectively. The condition object now also includes the call. # mlr3misc 0.16.0 * fix: `crate()` is using the correct 'topenv' environment now. * BREAKING CHANGE: Remove the unused 'safe' variants of dictionary getters. * feat: `dictionary_sugar_get()` and corresponding functions now take a list of dictionaries as optional argument `.dicts_suggest` to look for suggestions if `.key` is not part of the dictionary. # mlr3misc 0.15.1 * refactor: Update `as_callback()` functions. # mlr3misc 0.15.0 * Feat: Added `strip_srcrefs` S3 generic, which removes source references from objects * The RNG state is now copied to the callr session when using `encapsulate()`. # mlr3misc 0.14.0 * Added argument `.compile` to function `crate()` because R disables byte-code compilation of functions when changing their enclosing environment * Added the possibility to include prototype arguments when adding elements to a `Dictionary` * Removed unused argument `required_args` from `Dictionary` class * Disable leanification when `ROXYGEN_PKG` environment variable is set # mlr3misc 0.13.0 * Updated default environment for `crate()` to `topenv()` (#86). * Added safe methods for dictionary retrieval (#83) * fix: Fixed an important bug that caused serialized objects to be overly large when installing mlr3 with `--with-keep.source` (#88) # mlr3misc 0.12.0 * Added new encapsulation mode `"try"`. * Added functions `dictionary_sugar_inc_get` and `dictionary_sugar_inc_mget` which allow to conveniently add suffixes to dictionary ids when retrieving objects. # mlr3misc 0.11.0 * Added initial support for a callback mechanism, see `as_callback()`. * Added helper `catn()`. * Added helper `set_params()`. * Added assign method for `get_private()`. * Elements of a dictionary via `dictionary_sugar_mget()` are now returned named. # mlr3misc 0.10.0 * Added helper `get_private()`. * Added helper `map_br()` and `map_bc()`. * Added helper `recycle_vectors()`. * Added helpers `walk()`, `iwalk()` and `pwalk()`. # mlr3misc 0.9.5 * Added helper `deframe()`. # mlr3misc 0.9.4 * Added helper `capitalize()`. * Added helper `to_decimal()`. * Fixed cleanup in `register_namespace_callback()`. # mlr3misc 0.9.3 * New (internal) helper functions: `calculate_hash()` and `assert_ro_binding()` # mlr3misc 0.9.2 * R6 objects retrieved from the dictionary are now properly cloned. # mlr3misc 0.9.1 * Fixed compilation for R versions older than 3.5.0 (#59). # mlr3misc 0.9.0 * Changed return type of `reorder_vector()`. * Added assertions in `pmap()` to avoid a segfault (#56). * Added `count_missing()`. # mlr3misc 0.8.0 * New function `reorder_vector()`. * `formulate()` can now quote all terms, defaulting to quote all terms on the right hand side. # mlr3misc 0.7.0 * Make more map functions work nicely with data frames and data tables. * `formulate()` now supports multiple LHS terms. * Added `format_bib()` and `cite_bib()` helpers for working with bibentries and roxygen2. # mlr3misc 0.6.0 * New argument `.timeout` for `invoke()`. * New argument `.timeout` for `encapsulate()`. * Removed `cite_bib()` and Rd macro `\cite{}` and removed orphaned package `bibtex` from suggests. * New argument `quietly` for `require_namespaces()`. * New function `crate()` to cleanly separate a function from its environment. * New function `register_namespace_callback()`. # mlr3misc 0.5.0 * Added `compose()` function for function composition. * Added method `leanify_package()` that shrinks the size of serialized R6 objects. # mlr3misc 0.4.0 * Added helper functions to assist in generating Rd documentation for 'mlr3' objects. # mlr3misc 0.3.0 * Introduced a placeholder for column name prefixes in `unnest()`. # mlr3misc 0.2.0 * Fixed an issue with `rcbind()` for columns of `x` named `y` (#42). * Fixed broken `on.exit()` in `invoke()` if both a seed and a list of options were provided. # mlr3misc 0.1.8 * New function `check_packages_installed()`. * New function `open_help()`. # mlr3misc 0.1.7 * `map_dtr()`, `imap_dtr()` and `pmap_dtr()` now pass `.idcol` down to argument `idcol` of `data.table::rbindlist()`. * `cite_bib()` can now handle packages with multiple citation entries. * Added argument `wrap` to `catf()`, `messagef()`, `warningf()` and `stopf()` to wrap the respective messages to a customizable width. * Added `with_package()` helper, similar to the one in package `withr`. # mlr3misc 0.1.6 * `cite_bib()` or Rd macro `\cite{}` can now return the citation information of the package if key is set to `"pkg::citation"`. * Updated dictionary helpers. # mlr3misc 0.1.5 * Fixed error in C code discovered by UBSAN checks on CRAN. * Added `dictionary_sugar_mget()`. * Renamed `dictionary_sugar()` to `dictionary_sugar_get()`. * Added function `cite_bib()` and Rd macro `\cite{}` to insert entries from bibtex files into roxygen documentation. * `unnest()` now creates list columns for non atomic list elements. # mlr3misc 0.1.4 * Added argument `na_rm` to `which_max()` and `which_min()`. * Fixed a bug in `as_short_string()` for empty atomic vectors. # mlr3misc 0.1.3 * New function `detect()`. * New function `dictionary_sugar()`. * It is now asserted that the return value of `Dictionary$get()` is an R6 object. * Fix some assertions in `Dictionary` # mlr3misc 0.1.2 * New function `named_vector()`. * New function `keep_in_bounds()`. * New function `set_col_names()`. * New function `distinct_values()`. * Added argument `.key` to `rowwise_table()`. * Additional arguments passed to `Dictionary$get()` and `Dictionary$mget()` must now be named. # mlr3misc 0.1.1 * New function `encapsulate()` to call functions while recording a log. * `invoke()`: New arguments `.opts` and `.seed` to temporarily set options or random seeds, respectively. * Fixed warnings about partial argument matching. # mlr3misc 0.1.0 * Initial release. mlr3misc/README.md0000644000176200001440000000146215147263543013277 0ustar liggesusers# mlr3misc Package website: [release](https://mlr3misc.mlr-org.com/) | [dev](https://mlr3misc.mlr-org.com/dev/) Miscellaneous helper functions for [mlr3](https://mlr3.mlr-org.com). [![r-cmd-check](https://github.com/mlr-org/mlr3misc/actions/workflows/r-cmd-check.yml/badge.svg)](https://github.com/mlr-org/mlr3misc/actions/workflows/r-cmd-check.yml) [![CRAN Status](https://www.r-pkg.org/badges/version-ago/mlr3misc)](https://cran.r-project.org/package=mlr3misc) [![Mattermost](https://img.shields.io/badge/chat-mattermost-orange.svg)](https://lmmisld-lmu-stats-slds.srv.mwn.de/mlr_invite/) ## Installation Install the last release from CRAN: ``` r install.packages("mlr3misc") ``` Install the development version from GitHub: ``` r pak::pak("mlr-org/mlr3misc") ``` mlr3misc/man/0000755000176200001440000000000015212015277012560 5ustar liggesusersmlr3misc/man/transpose_list.Rd0000644000176200001440000000107115211524655016123 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/transpose.R \name{transpose_list} \alias{transpose_list} \title{Transpose lists of lists} \usage{ transpose_list(.l) } \arguments{ \item{.l}{(\code{list()} of \code{list()}).} } \value{ \code{list()}. } \description{ Transposes a list of list, and turns it inside out, similar to the function \code{transpose()} in package \CRANpkg{purrr}. } \examples{ x = list(list(a = 2, b = 3), list(a = 5, b = 10)) str(x) str(transpose_list(x)) # list of data frame rows: transpose_list(iris[1:2, ]) } mlr3misc/man/keep_in_bounds.Rd0000644000176200001440000000152515211524655016042 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/keep_in_bounds.R \name{keep_in_bounds} \alias{keep_in_bounds} \title{Remove All Elements Out Of Bounds} \usage{ keep_in_bounds(x, lower, upper) } \arguments{ \item{x}{(\code{integer()})\cr Vector to filter.} \item{lower}{(\code{integer(1)})\cr Lower bound.} \item{upper}{(\code{integer(1)})\cr Upper bound.} } \value{ (integer()) with only values in \verb{[lower, upper]}. } \description{ Filters vector \code{x} to only keep elements which are in bounds \verb{[lower, upper]}. This is equivalent to the following, but tries to avoid unnecessary allocations: \if{html}{\out{
}}\preformatted{ x[!is.na(x) & x >= lower & x <= upper] }\if{html}{\out{
}} Currently only works for integer \code{x}. } \examples{ keep_in_bounds(sample(20), 5, 10) } mlr3misc/man/dictionary_sugar_get.Rd0000644000176200001440000000420515211524655017261 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dictionary_sugar.R \name{dictionary_sugar_get} \alias{dictionary_sugar_get} \alias{dictionary_sugar} \alias{dictionary_sugar_mget} \title{A Quick Way to Initialize Objects from Dictionaries} \usage{ dictionary_sugar_get(dict, .key, ..., .dicts_suggest = NULL) dictionary_sugar(dict, .key, ..., .dicts_suggest = NULL) dictionary_sugar_mget(dict, .keys, ..., .dicts_suggest = NULL) } \arguments{ \item{dict}{(\link{Dictionary}).} \item{.key}{(\code{character(1)})\cr Key of the object to construct.} \item{...}{(\code{any})\cr See description.} \item{.dicts_suggest}{(named \code{list()}) Named list of \link[=Dictionary]{dictionaries} used to look up suggestions for \code{.key} if \code{.key} does not exist in \code{dict}.} \item{.keys}{(\code{character()})\cr Keys of the objects to construct.} } \value{ \code{\link[R6:R6Class]{R6::R6Class()}} } \description{ Given a \link{Dictionary}, retrieve objects with provided keys. \itemize{ \item \code{dictionary_sugar_get()} to retrieve a single object with key \code{.key}. \item \code{dictionary_sugar_mget()} to retrieve a list of objects with keys \code{.keys}. \item \code{dictionary_sugar()} is deprecated in favor of \code{dictionary_sugar_get()}. \item If \code{.key} or \code{.keys} is missing, the dictionary itself is returned. } Arguments in \code{...} must be named and are consumed in the following order: \enumerate{ \item All arguments whose names match the name of an argument of the constructor are passed to the \verb{$get()} method of the \link{Dictionary} for construction. \item All arguments whose names match the name of a parameter of the \link[paradox:ParamSet]{paradox::ParamSet} of the constructed object are set as parameters. If there is no \link[paradox:ParamSet]{paradox::ParamSet} in \code{obj$param_set}, this step is skipped. \item All remaining arguments are assumed to be regular fields of the constructed R6 instance, and are assigned via \code{\link{<-}}. } } \examples{ library(R6) item = R6Class("Item", public = list(x = 0)) d = Dictionary$new() d$add("key", item) dictionary_sugar_get(d, "key", x = 2) } mlr3misc/man/rowwise_table.Rd0000644000176200001440000000170715211524655015726 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rowwise_table.R \name{rowwise_table} \alias{rowwise_table} \title{Row-Wise Constructor for 'data.table'} \usage{ rowwise_table(..., .key = NULL) } \arguments{ \item{...}{(\code{any})\cr Arguments: Column names in first rows as formulas (with empty left hand side), then the tabular data in the following rows.} \item{.key}{(\code{character(1)})\cr If not \code{NULL}, set the key via \code{\link[data.table:setkeyv]{data.table::setkeyv()}} after constructing the table.} } \value{ \code{\link[data.table:data.table]{data.table::data.table()}}. } \description{ Similar to the \CRANpkg{tibble} function \code{tribble()}, this function allows to construct tabular data in a row-wise fashion. The first arguments passed as formula will be interpreted as column names. The remaining arguments will be put into the resulting table. } \examples{ rowwise_table( ~a, ~b, 1, "a", 2, "b" ) } mlr3misc/man/warn_deprecated.Rd0000644000176200001440000000207115211524655016202 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/warn_deprecated.R \name{warn_deprecated} \alias{warn_deprecated} \title{Give a Warning about a Deprecated Function, Argument, or Active Binding} \usage{ warn_deprecated(what) } \arguments{ \item{what}{(\code{character(1)})\cr A description of the deprecated entity. This should be somewhat descriptive, e.g. \code{"Class$method()"} or \code{"Argument 'foo' of Class$method()"}.\cr The \code{what} is used to determine if the warning has already been given, so it should be unique for each deprecated entity.} } \description{ Generates a warning when a deprecated function, argument, or active binding is used or accessed. A warning will only be given once per session, and all deprecation warnings can be suppressed by setting the option \code{mlr3.warn_deprecated = FALSE}. The warning is of the format "what is deprecated and will be removed in the future." Use the \code{deprecated_binding()} helper function to create an active binding that generates a warning when accessed. } \keyword{internal} mlr3misc/man/has_element.Rd0000644000176200001440000000121115211524655015332 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/has_element.R \name{has_element} \alias{has_element} \title{Check if an Object is Element of a List} \usage{ has_element(.x, .y) } \arguments{ \item{.x}{(\code{list()} | atomic \code{vector()}).} \item{.y}{(\code{any})\cr Object to test for.} } \description{ Simply checks if a list contains a given object. \itemize{ \item NB1: Objects are compared with identity. \item NB2: Only use this on lists with complex objects, for simpler structures there are faster operations. \item NB3: Clones of R6 objects are not detected. } } \examples{ has_element(list(1, 2, 3), 1) } mlr3misc/man/which_min.Rd0000644000176200001440000000262515211524655015025 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/which_max.R \name{which_min} \alias{which_min} \alias{which_max} \title{Index of the Minimum/Maximum Value, with Correction for Ties} \usage{ which_min(x, ties_method = "random", na_rm = FALSE) which_max(x, ties_method = "random", na_rm = FALSE) } \arguments{ \item{x}{(\code{numeric()})\cr Numeric vector.} \item{ties_method}{(\code{character(1)})\cr Handling of ties. One of "first", "last" or "random" (default) to return the first index, the last index, or a random index of the minimum/maximum values.} \item{na_rm}{(\code{logical(1)})\cr Remove NAs before computation?} } \value{ (\code{integer()}): Index of the minimum/maximum value. Returns an empty integer vector for empty input vectors and vectors with no non-missing values (if \code{na_rm} is \code{TRUE}). Returns \code{NA} if \code{na_rm} is \code{FALSE} and at least one \code{NA} is found in \code{x}. } \description{ Works similar to \code{\link[base:which.min]{base::which.min()}}/\code{\link[base:which.max]{base::which.max()}}, but corrects for ties. Missing values are treated as \code{Inf} for \code{which_min} and as \code{-Inf} for \code{which_max()}. } \examples{ x = c(2, 3, 1, 3, 5, 1, 1) which_min(x, ties_method = "first") which_min(x, ties_method = "last") which_min(x, ties_method = "random") which_max(x) which_max(integer(0)) which_max(NA) which_max(c(NA, 1)) } mlr3misc/man/invoke.Rd0000644000176200001440000000277215211524655014356 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/invoke.R \name{invoke} \alias{invoke} \title{Invoke a Function Call} \usage{ invoke( .f, ..., .args = list(), .opts = list(), .seed = NA_integer_, .timeout = Inf ) } \arguments{ \item{.f}{(\verb{function()})\cr Function to call.} \item{...}{(\code{any})\cr Additional function arguments passed to \code{.f}.} \item{.args}{(\code{list()})\cr Additional function arguments passed to \code{.f}, as (named) \code{list()}. These arguments will be concatenated to the arguments provided via \code{...}.} \item{.opts}{(named \code{list()})\cr List of options which are set before the \code{.f} is called. Options are reset to their previous state afterwards.} \item{.seed}{(\code{integer(1)})\cr Random seed to set before invoking the function call. Gets reset to the previous seed on exit.} \item{.timeout}{(\code{numeric(1)})\cr Timeout in seconds. Uses \code{\link[=setTimeLimit]{setTimeLimit()}}. Note that timeouts are only triggered on a user interrupt, not in compiled code.} } \description{ An alternative interface for \code{\link[=do.call]{do.call()}}, similar to the deprecated function in \pkg{purrr}. This function tries hard to not evaluate the passed arguments too eagerly which is important when working with large R objects. It is recommended to pass all arguments named in order to not rely on positional argument matching. } \examples{ invoke(mean, .args = list(x = 1:10)) invoke(mean, na.rm = TRUE, .args = list(1:10)) } mlr3misc/man/mlr_callbacks.Rd0000644000176200001440000000121415211524655015642 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Callback.R \name{mlr_callbacks} \alias{mlr_callbacks} \title{Dictionary of Callbacks} \usage{ mlr_callbacks } \description{ A simple \link{Dictionary} storing objects of class \link{Callback}. Each callback has an associated help page, see \code{mlr_callbacks_[id]}. This dictionary can get populated with additional callbacks by add-on packages. As a convention, the key should start with the name of the package, i.e. \code{package.callback}. For a more convenient way to retrieve and construct learners, see \code{\link[=clbk]{clbk()}}/\code{\link[=clbks]{clbks()}}. } mlr3misc/man/str_indent.Rd0000644000176200001440000000147715211524655015235 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_indent.R \name{str_indent} \alias{str_indent} \title{Indent Strings} \usage{ str_indent(initial, str, width = 0.9 * getOption("width"), exdent = 2L, ...) } \arguments{ \item{initial}{(\code{character(1)})\cr Initial string, passed to \code{\link[=strwrap]{strwrap()}}.} \item{str}{(\code{character()})\cr Vector of strings.} \item{width}{(\code{integer(1)})\cr Width of the output.} \item{exdent}{(\code{integer(1)})\cr Indentation of subsequent lines in paragraph.} \item{...}{(\code{any})\cr Additional parameters passed to \code{\link[=str_collapse]{str_collapse()}}.} } \value{ (\code{character()}). } \description{ Formats a text block for printing. } \examples{ cat(str_indent("Letters:", str_collapse(letters), width = 25), sep = "\n") } mlr3misc/man/set_params.Rd0000644000176200001440000000205515211524655015213 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/set_params.R \name{set_params} \alias{set_params} \title{Modify Values of a Parameter Set} \usage{ set_params(.ps, ..., .values = list(), .insert = TRUE) } \arguments{ \item{.ps}{(\link[paradox:ParamSet]{paradox::ParamSet})\cr The parameter set whose values are changed.} \item{...}{(\code{any}) Named parameter values.} \item{.values}{(\code{list()}) Named list with parameter values.} \item{.insert}{(\code{logical(1)})\cr Whether to insert the values (old values are being kept, if not overwritten), or to discard the old values. Is TRUE by default.} } \description{ Convenience function to modify (or overwrite) the values of a \link[paradox:ParamSet]{paradox::ParamSet}. } \examples{ if (requireNamespace("paradox")) { param_set = paradox::ps(a = paradox::p_dbl(), b = paradox::p_dbl()) param_set$values$a = 0 set_params(param_set, a = 1, .values = list(b = 2), .insert = TRUE) set_params(param_set, a = 3, .insert = FALSE) set_params(param_set, b = 4, .insert = TRUE) } } mlr3misc/man/Dictionary.Rd0000644000176200001440000002220015211524655015154 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Dictionary.R \name{Dictionary} \alias{Dictionary} \title{Key-Value Storage} \description{ A key-value store for \link[R6:R6]{R6::R6} objects. On retrieval of an object, the following applies: \itemize{ \item If the object is a \code{R6ClassGenerator}, it is initialized with \code{new()}. \item If the object is a function, it is called and must return an instance of a \link[R6:R6]{R6::R6} object. \item If the object is an instance of a R6 class, it is returned as-is. } Default argument required for construction can be stored alongside their constructors by passing them to \verb{$add()}. } \section{S3 methods}{ \itemize{ \item \code{as.data.table(d)}\cr \link{Dictionary} -> \code{\link[data.table:data.table]{data.table::data.table()}}\cr Converts the dictionary to a \code{\link[data.table:data.table]{data.table::data.table()}}. } } \examples{ library(R6) item1 = R6Class("Item", public = list(x = 1)) item2 = R6Class("Item", public = list(x = 2)) d = Dictionary$new() d$add("a", item1) d$add("b", item2) d$add("c", item1$new()) d$keys() d$get("a") d$mget(c("a", "b")) } \concept{Dictionary} \section{Public fields}{ \if{html}{\out{
}} \describe{ \item{\code{items}}{(\code{environment()})\cr Stores the items of the dictionary} } \if{html}{\out{
}} } \section{Methods}{ \subsection{Public methods}{ \itemize{ \item \href{#method-Dictionary-initialize}{\code{Dictionary$new()}} \item \href{#method-Dictionary-format}{\code{Dictionary$format()}} \item \href{#method-Dictionary-print}{\code{Dictionary$print()}} \item \href{#method-Dictionary-keys}{\code{Dictionary$keys()}} \item \href{#method-Dictionary-has}{\code{Dictionary$has()}} \item \href{#method-Dictionary-get}{\code{Dictionary$get()}} \item \href{#method-Dictionary-mget}{\code{Dictionary$mget()}} \item \href{#method-Dictionary-add}{\code{Dictionary$add()}} \item \href{#method-Dictionary-remove}{\code{Dictionary$remove()}} \item \href{#method-Dictionary-prototype_args}{\code{Dictionary$prototype_args()}} \item \href{#method-Dictionary-clone}{\code{Dictionary$clone()}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-initialize}{}}} \subsection{\code{Dictionary$new()}}{ Construct a new Dictionary. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$new()} \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-format}{}}} \subsection{\code{Dictionary$format()}}{ Format object as simple string. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$format(...)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{...}}{(ignored).} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-print}{}}} \subsection{\code{Dictionary$print()}}{ Print object. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$print()} \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-keys}{}}} \subsection{\code{Dictionary$keys()}}{ Returns all keys which comply to the regular expression \code{pattern}. If \code{pattern} is \code{NULL} (default), all keys are returned. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$keys(pattern = NULL)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{pattern}}{(\code{character(1)}).} } \if{html}{\out{
}} } \subsection{Returns}{ \code{character()} of keys. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-has}{}}} \subsection{\code{Dictionary$has()}}{ Returns a logical vector with \code{TRUE} at its i-th position if the i-th key exists. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$has(keys)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{keys}}{(\code{character()}).} } \if{html}{\out{
}} } \subsection{Returns}{ \code{logical()}. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-get}{}}} \subsection{\code{Dictionary$get()}}{ Retrieves object with key \code{key} from the dictionary. Additional arguments must be named and are passed to the constructor of the stored object. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$get(key, ..., .prototype = FALSE)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{key}}{(\code{character(1)}).} \item{\code{...}}{(\code{any})\cr Passed down to constructor.} \item{\code{.prototype}}{(\code{logical(1)})\cr Whether to construct a prototype object.} } \if{html}{\out{
}} } \subsection{Returns}{ Object with corresponding key. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-mget}{}}} \subsection{\code{Dictionary$mget()}}{ Returns objects with keys \code{keys} in a list named with \code{keys}. Additional arguments must be named and are passed to the constructors of the stored objects. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$mget(keys, ...)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{keys}}{(\code{character()}).} \item{\code{...}}{(\code{any})\cr Passed down to constructor.} } \if{html}{\out{
}} } \subsection{Returns}{ Named \code{list()} of objects with corresponding keys. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-add}{}}} \subsection{\code{Dictionary$add()}}{ Adds object \code{value} to the dictionary with key \code{key}, potentially overwriting a previously stored item. Additional arguments in \code{...} must be named and are passed as default arguments to \code{value} during construction. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$add(key, value, ..., .prototype_args = list())} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{key}}{(\code{character(1)}).} \item{\code{value}}{(\code{any}).} \item{\code{...}}{(\code{any})\cr Passed down to constructor.} \item{\code{.prototype_args}}{(\code{list()})\cr List of arguments to construct a prototype object. Can be used when objects have construction arguments without defaults.} } \if{html}{\out{
}} } \subsection{Returns}{ \code{Dictionary}. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-remove}{}}} \subsection{\code{Dictionary$remove()}}{ Removes objects from the dictionary. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$remove(keys)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{keys}}{(\code{character()})\cr Keys of objects to remove.} } \if{html}{\out{
}} } \subsection{Returns}{ \code{Dictionary}. } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-prototype_args}{}}} \subsection{\code{Dictionary$prototype_args()}}{ Returns the arguments required to construct a simple prototype of the object. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$prototype_args(key)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{key}}{(\code{character(1)})\cr Key of object to query for required arguments.} } \if{html}{\out{
}} } \subsection{Returns}{ \code{list()} of prototype arguments } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Dictionary-clone}{}}} \subsection{\code{Dictionary$clone()}}{ The objects of this class are cloneable with this method. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Dictionary$clone(deep = FALSE)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{deep}}{Whether to make a deep clone.} } \if{html}{\out{
}} } } } mlr3misc/man/names2.Rd0000644000176200001440000000140015211524655014233 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/names2.R \name{names2} \alias{names2} \title{A Type-Stable names() Replacement} \usage{ names2(x, missing_val = NA_character_) } \arguments{ \item{x}{(\code{any})\cr Object.} \item{missing_val}{(\code{atomic(1)})\cr Value to set for missing names. Default is \code{NA_character_}.} } \value{ (\code{character(length(x))}). } \description{ A simple wrapper around \code{\link[base:names]{base::names()}}. Returns a character vector even if no names attribute is set. Values \code{NA} and \code{""} are treated as missing and replaced with the value provided in \code{missing_val}. } \examples{ x = 1:3 names(x) names2(x) names(x)[1:2] = letters[1:2] names(x) names2(x, missing_val = "") } mlr3misc/man/mlr3misc-package.Rd0000644000176200001440000000237015211524655016177 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/zzz.R \docType{package} \name{mlr3misc-package} \alias{mlr3misc} \alias{mlr3misc-package} \title{mlr3misc: Helper Functions for 'mlr3'} \description{ \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} Frequently used helper functions and assertions used in 'mlr3' and its companion packages. Comes with helper functions for functional programming, for printing, to work with 'data.table', as well as some generally useful 'R6' classes. This package also supersedes the package 'BBmisc'. } \seealso{ Useful links: \itemize{ \item \url{https://mlr3misc.mlr-org.com} \item \url{https://github.com/mlr-org/mlr3misc} \item Report bugs at \url{https://github.com/mlr-org/mlr3misc/issues} } } \author{ \strong{Maintainer}: Marc Becker \email{marcbecker@posteo.de} (\href{https://orcid.org/0000-0002-8115-0400}{ORCID}) Authors: \itemize{ \item Marc Becker \email{marcbecker@posteo.de} (\href{https://orcid.org/0000-0002-8115-0400}{ORCID}) \item Michel Lang \email{michellang@gmail.com} (\href{https://orcid.org/0000-0001-9754-0393}{ORCID}) \item Patrick Schratz \email{patrick.schratz@gmail.com} (\href{https://orcid.org/0000-0003-0748-6624}{ORCID}) } } mlr3misc/man/as_short_string.Rd0000644000176200001440000000234315211524655016265 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/as_short_string.R \name{as_short_string} \alias{as_short_string} \title{Convert R Object to a Descriptive String} \usage{ as_short_string(x, width = 30L, num_format = "\%.4g") } \arguments{ \item{x}{(\code{any})\cr Arbitrary object.} \item{width}{(\code{integer(1)})\cr Truncate strings to width \code{width}.} \item{num_format}{(\code{character(1)})\cr Used to format numerical scalars via \code{\link[base:sprintf]{base::sprintf()}}.} } \value{ (\code{character(1)}). } \description{ This function is intended to convert any R object to a short descriptive string, e.g. in \code{\link[base:print]{base::print()}} functions. The following rules apply: \itemize{ \item if \code{x} is \code{atomic()} with length 0 or 1: printed as-is. \item if \code{x} is \code{atomic()} with length greater than 1, \code{x} is collapsed with \code{","}, and the resulting string is truncated to \code{trunc_width} characters. \item if \code{x} is an expression: converted to character. \item Otherwise: the class is printed. } If \code{x} is a list, the above rules are applied (non-recursively) to its elements. } \examples{ as_short_string(list(a = 1, b = NULL, "foo", c = 1:10)) } mlr3misc/man/check_operators.Rd0000644000176200001440000000160215211524655016225 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/check_operators.R \name{check_operators} \alias{check_operators} \alias{\%check&&\%} \alias{\%check||\%} \title{Logical Check Operators} \usage{ lhs \%check&&\% rhs lhs \%check||\% rhs } \arguments{ \item{lhs, rhs}{(\verb{function()})\cr \verb{check_*}-functions that return either \code{TRUE} or an error message as a \code{character(1)}.} } \value{ Either \code{TRUE} or a \code{character(1)}. } \description{ Logical AND and OR operators for \verb{check_*}-functions from \code{\link[checkmate:checkmate]{checkmate}}. } \examples{ library(checkmate) x = c(0, 1, 2, 3) check_numeric(x) \%check&&\% check_names(names(x), "unnamed") # is TRUE check_numeric(x) \%check&&\% check_true(all(x < 0)) # fails check_numeric(x) \%check||\% check_character(x) # is TRUE check_number(x) \%check||\% check_flag(x) # fails } mlr3misc/man/printf.Rd0000644000176200001440000000454215211524655014362 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/printf.R \name{printf} \alias{printf} \alias{catf} \alias{messagef} \alias{warningf} \alias{stopf} \title{Functions for Formatted Output and Conditions} \usage{ catf(msg, ..., file = "", wrap = FALSE) messagef(msg, ..., wrap = FALSE, class = NULL) warningf(msg, ..., wrap = FALSE, class = NULL) stopf(msg, ..., wrap = FALSE, class = NULL) } \arguments{ \item{msg}{(\code{character(1)})\cr Format string passed to \code{\link[base:sprintf]{base::sprintf()}}.} \item{...}{(\code{any})\cr Arguments passed down to \code{\link[base:sprintf]{base::sprintf()}}.} \item{file}{(\code{character(1)})\cr Passed to \code{\link[base:cat]{base::cat()}}.} \item{wrap}{(\code{integer(1)} | \code{logical(1)})\cr If set to a positive integer, \code{\link[base:strwrap]{base::strwrap()}} is used to wrap the string to the provided width. If set to \code{TRUE}, the width defaults to \code{0.9 * getOption("width")}. If set to \code{FALSE}, wrapping is disabled (default). If wrapping is enabled, all whitespace characters (\verb{[[:space:]]}) are converted to spaces, and consecutive spaces are converted to a single space.} \item{class}{(\code{character()})\cr Class of the condition (for errors and warnings).} } \description{ \code{catf()}, \code{messagef()}, \code{warningf()} and \code{stopf()} are wrappers around \code{\link[base:cat]{base::cat()}}, \code{\link[base:message]{base::message()}}, \code{\link[base:warning]{base::warning()}} and \code{\link[base:stop]{base::stop()}}, respectively. } \details{ For leanified R6 classes, the call included in the condition is the method call and not the call into the leanified method. } \section{Errors and Warnings}{ Errors and warnings get the classes \verb{mlr3\{error, warning\}} and also inherit from \verb{simple\{Error, Warning\}}. It is possible to give errors and warnings their own class via the \code{class} argument. Doing this, allows to suppress selective conditions via calling handlers, see e.g. \code{\link{globalCallingHandlers}}. When a function throws such a condition that the user might want to disable, a section \emph{Errors and Warnings} should be included in the function documentation, describing the condition and its class. } \examples{ messagef(" This is a rather long \%s on multiple lines which will get wrapped. ", "string", wrap = 15) } mlr3misc/man/compose.Rd0000644000176200001440000000121015211524655014512 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/compose.R \name{compose} \alias{compose} \title{Composition of Functions} \usage{ compose(...) } \arguments{ \item{...}{(\code{functions})\cr Functions to compose.} } \value{ (\verb{function()}) which calls the functions provided via \code{...} in reverse order. } \description{ Composes two or more functions into a single function. The returned function calls all provided functions in reverse order: The return value of the last function serves as input for the next to last function, and so on. } \examples{ f = compose(function(x) x + 1, function(x) x / 2) f(10) } mlr3misc/man/get_seed.Rd0000644000176200001440000000066015211524655014634 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/get_seed.R \name{get_seed} \alias{get_seed} \title{Get the Random Seed} \usage{ get_seed() } \value{ \code{integer()}. Depends on the \code{\link[base:RNGkind]{base::RNGkind()}}. } \description{ Retrieves the current random seed (\code{.Random.seed} in the global environment), and initializes the RNG first, if necessary. } \examples{ str(get_seed()) } mlr3misc/man/modify_if.Rd0000644000176200001440000000215215211524655015020 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/modify.R \name{modify_if} \alias{modify_if} \alias{modify_at} \title{Selectively Modify Elements of a Vector} \usage{ modify_if(.x, .p, .f, ...) modify_at(.x, .at, .f, ...) } \arguments{ \item{.x}{(\code{vector()}).} \item{.p}{(\verb{function()})\cr Predicate function.} \item{.f}{(\verb{function()})\cr Function to apply on \code{.x}.} \item{...}{(\code{any})\cr Additional arguments passed to \code{.f}.} \item{.at}{((\code{integer()} | \code{character()}))\cr Index vector to select elements from \code{.x}.} } \description{ Modifies elements of a vector selectively, similar to the functions in \CRANpkg{purrr}. \code{modify_if()} applies a predicate function \code{.p} to all elements of \code{.x} and applies \code{.f} to those elements of \code{.x} where \code{.p} evaluates to \code{TRUE}. \code{modify_at()} applies \code{.f} to those elements of \code{.x} selected via \code{.at}. } \examples{ x = modify_if(iris, is.factor, as.character) str(x) x = modify_at(iris, 5, as.character) x = modify_at(iris, "Sepal.Length", sqrt) str(x) } mlr3misc/man/reorder_vector.Rd0000644000176200001440000000171515211524655016103 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/reorder_vector.R \name{reorder_vector} \alias{reorder_vector} \title{Reorder Vector According to Second Vector} \usage{ reorder_vector(x, y, na_last = NA) } \arguments{ \item{x}{(\verb{vector())}.} \item{y}{(\code{vector()}).} \item{na_last}{(\code{logical(1)})\cr What to do with values in \code{x} which are not in \code{y}? \itemize{ \item \code{NA}: Extra values are removed. \item \code{FALSE}: Extra values are moved to the beginning of the new vector. \item \code{TRUE}: Extra values are moved to the end of the new vector. }} } \value{ (\code{integer()}). } \description{ Returns an integer vector to order vector \code{x} according to vector \code{y}. } \examples{ # x subset of y x = c("b", "a", "c", "d") y = letters x[reorder_vector(x, y)] # y subset of x y = letters[1:3] x[reorder_vector(x, y)] x[reorder_vector(x, y, na_last = TRUE)] x[reorder_vector(x, y, na_last = FALSE)] } mlr3misc/man/formulate.Rd0000644000176200001440000000203015211524655015044 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/formulate.R \name{formulate} \alias{formulate} \title{Create Formulas} \usage{ formulate(lhs = character(), rhs = character(), env = NULL, quote = "right") } \arguments{ \item{lhs}{(\code{character()})\cr Left-hand side of formula. Multiple elements will be collapsed with \code{" + "}.} \item{rhs}{(\code{character()})\cr Right-hand side of formula. Multiple elements will be collapsed with \code{" + "}.} \item{env}{(\code{environment()})\cr Environment for the new formula. Defaults to \code{NULL}.} \item{quote}{(\code{character(1)})\cr Which side of the formula to quote? Subset of \verb{("left", "right")}, defaulting to \code{"right"}.} } \value{ \code{\link[stats:formula]{stats::formula()}}. } \description{ Given the left-hand side and right-hand side as character vectors, generates a new \code{\link[stats:formula]{stats::formula()}}. } \examples{ formulate("Species", c("Sepal.Length", "Sepal.Width")) formulate(rhs = c("Sepal.Length", "Sepal.Width")) } mlr3misc/man/hash_input.Rd0000644000176200001440000000201315211524655015211 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/calculate_hash.R \name{hash_input} \alias{hash_input} \alias{hash_input.function} \alias{hash_input.data.table} \alias{hash_input.default} \title{Hash Input} \usage{ hash_input(x) \method{hash_input}{`function`}(x) \method{hash_input}{data.table}(x) \method{hash_input}{default}(x) } \arguments{ \item{x}{(\code{any})\cr Object for which to retrieve the hash input.} } \description{ Returns the part of an object to be used to calculate its hash. } \section{Methods (by class)}{ \itemize{ \item \code{hash_input(`function`)}: The formals and the body are returned in a \code{list()}. This ensures that the bytecode or parent environment are not included. in the hash. \item \code{hash_input(data.table)}: The data.table is converted to a regular list and \code{hash_input()} is applied to all elements. The conversion to a list ensures that keys and indices are not included in the hash. \item \code{hash_input(default)}: Returns the object as is. }} mlr3misc/man/catn.Rd0000644000176200001440000000123315211524655013777 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/catn.R \name{catn} \alias{catn} \title{Function for Formatted Output} \usage{ catn(..., file = "") } \arguments{ \item{...}{(\code{any})\cr Arguments passed down to \code{\link[base:paste0]{base::paste0()}}.} \item{file}{(\code{character(1)})\cr Passed to \code{\link[base:cat]{base::cat()}}.} } \description{ Wrapper around \code{\link[base:cat]{base::cat()}} with a line break. Elements are converted to character and concatenated with \code{\link[base:paste0]{base::paste0()}}. If a vector is passed, elements are collapsed with line breaks. } \examples{ catn(c("Line 1", "Line 2")) } mlr3misc/man/recycle_vectors.Rd0000644000176200001440000000124515211524655016250 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/recycle_vector.R \name{recycle_vectors} \alias{recycle_vectors} \title{Recycle List of Vectors to Common Length} \usage{ recycle_vectors(.x) } \arguments{ \item{.x}{(\code{list()}).} } \value{ (\code{list()}) with vectors of same size. } \description{ Repeats all vectors of a list \code{.x} to the length of the longest vector using \code{\link[=rep]{rep()}} with argument \code{length.out}. This operation will only work if the length of the longest vectors is an integer multiple of all shorter vectors, and will throw an exception otherwise. } \examples{ recycle_vectors(list(a = 1:3, b = 2)) } mlr3misc/man/strip_srcrefs.Rd0000644000176200001440000000133515211524655015745 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/strip_srcrefs.R \name{strip_srcrefs} \alias{strip_srcrefs} \title{Strip source references from objects} \usage{ strip_srcrefs(x, ...) } \arguments{ \item{x}{(\code{any})\cr The object to strip of source references.} \item{...}{(\code{any})\cr Additional arguments to the method.} } \description{ Source references can make objects unexpectedly large and are undesirable in many situations. As \CRANpkg{renv} installs packages with the \code{--with-keep.source} option, we sometimes need to remove source references from objects. Methods should remove source references from the input, but should otherwise leave the input unchanged. } \keyword{internal} mlr3misc/man/register_namespace_callback.Rd0000644000176200001440000000201115211524655020521 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/register_namespace_callback.R \name{register_namespace_callback} \alias{register_namespace_callback} \title{Registers a Callback on Namespace load/unLoad Events} \usage{ register_namespace_callback(pkgname, namespace, callback) } \arguments{ \item{pkgname}{(\code{character(1)})\cr Name of the package which registers the callback.} \item{namespace}{(\code{character(1)})\cr Namespace to react on.} \item{callback}{(\verb{function()})\cr Function to call on namespace load. The callback is invoked without arguments, so it can be defined as \verb{function()} or \verb{function(...)}. Any arguments passed by the hook caller (e.g. \code{package} and \code{lib_path} from \code{pkgload}) are discarded.} } \value{ \code{NULL}. } \description{ Register a function \code{callback} to be called after a namespace is loaded. Calls \code{callback} once if the namespace has already been loaded before and also adds an unload-hook that removes the load hook. } mlr3misc/man/chunk_vector.Rd0000644000176200001440000000256415211524655015554 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/chunk.R \name{chunk_vector} \alias{chunk_vector} \alias{chunk} \title{Chunk Vectors} \usage{ chunk_vector(x, n_chunks = NULL, chunk_size = NULL, shuffle = TRUE) chunk(n, n_chunks = NULL, chunk_size = NULL, shuffle = TRUE) } \arguments{ \item{x}{(\code{vector()})\cr Vector to split into chunks.} \item{n_chunks}{(\code{integer(1)})\cr Requested number of chunks. Mutually exclusive with \code{chunk_size} and \code{props}.} \item{chunk_size}{(\code{integer(1)})\cr Requested number of elements in each chunk. Mutually exclusive with \code{n_chunks} and \code{props}.} \item{shuffle}{(\code{logical(1)})\cr If \code{TRUE}, permutes the order of \code{x} before chunking.} \item{n}{(\code{integer(1)})\cr Length of vector to split.} } \value{ \code{chunk()} returns a \code{integer()} of chunk indices, \code{chunk_vector()} a \code{list()} of \code{integer} vectors. } \description{ Chunk atomic vectors into parts of roughly equal size. \code{chunk()} takes a vector length \code{n} and returns an integer with chunk numbers. \code{chunk_vector()} uses \code{\link[base:split]{base::split()}} and \code{chunk()} to split an atomic vector into chunks. } \examples{ x = 1:11 ch = chunk(length(x), n_chunks = 2) table(ch) split(x, ch) chunk_vector(x, n_chunks = 2) chunk_vector(x, n_chunks = 3, shuffle = TRUE) } mlr3misc/man/map_values.Rd0000644000176200001440000000152115211524655015206 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/map_values.R \name{map_values} \alias{map_values} \title{Replace Elements of Vectors with New Values} \usage{ map_values(x, old, new) } \arguments{ \item{x}{(\verb{vector())}.} \item{old}{(\code{vector()})\cr Vector with values to replace.} \item{new}{(\code{vector()})\cr Values to replace with. Will be forced to the same length as \code{old} with \code{\link[base:rep_len]{base::rep_len()}}.} } \value{ (\code{vector()}) of the same length as \code{x}. } \description{ Replaces all values in \code{x} which match \code{old} with values in \code{new}. Values are matched with \code{\link[base:match]{base::match()}}. } \examples{ x = letters[1:5] # replace all "b" with "_b_", and all "c" with "_c_" old = c("b", "c") new = c("_b_", "_c_") map_values(x, old, new) } mlr3misc/man/load_dataset.Rd0000644000176200001440000000143015211524655015475 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/load_dataset.R \name{load_dataset} \alias{load_dataset} \title{Retrieve a Single Data Set} \usage{ load_dataset(id, package, keep_rownames = FALSE) } \arguments{ \item{id}{(\code{character(1)})\cr Name of the data set.} \item{package}{(\code{character(1)})\cr Package to load the data set from.} \item{keep_rownames}{(\code{logical(1)})\cr Keep possible row names (default: \code{FALSE}).} } \description{ Loads a data set with name \code{id} from package \code{package} and returns it. If the package is not installed, an error with condition "packageNotFoundError" is raised. The name of the missing packages is stored in the condition as \code{packages}. } \examples{ head(load_dataset("iris", "datasets")) } mlr3misc/man/as_callback.Rd0000644000176200001440000000161015211524655015270 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Callback.R \name{as_callback} \alias{as_callback} \alias{as_callback.Callback} \alias{as_callbacks} \alias{as_callbacks.NULL} \alias{as_callbacks.list} \alias{as_callbacks.Callback} \title{Convert to a Callback} \usage{ as_callback(x, ...) \method{as_callback}{Callback}(x, clone = FALSE, ...) as_callbacks(x, clone = FALSE, ...) \method{as_callbacks}{`NULL`}(x, ...) \method{as_callbacks}{list}(x, clone = FALSE, ...) \method{as_callbacks}{Callback}(x, clone = FALSE, ...) } \arguments{ \item{x}{(\code{any})\cr Object to convert.} \item{...}{(\code{any})\cr Additional arguments.} \item{clone}{(\code{logical(1)})\cr If \code{TRUE}, ensures that the returned object is not the same as the input \code{x}.} } \value{ \link{Callback}. } \description{ Convert object to a \link{Callback} or a list of \link{Callback}. } mlr3misc/man/str_trunc.Rd0000644000176200001440000000125515211524655015101 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_trunc.R \name{str_trunc} \alias{str_trunc} \title{Truncate Strings} \usage{ str_trunc(str, width = 0.9 * getOption("width"), ellipsis = "[...]") } \arguments{ \item{str}{(\code{character()})\cr Vector of strings.} \item{width}{(\code{integer(1)})\cr Width of the output.} \item{ellipsis}{(\code{character(1)})\cr If the string has to be shortened, this is signaled by appending \code{ellipsis} to \code{str}. Default is \code{"[...]"}.} } \value{ (\code{character()}). } \description{ \code{str_trunc()} truncates a string to a given width. } \examples{ str_trunc("This is a quite long string", 20) } mlr3misc/man/rcbind.Rd0000644000176200001440000000151715211524655014320 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rcbind.R \name{rcbind} \alias{rcbind} \title{Bind Columns by Reference} \usage{ rcbind(x, y) } \arguments{ \item{x}{(\code{\link[data.table:data.table]{data.table::data.table()}})\cr \code{\link[data.table:data.table]{data.table::data.table()}} to add columns to.} \item{y}{(\code{\link[data.table:data.table]{data.table::data.table()}})\cr \code{\link[data.table:data.table]{data.table::data.table()}} to take columns from.} } \value{ (\code{\link[data.table:data.table]{data.table::data.table()}}): Updated \code{x} . } \description{ Performs \code{\link[base:cbind]{base::cbind()}} on \link[data.table:data.table]{data.tables}, possibly by reference. } \examples{ x = data.table::data.table(a = 1:3, b = 3:1) y = data.table::data.table(c = runif(3)) rcbind(x, y) } mlr3misc/man/clbk.Rd0000644000176200001440000000113115211524655013762 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Callback.R \name{clbk} \alias{clbk} \alias{clbks} \title{Syntactic Sugar for Callback Construction} \usage{ clbk(.key, ...) clbks(.keys) } \arguments{ \item{.key}{(\code{character(1)})\cr Key of the object to construct.} \item{...}{(named \code{list()})\cr Named arguments passed to the state of the callback.} \item{.keys}{(\code{character()})\cr Keys of the objects to construct.} } \description{ Functions to retrieve callbacks from \link{mlr_callbacks} and set parameters in one go. } \seealso{ Callback call_back } mlr3misc/man/macros/0000755000176200001440000000000014455233002014040 5ustar liggesusersmlr3misc/man/macros/cite.Rd0000644000176200001440000000012314455233002015247 0ustar liggesusers\newcommand{\cite}{\Sexpr[results=rd,stage=build]{mlr3misc::cite_bib("#1", "#2")}} mlr3misc/man/check_packages_installed.Rd0000644000176200001440000000220215211524655020021 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/check_packages_installed.R \name{check_packages_installed} \alias{check_packages_installed} \title{Check that packages are installed, without loading them} \usage{ check_packages_installed( pkgs, warn = TRUE, msg = "The following packages are required but not installed: \%s" ) } \arguments{ \item{pkgs}{(\code{character()})\cr Packages to check.} \item{warn}{(\code{logical(1)})\cr If \code{TRUE}, signals a warning of class \code{"packageNotFoundWarning"} about the missing packages.} \item{msg}{(\code{character(1)})\cr Format of the warning message. Use \code{"\%s"} as placeholder for the list of packages.} } \value{ (\code{logical()}) named with package names. \code{TRUE} if the respective package is installed, \code{FALSE} otherwise. } \description{ Calls \code{\link[=find.package]{find.package()}} to check if the all packages are installed. } \examples{ check_packages_installed(c("mlr3misc", "foobar"), warn = FALSE) # catch warning tryCatch(check_packages_installed(c("mlr3misc", "foobaaar")), packageNotFoundWarning = function(w) as.character(w)) } mlr3misc/man/named_vector.Rd0000644000176200001440000000104615211524655015522 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/named_vector.R \name{named_vector} \alias{named_vector} \title{Create a Named Vector} \usage{ named_vector(nn = character(0L), init = NA) } \arguments{ \item{nn}{(\code{character()})\cr Names of new vector} \item{init}{(\code{atomic})\cr All vector elements are initialized to this value.} } \value{ (named \code{vector()}). } \description{ Creates a simple atomic vector with \code{init} as values. } \examples{ named_vector(c("a", "b"), NA) named_vector(character()) } mlr3misc/man/compat-map.Rd0000644000176200001440000001217315211524655015115 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/purrr_map.R \name{compat-map} \alias{compat-map} \alias{map} \alias{map_lgl} \alias{map_int} \alias{map_dbl} \alias{map_chr} \alias{map_br} \alias{map_bc} \alias{map_dtr} \alias{map_dtc} \alias{pmap} \alias{pmap_lgl} \alias{pmap_int} \alias{pmap_dbl} \alias{pmap_chr} \alias{pmap_dtr} \alias{pmap_dtc} \alias{imap} \alias{imap_lgl} \alias{imap_int} \alias{imap_dbl} \alias{imap_chr} \alias{imap_dtr} \alias{imap_dtc} \alias{keep} \alias{discard} \alias{compact} \alias{map_if} \alias{map_if.default} \alias{map_at} \alias{every} \alias{some} \alias{detect} \alias{walk} \alias{iwalk} \alias{pwalk} \title{Apply Functions in the spirit of 'purrr'} \usage{ map(.x, .f, ...) map_lgl(.x, .f, ...) map_int(.x, .f, ...) map_dbl(.x, .f, ...) map_chr(.x, .f, ...) map_br(.x, .f, ...) map_bc(.x, .f, ...) map_dtr(.x, .f, ..., .fill = FALSE, .idcol = NULL) map_dtc(.x, .f, ...) pmap(.x, .f, ...) pmap_lgl(.x, .f, ...) pmap_int(.x, .f, ...) pmap_dbl(.x, .f, ...) pmap_chr(.x, .f, ...) pmap_dtr(.x, .f, ..., .fill = FALSE, .idcol = NULL) pmap_dtc(.x, .f, ...) imap(.x, .f, ...) imap_lgl(.x, .f, ...) imap_int(.x, .f, ...) imap_dbl(.x, .f, ...) imap_chr(.x, .f, ...) imap_dtr(.x, .f, ..., .fill = FALSE, .idcol = NULL) imap_dtc(.x, .f, ...) keep(.x, .f, ...) discard(.x, .p, ...) compact(.x) map_if(.x, .p, .f, ...) \method{map_if}{default}(.x, .p, .f, ...) map_at(.x, .at, .f, ...) every(.x, .p, ...) some(.x, .p, ...) detect(.x, .p, ...) walk(.x, .f, ...) iwalk(.x, .f, ...) pwalk(.x, .f, ...) } \arguments{ \item{.x}{(\code{list()} | atomic \code{vector()}).} \item{.f}{(\verb{function()} | \code{character()} | \code{integer()})\cr Function to apply, or element to extract by name (if \code{.f} is \code{character()}) or position (if \code{.f} is \code{integer()}).} \item{...}{(\code{any})\cr Additional arguments passed down to \code{.f} or \code{.p}.} \item{.fill}{(\code{logical(1)})\cr Passed down to \code{\link[data.table:rbindlist]{data.table::rbindlist()}}.} \item{.idcol}{(\code{logical(1)})\cr Passed down to \code{\link[data.table:rbindlist]{data.table::rbindlist()}}.} \item{.p}{(\verb{function()} | \code{logical()})\cr Predicate function.} \item{.at}{(\code{character()} | \code{integer()} | \code{logical()})\cr Index vector.} } \description{ \code{map}-like functions, similar to the ones implemented in \CRANpkg{purrr}: \itemize{ \item \code{map()} returns the results of \code{.f} applied to \code{.x} as list. If \code{.f} is not a function, \code{map} will call \code{[[} on all elements of \code{.x} using the value of \code{.f} as index. \item \code{imap()} applies \code{.f} to each value of \code{.x} (passed as first argument) and its name (passed as second argument). If \code{.x} does not have names, a sequence along \code{.x} is passed as second argument instead. \item \code{pmap()} expects \code{.x} to be a list of vectors of equal length, and then applies \code{.f} to the first element of each vector of \code{.x}, then the second element of \code{.x}, and so on. \item \code{map_if()} applies \code{.f} to each element of \code{.x} where the predicate \code{.p} evaluates to \code{TRUE}. \item \code{map_at()} applies \code{.f} to each element of \code{.x} referenced by \code{.at}. All other elements remain unchanged. \item \code{keep()} keeps those elements of \code{.x} where predicate \code{.p} evaluates to \code{TRUE}. \item \code{discard()} discards those elements of \code{.x} where predicate \code{.p} evaluates to \code{TRUE}. \item \code{compact()} discards elements of \code{.x} that are \code{NULL}. \item \code{every()} is \code{TRUE} if predicate \code{.p} evaluates to \code{TRUE} for each \code{.x}. \item \code{some()} is \code{TRUE} if predicate \code{.p} evaluates to \code{TRUE} for at least one \code{.x}. \item \code{detect()} returns the first element where predicate \code{.p} evaluates to \code{TRUE}. \item \code{walk()}, \code{iwalk()} and \code{pwalk()} are the counterparts to \code{map()}, \code{imap()} and \code{pmap()}, but just visit (or change by reference) the elements of \code{.x}. They return input \code{.x} invisibly. } Additionally, the functions \code{map()}, \code{imap()} and \code{pmap()} have type-safe variants with the following suffixes: \itemize{ \item \verb{*_lgl()} returns a \code{logical(length(.x))}. \item \verb{*_int()} returns a \code{integer(length(.x))}. \item \verb{*_dbl()} returns a \code{double(length(.x))}. \item \verb{*_chr()} returns a \code{character(length(.x))}. \item \verb{*_br()} returns an object where the results of \code{.f} are put together with \code{\link[base:rbind]{base::rbind()}}. \item \verb{*_bc()} returns an object where the results of \code{.f} are put together with \code{\link[base:cbind]{base::cbind()}}. \item \verb{*_dtr()} returns a \code{\link[data.table:data.table]{data.table::data.table()}} where the results of \code{.f} are put together in an \code{\link[base:rbind]{base::rbind()}} fashion. \item \verb{*_dtc()} returns a \code{\link[data.table:data.table]{data.table::data.table()}} where the results of \code{.f} are put together in an \code{\link[base:cbind]{base::cbind()}} fashion. } } mlr3misc/man/sequence_helpers.Rd0000644000176200001440000000145315211524655016410 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/seq.R \name{sequence_helpers} \alias{sequence_helpers} \alias{seq_row} \alias{seq_col} \alias{seq_len0} \alias{seq_along0} \title{Sequence Construction Helpers} \usage{ seq_row(x) seq_col(x) seq_len0(n) seq_along0(x) } \arguments{ \item{x}{(\code{any})\cr Arbitrary object. Used to query its rows, cols or length.} \item{n}{(\code{integer(1)})\cr Length of the sequence.} } \description{ \code{seq_row()} creates a sequence along the number of rows of \code{x}, \code{seq_col()} a sequence along the number of columns of \code{x}. \code{seq_len0()} and \code{seq_along0()} are the 0-based counterparts to \code{\link[base:seq_len]{base::seq_len()}} and \code{\link[base:seq_along]{base::seq_along()}}. } \examples{ seq_len0(3) } mlr3misc/man/calculate_hash.Rd0000644000176200001440000000147415211524655016021 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/calculate_hash.R \name{calculate_hash} \alias{calculate_hash} \title{Calculate a Hash for Multiple Objects} \usage{ calculate_hash(...) } \arguments{ \item{...}{(\code{any})\cr Objects to hash.} } \value{ (\code{character(1)}). } \description{ Calls \code{\link[digest:digest]{digest::digest()}} using the 'xxhash64' algorithm after applying \code{\link{hash_input}} to each object. To customize the hashing behaviour, you can overwrite \code{\link{hash_input}} for specific classes. For \code{data.table} objects, \code{\link{hash_input}} is applied to all columns, so you can overwrite \code{\link{hash_input}} for columns of a specific class. Objects that don't have a specific method are hashed as is. } \examples{ calculate_hash(iris, 1, "a") } mlr3misc/man/ids.Rd0000644000176200001440000000061215211524655013631 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ids.R \name{ids} \alias{ids} \title{Extract ids from a List of Objects} \usage{ ids(xs) } \arguments{ \item{xs}{(\code{list()})\cr Every element must have a slot 'id'.} } \value{ (\code{character()}). } \description{ None. } \examples{ xs = list(a = list(id = "foo", a = 1), bar = list(id = "bar", a = 2)) ids(xs) } mlr3misc/man/deprecated_binding.Rd0000644000176200001440000000165015211524655016647 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/warn_deprecated.R \name{deprecated_binding} \alias{deprecated_binding} \title{Create an Active Binding that Generates a Deprecation Warning} \usage{ deprecated_binding(what, value) } \arguments{ \item{what}{(\code{character(1)})\cr A description of the deprecated binding. Should be of the form \code{"Class$field"}.} \item{value}{(any)\cr The value of the active binding. This should be an expression that will be evaluated in the context of the active binding. It could, for example, refer to \code{self}.} } \description{ Creates an active binding that generates a warning when accessed, using \code{warn_deprecated()}. The active binding will otherwise be read-only. } \examples{ MyClass = R6::R6Class("MyClass", public = list(), active = list( foo = deprecated_binding("MyClass$foo", "bar") ) ) mco = MyClass$new() mco$foo } \keyword{internal} mlr3misc/man/format_bib.Rd0000644000176200001440000000237215211524655015163 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/format_bib.R \name{format_bib} \alias{format_bib} \alias{cite_bib} \title{Format Bibentries in Roxygen} \usage{ format_bib(..., bibentries = NULL, envir = parent.frame()) cite_bib(..., bibentries = NULL, envir = parent.frame()) } \arguments{ \item{...}{(\code{character()})\cr One or more names of bibentries.} \item{bibentries}{(named \code{list()})\cr Named list of bibentries.} \item{envir}{(\code{environment})\cr Environment to lookup \code{bibentries} if not provided.} } \value{ (\code{character(1)}). } \description{ Operates on a named list of \code{\link[=bibentry]{bibentry()}} entries and formats them nicely for documentation with \CRANpkg{roxygen2}. \itemize{ \item \code{format_bib()} is intended to be called in the \verb{@references} section and prints the complete entry using \code{\link[=toRd]{toRd()}}. \item \code{cite_bib()} returns the family name of the first author (if available, falling back to the complete author name if not applicable) and the year in format \code{"[LastName] (YYYY)"}. } } \examples{ bibentries = list(checkmate = citation("checkmate"), R = citation()) format_bib("checkmate") format_bib("R") cite_bib("checkmate") cite_bib("checkmate", "R") } mlr3misc/man/call_back.Rd0000644000176200001440000000043415211524655014747 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Callback.R \name{call_back} \alias{call_back} \title{Call Callbacks} \usage{ call_back(stage, callbacks, context) } \description{ Call list of callbacks with context at specific stage. } \keyword{internal} mlr3misc/man/require_namespaces.Rd0000644000176200001440000000224615211524655016732 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/require_namespaces.R \name{require_namespaces} \alias{require_namespaces} \title{Require Multiple Namespaces} \usage{ require_namespaces( pkgs, msg = "The following packages could not be loaded: \%s", quietly = FALSE ) } \arguments{ \item{pkgs}{(\code{character()})\cr Packages to load.} \item{msg}{(\code{character(1)})\cr Message to print on error. Use \code{"\%s"} as placeholder for the list of packages.} \item{quietly}{(\code{logical(1)})\cr If \code{TRUE} then returns \code{TRUE} if all packages are loaded, otherwise \code{FALSE}.} } \value{ (\code{character()}) of loaded packages (invisibly). } \description{ Packages are loaded (not attached) via \code{\link[base:requireNamespace]{base::requireNamespace()}}. If at least one package can not be loaded, an exception of class "packageNotFoundError" is raised. The character vector of missing packages is stored in the condition as \code{packages}. } \examples{ require_namespaces("mlr3misc") # catch condition, return missing packages tryCatch(require_namespaces(c("mlr3misc", "foobaaar")), packageNotFoundError = function(e) e$packages) } mlr3misc/man/unnest.Rd0000644000176200001440000000216415211524655014372 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/unnest.R \name{unnest} \alias{unnest} \title{Unnest List Columns} \usage{ unnest(x, cols, prefix = NULL) } \arguments{ \item{x}{(\code{\link[data.table:data.table]{data.table::data.table()}})\cr \code{\link[data.table:data.table]{data.table::data.table()}} with columns to unnest.} \item{cols}{(\code{character()})\cr Column names of list columns to operate on.} \item{prefix}{(\code{logical(1)} | \code{character(1)})\cr String to prefix the new column names with. Use \code{"{col}"} (without the quotes) as placeholder for the original column name.} } \value{ (\code{\link[data.table:data.table]{data.table::data.table()}}). } \description{ Transforms list columns to separate columns, possibly by reference. The original columns are removed from the returned table. All non-atomic objects in the list columns are expanded to new list columns. } \examples{ x = data.table::data.table( id = 1:2, value = list(list(a = 1, b = 2), list(a = 2, b = 2)) ) print(x) unnest(data.table::copy(x), "value") unnest(data.table::copy(x), "value", prefix = "{col}.") } mlr3misc/man/topo_sort.Rd0000644000176200001440000000243215211524655015104 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/topo_sort.R \name{topo_sort} \alias{topo_sort} \title{Topological Sorting of Dependency Graphs} \usage{ topo_sort(nodes) } \arguments{ \item{nodes}{(\code{\link[data.table:data.table]{data.table::data.table()}})\cr Has 2 columns: \itemize{ \item \code{id} of type \code{character}, contains all node labels. \item \code{parents} of type \code{list} of \code{character}, contains all direct parents label of \code{id}. }} } \value{ (\code{\link[data.table:data.table]{data.table::data.table()}}) with columns \code{id}, \code{depth}, sorted topologically for IDs. } \description{ Topologically sort a graph, where we are passed node labels and a list of direct parents for each node, as labels, too. A node can be 'processed' if all its parents have been 'processed', and hence occur at previous indices in the resulting sorting. Returns a table, in topological row order for IDs, and an entry \code{depth}, which encodes the topological layer, starting at 0. So nodes with \code{depth == 0} are the ones with no dependencies, and the one with maximal \code{depth} are the ones on which nothing else depends on. } \examples{ nodes = rowwise_table( ~id, ~parents, "a", "b", "b", "c", "c", character() ) topo_sort(nodes) } mlr3misc/man/figures/0000755000176200001440000000000014455233002014220 5ustar liggesusersmlr3misc/man/figures/logo.png0000644000176200001440000001636014455233002015674 0ustar liggesusers‰PNG  IHDRE(Vü…ØsBIT|dˆ pHYsµØ0¶tEXtSoftwarewww.inkscape.org›î<mIDATxœíÝ”Üu}ïñ×û;»›‚V0 ø ±¶^!ázÅvŸ3C"—ëuÕ¶x0·¤õÚSu­éÁ’Ð^Q~ µ,*ÖìÎ÷;.¸"j$ xQ¨W‹”‹Ò+„Ël0›ìÎ÷}ÿØ]HBv³;¿>óy>ÎÉñÝÌ÷ub²ûÌw¾óSäÖ_|Žd++/ÙñA ¤8@=uÕûsë/>Gf—K²Ü¯³Šüý’y½POQ=l:ˆ.“dÓ?uNnæË%·¹~@hu‹•܆MgK~¹ZWV®>—3F eÕ%ŠD3#вjŽ¢yÑ Â´¤š®)Z`IÒ9¹õ›.ã#ÐjªŽ“ÜúdºBÕ„•ëŠÊ5ç~€3F UTE5Ñ Â´GQ]‚haZæ®A$I¦÷å6\ò%®1¡Í;Fr6­—üJÕù†Ó3.¯\ýÑrÆ„2¯(jl=3…0Á4ŠšDÏÌ!Œ@s†NsƒH’üý]6mâ#Ðl³ÆNóƒhŠKÞuö% #ÐL¹þd  ÚËɹ×ß¹<½»\t|ÐažE¹³7¾WÒU D3Nν>8ašaŸ(ʽñ½ò–¢„hŠg¢¨ƒha.'µtÍ Œ@Cårë/>K²«ÕºA4ƒ0 Ó%Ó)jý ’$¹ûI:k`±®¯åqrë7Þ&ÓËëµkaüã•«?vólÍmØø-I¯iâ g™>[¹ê¼/96uU®>ïì܆K&$è1srý°¢‰B­A$I2½D En‡Íùaéh ´ÍS_⸴‚H2¯óÔ‡$]z̬¦‚(¯k>>z hOSO› ¤•cv¬W+†AšàÙk‰Z1Œ\?¬ìî*D Ñö½ÀºµÂhKewWA7þÙŽÐC@û{î«ÎZ#Œ¶TÆ»òh–¿&ŒÌ®oò‰ Ì~¢´òÔQÍ#‚1÷Moî¯41Œ"ÌÁïdÝœ0"ˆ@Pó{{™0’¾Rÿ vW¥g÷iiþïyvs¥²ãè÷ª®adwUzÆ×èKŸx¢~ °p {#غ†AZÇ¢HªSD µ,<Ф½Ã膅ÿb‚´žê¢Hš £³´€0rÓÝhEÕG‘´ 0rÓÝ©‹ -©¶(’æFÏÑÕç=^óñ ö(’æ #‚dA}¢H:`D +êEÒ³ad~#A²¤¾Q$M…ÑÑcg¥»ºz "] yÔII¼—ÈŒúŸ)È ¢@D€$¢@Q ‰(DHjÔ}ŠZûg=Òá!¦¾e®›t‘›Ù¬={ËEÑ÷Ò´*kÔç6lüš¤ç7êñçb©>3ùåónŸíã¹ ¯—tt'=Ëíó•kÎgûpnæË$?¾™“žá~iåš}=ȱ¬q7ot"S›zä_:ȧügIÇ5cËsùs~T¾Ê¤×5k;ÇÖ·B€VÀÛ|ˆ(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@’Ôz »J¥Òa===Ý¡wTcrrÒóùüã¡w uE€ª™Ù­'…ÞQ =­ƒ§ÏDH"Š$5ðš"3]&iY£Îc»~Q™ãã.¿&’Ñ´A{1ÓOçÚ&÷Ìì»Mš³³ÜÝiˆÐ¸À Pµ8Ž·JÊì…Ö…BïƒxOŸˆ(DH"Š$E’ˆ"I ¼OQ׆—¸ly£.‘û¥ל·m¶wmØô·.½°™›f˜ù5“WwÇlÖoú´™^ÖÄIÏ0«üãäUç„86¡5,ŠÜõn™٨ǟKj^’4k¹üí’ŽkÞ¢½Žêû’f"™Ÿ.éuM´—4µ{$E€ŽÄÓg"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$©«=,Óá |üYYýzÎOp/+²Ÿ6iÎ>Lþà\\ßñHs~N£X¤ûC€V`¡²+Žã­’N ½£Z…BïƒxOŸˆ(DH"Š$E’ˆ"ID€$¢@Q ©±o󠎆††ž'i…™EÑá’Iê2³CÝý©éOÛ!éé4Míêêz¸¯¯ïé`ƒÛÄààà’åË—¯ô¢J¥²ÔÌ–K’™-OÓtÌÌö˜ÙXš¦»r¹Ü¸™íسgÏck×®}"ðt ­•ËåC'''_EёӗšY·»Gf¶TÒw*—ËíLÓt§¤cccô÷÷ïší1¹½9ÐbÊåò‘išž¬©·N8AÒñÓÿ»¸Š‡{ÚÌþÍÝæî÷EQtoš¦?,‹Ûë¹¹ŒŒŒ,Ÿ˜˜xƒ¤ß7³%(é•’žWÍã™Ù“’œù‘¦éföãÅ‹oëíí¯Óìàx›4Ò¶mÛº}ôÑ×HZ)é„(ŠŽMÓô83;VÒ’*ö)3ûwÿ¤‡Ýý3{ØÌàØèèèÒÝ»wŸêîI§J:® ‡ýß’~àîÉ’%K’ÞÞÞM8fK]<>>þfIEI§HzšsIÁIwKÚâî?Ìårßëëë{´ Çm¢õ4}föiš¾ÕÌNq÷תºVãßùÃ0::ºx×®]kÍìLI}šz*,”qw¿UÒÍ;wî¼y®SËY7Bg˜Y¿»¯‘thèM’*’FÍì&IßÈçó‡´DjuË-·¾dÉ’3Üý’Þ¤êÏÕêAþ0 n†‡‡WDQ4zG Æ …Bo#$Éqîþ§föw?¼‘Ǫ†™=™¦é ¹\îò¾¾¾{Cï©—R©ôº(ŠÎ‘ôîVü}ßË„¤oKºáˆ#ŽøúÊ•+'B:¢h_årùÐ4Mo¯çc6Ù…BáÃ>ÈÀÀ@´jÕª¾(ŠÞ7}–<ä? g<È…Ö¨›žžžžÉÉÉׇÞQ­ék@bxxxuEåîk%EîÞ¨CÕÄÝ7³¤iúá8އÌì‚|>¿5ô®j¸»%IòVI!éÔVý=ßO·¤Ó$¶}ûö‡ã8¾ÔÝ/-‹;BÃüT*•œ™eöë »7ôLåèèèÒ]»v½×Ì>"éøû{iDÐ@I’¼ÖÝ?+i]è- d’Ö¹ûº8Ž“4Mÿò´ÓNûièQóU*• årùs’þSè-58JÒçÌìü8Ž?EÑÿäՄȪÁÁÁžeË–5>>þ3[zϸ»qŸ" n½õÖ߉ãøJw¿[Ù ¢ýå£(º;Žã/$IòüÐcæR.—_ÇñmfVr÷,ÑÞž/éÂ4M–$Iè1ÀBLŸ±=sÙ²e÷Kº\RK‘$™QÔ“»[Ç&&&~.élµÏ R»$}ØÝފߘ‡††žÇñeišn•ôæÐ{äw¿©T*}{ddä%¡Ç3<<||’$ßv÷ë%zÏ|´Ël ¸áááI’ IºJÒï„ÞÓ /p÷›â8þj«œ5ŠãøÝQýLÒûÕ_ÓÌlÍäääO’$93ôà@sI’|2Š¢{%½%ôžàLP¥Ri]E?ÑÔ=o:Á»Üýž$IV…pË-·Çñ ¤4³†ÚÈrw¿>I’+FGG›uà Êåò1‡vØwÜýo4õÂ,!Š€Z D¥RéoÌìŸ%zO“íî·—J¥õÍ>p’$§,Z´èIïhö±[‰»Ÿ³{÷îï–Ëå#Co’$ɧiz»¿)ô–*E@µFFF–¯^½z³™}Rû–9‹ÍìêR©ôwîޔ߃R©ôQwÿŽ™q]$w_¦é–8ŽO½+Žã÷¹ûfUù¶8­‚(ª$É‹*•ÊwÕ9O—ÍÉÌ>–$Éu£££ »ÍG©TZ”$ÉÕf¶I¼™õþ^!é{ÃÃÿz:ËôõCWhê•eYÿ{É™"`¡Êåò«Ü}K½ä»^Îܵk×?5"Œ’$y¾™}ÇÝ›þT]†EÑ­I’ünè!è Û¶më^¶lÙWÝýœÐ[ê„(bhhèÄ4MG%½4ô–Vdfo¿v`` n_[†‡‡W¸ûw$½¡^ÙÆŽt÷oóç U*•=öØcƒj£ëú¸y#°ÃÃÿ—ËånW ß|¬EüñêÕ«7Õㆆ†^EÑ$½¶×!^EQidddyè!hOƒƒƒ=föMwÿ¯¡·Ô7oæ©T*½:Š¢ÛÔy¯0«ÖŸÅq|n-0<<üÒ(ŠF5u½ æÕ“““_©ç;@šzÅí²eË®“”½¥ø ÄæÍ›’‹ Z¨‹’$é­ænÞ¼ù¨(Šnãf5Y·jÕª¿=íeõêÕ_”ô®Ð;„3EÀ\FFF–wuu•øæ\•.w¿©\./èöþ›7o~AWW×­’ŽmЮŽafŸ*—Ë\‹…ºˆãøhêÎñíŠ(f3::Ú511q³¤ß½%ÃŽHÓôºù>S*•uuuÝ"éU ÞÕ)riš~etttiè!ȶ8Žû$]zGƒEÀlÆÇÇ/2³5¡w´Þ“O>ùOöIînfv¥¤76aS'yÅîÝ»y U+—˯’t“¤\è-FÇñŸHªéBa<ËÝ/>~®ÏI’äS’x“Óp÷söûH¹\>ÔÝ¿!©^ÍÈ™"`Ó7¿»"ôŽ6³$Š¢˜íƒI’ä%}ª‰{:MO.—»$ôdOš¦_p÷Cïh¢ØÛèèèbw¿QÒ’Ð[ÚP_ÇoÛÿ'Ëåò1îþq溡ܽP*•Ö…Þì(•Jï”tVèÍÂ}Š€ýŒ_,nØHK¥Ò¢™ÿضm[·»ß,é7u’‹ÛþºÔ.Žã—M_ã×1¸£5°w?LÒCïhsÇJzæý˶oßþ)w_pOG1³W.[¶ì¿…ÞÖæî¦©7x]zK³eýmzâ M`fŸ(•J×är¹×¤iúñÐ{:Ð_Hº9ô´®$IΑôÖÐ;àL€¦;ÆÌ>”¦é’ºCé@'%IrJèhMföbI…ÞQ ˆ‹%zD§r÷óCo@Ëú]uÆËï„(„…ÐáÖ–J%ÞFØQ(2³w‡´¢:™ýQè @‹áLt"w?qúîí¦EЩÒ4}gè @ !Š Sñ°/nÞ4W*éaIc’vJÚ¡©{õ,•ô¡P(ü<ô _|ÆÚ.iXÒw£(ºwÏž=?[·nÝogûämÛ¶u?òÈ#/¢è ’ÞlfëÜýð¦­m?»Üý¶(ŠI?‘t_¡Px|¶OíÚ½{÷ËÜý’N•ô6I‡5ikîþ&ID@ ±GÒMQ]¶eË– ¤óý…+W®œô‹é×.Yºté;Ìì’^Õ ½mÇ̾'é&&&â¹"t½½½“’îŸþqm¹\>4MÓwIú+I¯hÌÚ°Ìì$uÔ³ Š€:šô…ÉÉɋ׭[÷p=°¿¿—¤ë·mÛöÕÇ{ìCîþ·’×ã±Û‘™Åîþé|>ÿ/õx¼¾¾¾§%]]*•n0³ó$ Hê©Çc·7…hê“Jz@Òîþ™=áîãf¶KÒ3«¤iºÔ̺%*i…™½ÐÝ_,é•’ŽŸþùjE@ü Š¢ôõõÝÛˆŸ>ƒô÷I’ÜáîßôÒF'Ã6³?Ïçó_oă‹ÅÝ’.,•J£fö5IG5â8344ôеk×>z:Çôµ}w˜Ù÷+•Ê9äÿ5}¦¶&###/™œœ\if«ÜýdI«$-™ï¯'Š€Ú¤îþ©­[·^¸§Éª•Ïçïzs.—»CÒ‹}¼Œ(uuuýÑš5kžjôŠÅâ’$ùCwÿ®Ú(Œr¹Ü›4õ/t ‘ž0³¯¥izãÖ­[ïhÄ×Ì5kÖ<$é!IߤÁÁÁžeË–­’ô‡f¶ÖÝOÒì7®æLPƒ§%Y,oiæA×®]û@’$Ew¿SÒ¢f»}~llìýýý•f0ŸÏߟ$Ißôï-§ê[†™­’tmèh[?•ô9w¿¥P(ìnæûûû÷Húþô ’$y‘¤ÓÝý%ýíû>ŒDP¥î¾¦X,þ(ÄÁóùü=qRÒE!Žß"þ²P(|>Äóùü}qXmî~bè hKw¹û…BáŸÍÌC‘¤|>ÿ%]&é²R©tlEïq÷³5uæ›7UØcfïD3ÆÆÆ6ºû¿…ÜС‚hF¡P¸NRrC½E¨³1I¾óÎ;W‹Åo¶Jí¯X,þ2ŸÏzllìåîþ'’îâL°@fvf>ŸþͰ¿¿¿’$ÉEîÞQ/§v÷/‹ÅO†Þ!Ifv¾»¿E¿>ÓÌ^¸yóæ¬[·î±Ð[mfçr¹L_Û“ ÓO±Ý(éFÎ si>Ÿ =bÆ¢E‹nÐÔ]±;Å}•Jå#¡GÌÈçó÷IúfèõÐÝÝÍÙ"ÔÂ%}¦¯¯ï´,Ñþˆ"`þîY¼xñù¡Gì­··w\SwÌî¿u÷þ…ÜŒ±Iþ>ô€zp÷W‡Þ€ÌzZÒ/ ­úTÙ|EÀüLJzÏt„´3kȽyZÐg‹Å⿆±¿B¡ð}MÝ<ëN=™ôDEP(¾zH=EÀü|±P(ü$ôˆ™˜˜¸]S§®ÛÙ/Ý}SèsÈü73ã¾WX¨ßJz[__ß]¡‡Ô QÜ£ãããŸ=b6ÓǶõzFQôÑé»J·¤4M3]‘»¯½™²ÇÌÞ>}¦´mEÀA¸û…gœqÆ“¡wÄBh ­}}}C¡GÌåC¹KS/CↀLÙÐ ¯Â­7¢˜ÛãK–,¹*ôˆyhɧöêÁÌZþ•ÓïÙôÃÐ;jafœ)¼˜Ù•…Bá†Ð;(æàî—öööî ½ã`̬å.@®“ûwìØ‘•§¦¶„P w_^*•:ýmcpî~ïÄÄÄGCïh¢˜ÝDOOÏ¥¡GÌÇÄÄÄÏBoh/6ó}Íjáî÷…ÞP#ëîîæ)4Ìe"—˽»o‹Q7D0 w/¿å-oy$ôŽùX»ví(û×´ì¯bfÿzÄ|¥išõ(Rš¦G„Þ€Öef—öõõÝzG#EÀì2󜹙¹™ý:ôŽ:»múÍ3aÅŠ÷KÊÄY­Ù¤iº$ô´¬GwíÚõ™Ð#(lÇÎ;¿zÄB¤iÚVQäî7†Þ°+W®œô›Ð;jÄ5E8 wÿë ¼ ·fDpî>Òßß¿+ôŽj§(J%Å¡GTáW¡Ôˆ(Â<¼sçÎëBh¢8€(Šn ½a¡ÌìáÐêèÇÅbq{è åîYÿÿ€(Âs¸û%Óï$ßöˆ"àÒ4 ½¡ ™‹ˆ9|;ô€jDQôxè 5"а¿±îîî+Ch¢x®‹Åâ/C¨BÖ¿!ïí¶ÐªáîO…ÞP£Å¡ å|yÍš5Yÿs=oDð\? = föDè u’îÙ³gkèUÊú7Îaf–©<ÔŠ(žëîЪáîír¦è§Ÿ~zVï¹ôtè5Ê…€ÖáîõõõýKèÍDÏ•É(Š¢¨]ÎÝz@µÌ¬#.FEgˆ¢è«fæ¡w4QìËÍìÇ¡GT#MÓñÐê$³Qäî¡7õâî_½¡Ùˆ"`_äóùL> •ËåÚâ,…™eö}ÜÌŒ(B»xjll,“gÍkAûú÷Ъ599Ùߣ(Êâ+ÿ$IîÎ×T´w¿#+oÆ\Oüöâîîîv8STyòÉ'ÿOèÕr÷žÐ€:¹=ô€ˆ"`/Qe6Šºººv‡ÞP¿ÊøsyI;ÚBEß ½!¢Ø‹»?zCµn¿ýö,ÇÄŒÌF©$™Ywè @L¦izOè!EÀ^ÜýÑЪ500Jš ½£F„P#Ρü²X,¶Ã™ç#Š€}eý^?™>[äî…ÞP#¢™—åW€ÖŠ(öEQ¦¿)gýæQeöL$¹û’ЀZ¥iú¯¡7„B{©T*ÿ/ô†Z¸{¦£HÒöÐjEÑ!¡7uðóÐB!Š€½tuueõ=·fd:ŠÒ4ÍôÓ—œ)B›øuè¡EÀ^zzz²~qa¦o¶ff»Bo¨o¨Švð›ÐB!Š€gyoooÖ_½•iQe=Š€ÌëééÉú«@«FÏj‹·ÉÈ2wo—7µ²jâÔSOÍäû?ÖQ<+Ó×ã´ƒJ¥Â™" ¬ífæ¡G„BÓÌŒ§Î‹¢ˆ0Âúmè!EZFš¦û/T túSØD$™YÖ_[¢Ì ŠDHîÞÑ/8!ŠDH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’ˆ"ID€$¢@Q ‰(DH"Š$E’¤ÿ+»#3‰GÖIEND®B`‚mlr3misc/man/to_decimal.Rd0000644000176200001440000000127715211524655015162 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/to_decimal.R \name{to_decimal} \alias{to_decimal} \title{Convert a Vector of Bits to a Decimal Number} \usage{ to_decimal(bits) } \arguments{ \item{bits}{(\code{logical()})\cr Logical vector of input values. Missing values are not allowed. If \code{bits} is longer than 30 elements, an exception is raised.} } \value{ (\code{integer(1)}). } \description{ Converts a logical vector from binary to decimal. The bit vector may have any length, the last position is the least significant, i.e. bits are multiplied with \code{2^(n-1)}, \code{2^(n-2)}, ..., \code{2^1}, \code{2^0} where \code{n} is the length of the bit vector. } mlr3misc/man/Callback.Rd0000644000176200001440000001306115211524655014550 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Callback.R \name{Callback} \alias{Callback} \title{Callback} \description{ Callbacks allow to customize the behavior of processes in mlr3 packages. The following packages implement callbacks: \itemize{ \item \code{CallbackOptimization} in \CRANpkg{bbotk}. \item \code{CallbackTuning} in \CRANpkg{mlr3tuning}. \item \code{CallbackTorch} in \href{https://github.com/mlr-org/mlr3torch}{\code{mlr3torch}} } } \details{ \link{Callback} is an abstract base class. A subclass inherits from \link{Callback} and adds stages as public members. Names of stages should start with \code{"on_"}. For each subclass a function should be implemented to create the callback. For an example on how to implement such a function see \code{callback_optimization()} in \CRANpkg{bbotk}. Callbacks are executed at stages using the function \code{\link[=call_back]{call_back()}}. A \link{Context} defines which information can be accessed from the callback. } \examples{ library(R6) # implement callback subclass CallbackExample = R6Class("CallbackExample", inherit = mlr3misc::Callback, public = list( on_stage_a = NULL, on_stage_b = NULL, on_stage_c = NULL ) ) } \section{Public fields}{ \if{html}{\out{
}} \describe{ \item{\code{id}}{(\code{character(1)})\cr Identifier of the callback.} \item{\code{label}}{(\code{character(1)})\cr Label for this object. Can be used in tables, plot and text output instead of the ID.} \item{\code{man}}{(\code{character(1)})\cr String in the format \verb{[pkg]::[topic]} pointing to a manual page for this object. Defaults to \code{NA}, but can be set by child classes.} \item{\code{state}}{(named \code{list()})\cr A callback can write data into the state.} } \if{html}{\out{
}} } \section{Methods}{ \subsection{Public methods}{ \itemize{ \item \href{#method-Callback-initialize}{\code{Callback$new()}} \item \href{#method-Callback-format}{\code{Callback$format()}} \item \href{#method-Callback-print}{\code{Callback$print()}} \item \href{#method-Callback-help}{\code{Callback$help()}} \item \href{#method-Callback-call}{\code{Callback$call()}} \item \href{#method-Callback-clone}{\code{Callback$clone()}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Callback-initialize}{}}} \subsection{\code{Callback$new()}}{ Creates a new instance of this \link[R6:R6Class]{R6} class. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Callback$new(id, label = NA_character_, man = NA_character_)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{id}}{(\code{character(1)})\cr Identifier for the new instance.} \item{\code{label}}{(\code{character(1)})\cr Label for the new instance.} \item{\code{man}}{(\code{character(1)})\cr String in the format \verb{[pkg]::[topic]} pointing to a manual page for this object. The referenced help package can be opened via method \verb{$help()}.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Callback-format}{}}} \subsection{\code{Callback$format()}}{ Helper for print outputs. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Callback$format(...)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{...}}{(ignored).} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Callback-print}{}}} \subsection{\code{Callback$print()}}{ Printer. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Callback$print(...)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{...}}{(ignored).} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Callback-help}{}}} \subsection{\code{Callback$help()}}{ Opens the corresponding help page referenced by field \verb{$man}. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Callback$help()} \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Callback-call}{}}} \subsection{\code{Callback$call()}}{ Call the specific stage for a given context. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Callback$call(stage, context)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{stage}}{(\code{character(1)})\cr stage.} \item{\code{context}}{(\code{Context})\cr Context.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Callback-clone}{}}} \subsection{\code{Callback$clone()}}{ The objects of this class are cloneable with this method. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Callback$clone(deep = FALSE)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{deep}}{Whether to make a deep clone.} } \if{html}{\out{
}} } } } mlr3misc/man/did_you_mean.Rd0000644000176200001440000000124315211524655015507 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/did_you_mean.R \name{did_you_mean} \alias{did_you_mean} \title{Suggest Alternatives} \usage{ did_you_mean(str, candidates) } \arguments{ \item{str}{(\code{character(1)})\cr String.} \item{candidates}{(\code{character()})\cr Candidate strings.} } \value{ (\code{character(1)}). Either a phrase suggesting one or more candidates from \code{candidates}, or an empty string if no close match is found. } \description{ Helps to suggest alternatives from a list of strings, based on the string similarity in \code{\link[utils:adist]{utils::adist()}}. } \examples{ did_you_mean("yep", c("yes", "no")) } mlr3misc/man/insert_named.Rd0000644000176200001440000000324615211524655015530 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/insert_named.R, R/remove_named.R \name{insert_named} \alias{insert_named} \alias{insert_named.NULL} \alias{insert_named.default} \alias{insert_named.environment} \alias{insert_named.data.frame} \alias{insert_named.data.table} \alias{remove_named} \alias{remove_named.environment} \alias{remove_named.data.frame} \alias{remove_named.data.table} \title{Insert or Remove Named Elements} \usage{ insert_named(x, y) \method{insert_named}{`NULL`}(x, y) \method{insert_named}{default}(x, y) \method{insert_named}{environment}(x, y) \method{insert_named}{data.frame}(x, y) \method{insert_named}{data.table}(x, y) remove_named(x, nn) \method{remove_named}{environment}(x, nn) \method{remove_named}{data.frame}(x, nn) \method{remove_named}{data.table}(x, nn) } \arguments{ \item{x}{(\code{vector()} | \code{list()} | \code{environment()} | \code{\link[data.table:data.table]{data.table::data.table()}})\cr Object to insert elements into, or remove elements from. Changes are by-reference for environments and data tables.} \item{y}{(\code{list()})\cr List of elements to insert into \code{x}.} \item{nn}{(\code{character()})\cr Character vector of elements to remove.} } \value{ Modified object. } \description{ Insert elements from \code{y} into \code{x} by name, or remove elements from \code{x} by name. Works for vectors, lists, environments and data frames and data tables. Objects with reference semantic (\code{environment()} and \code{\link[data.table:data.table]{data.table::data.table()}}) might be modified in-place. } \examples{ x = list(a = 1, b = 2) insert_named(x, list(b = 3, c = 4)) remove_named(x, "b") } mlr3misc/man/named_list.Rd0000644000176200001440000000076115211524655015176 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/named_list.R \name{named_list} \alias{named_list} \title{Create a Named List} \usage{ named_list(nn = character(0L), init = NULL) } \arguments{ \item{nn}{(\code{character()})\cr Names of new list.} \item{init}{(\code{any})\cr All list elements are initialized to this value.} } \value{ (named \code{list()}). } \description{ Create a Named List } \examples{ named_list(c("a", "b")) named_list(c("a", "b"), init = 1) } mlr3misc/man/count_missing.Rd0000644000176200001440000000077515211524655015745 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/count_missing.R \name{count_missing} \alias{count_missing} \title{Count Missing Values in a Vector} \usage{ count_missing(x) } \arguments{ \item{x}{\code{\link[=vector]{vector()}}\cr Supported are logical, integer, double, complex and string vectors.} } \value{ (\code{integer(1)}) number of missing values. } \description{ Same as \code{sum(is.na(x))}, but without the allocation. } \examples{ count_missing(c(1, 2, NA, 4, NA)) } mlr3misc/man/get_private.Rd0000644000176200001440000000110315211524655015357 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/get_private.R \name{get_private} \alias{get_private} \title{Extract Private Fields of R6 Objects} \usage{ get_private(x) } \arguments{ \item{x}{(\code{any})\cr Object to extract the private members from.} } \value{ \code{environment()} of private members, or \code{NULL} if \code{x} is not an R6 object. } \description{ Provides access to the private members of \link[R6:R6Class]{R6::R6Class} objects. } \examples{ library(R6) item = R6Class("Item", private = list(x = 1))$new() get_private(item)$x } mlr3misc/man/cross_join.Rd0000644000176200001440000000136415211524655015227 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cross_join.R \name{cross_join} \alias{cross_join} \title{Cross-Join for data.table} \usage{ cross_join(dots, sorted = TRUE, unique = FALSE) } \arguments{ \item{dots}{(named \code{list()})\cr Vectors to cross-join.} \item{sorted}{(\code{logical(1)})\cr See \code{\link[data.table:CJ]{data.table::CJ()}}.} \item{unique}{(\code{logical(1)})\cr See \code{\link[data.table:CJ]{data.table::CJ()}}.} } \value{ \code{\link[data.table:data.table]{data.table::data.table()}}. } \description{ A safe version of \code{\link[data.table:CJ]{data.table::CJ()}} in case a column is called \code{sorted} or \code{unique}. } \examples{ cross_join(dots = list(sorted = 1:3, b = letters[1:2])) } mlr3misc/man/shuffle.Rd0000644000176200001440000000116715211524655014514 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/shuffle.R \name{shuffle} \alias{shuffle} \title{Safe Version of Sample} \usage{ shuffle(x, n = length(x), ...) } \arguments{ \item{x}{(\code{vector()})\cr Vector to sample elements from.} \item{n}{(\code{integer()})\cr Number of elements to sample.} \item{...}{(\code{any})\cr Arguments passed down to \code{\link[base:sample.int]{base::sample.int()}}.} } \description{ A version of \code{sample()} which does not treat positive scalar integer \code{x} differently. See example. } \examples{ x = 2:3 sample(x) shuffle(x) x = 3 sample(x) shuffle(x) } mlr3misc/man/assert_callback.Rd0000644000176200001440000000106015211524655016165 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Callback.R \name{assert_callback} \alias{assert_callback} \alias{assert_callbacks} \title{Assertions for Callbacks} \usage{ assert_callback(callback, null_ok = FALSE) assert_callbacks(callbacks) } \arguments{ \item{callback}{(\link{Callback}).} \item{null_ok}{(\code{logical(1)})\cr If \code{TRUE}, \code{NULL} is allowed.} \item{callbacks}{(list of \link{Callback}).} } \value{ \link{Callback} | List of \link{Callback}s. } \description{ Assertions for \link{Callback} class. } mlr3misc/man/set_class.Rd0000644000176200001440000000070615211524655015036 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/set_class.R \name{set_class} \alias{set_class} \title{Set the Class} \usage{ set_class(x, classes) } \arguments{ \item{x}{(\code{any}).} \item{classes}{(\code{character()})\cr Vector of new class names.} } \value{ Object \code{x}, with updated class attribute. } \description{ Simple wrapper for \code{class(x) = classes}. } \examples{ set_class(list(), c("foo1", "foo2")) } mlr3misc/man/compute_mode.Rd0000644000176200001440000000153515211524655015537 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/compute_mode.R \name{compute_mode} \alias{compute_mode} \title{Compute The Mode} \usage{ compute_mode(x, ties_method = "random", na_rm = TRUE) } \arguments{ \item{x}{(\code{vector()}).} \item{ties_method}{(\code{character(1)})\cr Handling of ties. One of "first", "last" or "random" to return the first tied value, the last tied value, or a randomly selected tied value, respectively.} \item{na_rm}{(\code{logical(1)})\cr If \code{TRUE}, remove missing values prior to computing the mode.} } \value{ (\code{vector(1)}): mode value. } \description{ Computes the mode (most frequent value) of an atomic vector. } \examples{ compute_mode(c(1, 1, 1, 2, 2, 2, 3)) compute_mode(c(1, 1, 1, 2, 2, 2, 3), ties_method = "last") compute_mode(c(1, 1, 1, 2, 2, 2, 3), ties_method = "random") } mlr3misc/man/open_help.Rd0000644000176200001440000000057115211524655015027 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/open_help.R \name{open_help} \alias{open_help} \title{Opens a Manual Page} \usage{ open_help(man) } \arguments{ \item{man}{(\code{character(1)})\cr Manual page to open in "package::topic" syntax.} } \value{ Nothing. } \description{ Simply opens a manual page specified in "package::topic" syntax. } mlr3misc/man/get_private-set.Rd0000644000176200001440000000144215211524655016156 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/get_private.R \name{get_private<-} \alias{get_private<-} \title{Assign Value to Private Field} \usage{ get_private(x, which) <- value } \arguments{ \item{x}{(\code{any})\cr Object whose private field should be modified.} \item{which}{(character(1))\cr Private field that is being modified.} \item{value}{(\code{any})\cr Value to assign to the private field.} } \value{ The R6 instance x, modified in-place. If it is not an R6 instance, NULL is returned. } \description{ Convenience function to assign a value to a private field of an \link[R6:R6Class]{R6::R6Class} instance. } \examples{ library(R6) item = R6Class("Item", private = list(x = 1))$new() get_private(item)$x get_private(item, "x") = 2L get_private(item)$x } mlr3misc/man/leanify_r6.Rd0000644000176200001440000000350415211524655015113 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/leanify.R \name{leanify_r6} \alias{leanify_r6} \alias{leanify_package} \title{Move all methods of an R6 Class to an environment} \usage{ leanify_r6(cls, env = cls$parent_env) leanify_package(pkg_env = parent.frame(), skip_if = function(x) FALSE) } \arguments{ \item{cls}{(\link[R6:R6Class]{R6::R6Class})\cr Class generator to modify.} \item{env}{(\code{environment})\cr The target environment where the function should be stored. This should be either \code{cls$parent_env} (default) or one of its parent environments, otherwise the stump function will not find the moved (original code) function.} \item{pkg_env}{:: \code{environment}\cr The namespace from which to leanify all R6 classes. Does not have to be a package namespace, but this is the intended usecase.} \item{skip_if}{:: \code{function}\cr Function with one argument: Is called for each individual \code{\link[R6:R6Class]{R6::R6Class}}. If it returns \code{TRUE}, the class is skipped. Default function evaluating to \code{FALSE} always (i.e. skipping no classes).} } \value{ \code{NULL}. } \description{ \code{leanify_r6} moves the content of an \code{\link[R6:R6Class]{R6::R6Class}}'s functions to an environment, usually the package's namespace, to save space during serialization of R6 objects. \code{leanify_package} move all methods of \emph{all} R6 Classes to an environment. The function in the class (i.e. the object generator) is replaced by a stump function that does nothing except calling the original function that now resides somewhere else. It is possible to call this function after the definition of an \link[R6:R6]{R6::R6} class inside a package, but it is preferred to use \code{\link[=leanify_package]{leanify_package()}} to just leanify all \link[R6:R6]{R6::R6} classes inside a package. } mlr3misc/man/nin.Rd0000644000176200001440000000056715211524655013647 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nin.R \name{\%nin\%} \alias{\%nin\%} \title{Negated in-operator} \usage{ x \%nin\% y } \arguments{ \item{x}{(\code{vector()})\cr Values that should not be in \code{y}.} \item{y}{(\code{vector()})\cr Values to match against.} } \description{ This operator is equivalent to \code{!(x \%in\% y)}. } mlr3misc/man/assert_ro_binding.Rd0000644000176200001440000000102615211524655016545 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/assert_ro_binding.R \name{assert_ro_binding} \alias{assert_ro_binding} \title{Assertion for Active Bindings in R6 Classes} \usage{ assert_ro_binding(rhs) } \arguments{ \item{rhs}{(\code{any})\cr If not missing, an exception is raised.} } \value{ Nothing. } \description{ This assertion is intended to be called in active bindings of an \link[R6:R6Class]{R6::R6Class} which does not allow assignment. If \code{rhs} is not missing, an exception is raised. } mlr3misc/man/is_scalar_na.Rd0000644000176200001440000000052215211524655015470 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/is_scalar_na.R \name{is_scalar_na} \alias{is_scalar_na} \title{Check for a Single Scalar Value} \usage{ is_scalar_na(x) } \arguments{ \item{x}{(\code{any})\cr Argument to check.} } \value{ (\code{logical(1)}). } \description{ Check for a Single Scalar Value } mlr3misc/man/with_package.Rd0000644000176200001440000000147415211524655015507 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/with_package.R \name{with_package} \alias{with_package} \title{Execute code with a modified search path} \usage{ with_package(package, code, ...) } \arguments{ \item{package}{(\code{character(1)})\cr Name of the package to attach.} \item{code}{(\code{expression})\cr Code to run.} \item{...}{(\code{any})\cr Additional arguments passed to \code{\link[=library]{library()}}.} } \value{ Result of the evaluation of \code{code}. } \description{ Attaches a package to the search path (if not already attached), executes code and eventually removes the package from the search path again, restoring the previous state. Note that this function is deprecated in favor of the (now fixed) version in \CRANpkg{withr}. } \seealso{ \CRANpkg{withr} package. } mlr3misc/man/distinct_values.Rd0000644000176200001440000000232415211524655016254 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/distinct_values.R \name{distinct_values} \alias{distinct_values} \title{Get Distinct Values} \usage{ distinct_values(x, drop = TRUE, na_rm = TRUE) } \arguments{ \item{x}{(atomic \code{vector()}).} \item{drop}{:: \code{logical(1)}\cr If \code{TRUE}, only returns values which are present in \code{x}. If \code{FALSE}, returns all levels for \code{\link[=factor]{factor()}} and \code{\link[=ordered]{ordered()}}, as well as \code{TRUE} and \code{FALSE} for \code{\link[=logical]{logical()}}s.} \item{na_rm}{:: \code{logical(1)}\cr If \code{TRUE}, missing values are removed from the vector of distinct values.} } \value{ (atomic \code{vector()}) with distinct values in no particular order. } \description{ Extracts the distinct values of an atomic vector, with the possibility to drop levels and remove missing values. } \examples{ # for factors: x = factor(c(letters[1:2], NA), levels = letters[1:3]) distinct_values(x) distinct_values(x, na_rm = FALSE) distinct_values(x, drop = FALSE) distinct_values(x, drop = FALSE, na_rm = FALSE) # for logicals: distinct_values(TRUE, drop = FALSE) # for numerics: distinct_values(sample(1:3, 10, replace = TRUE)) } mlr3misc/man/extract_vars.Rd0000644000176200001440000000111015211524655015551 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/extract_vars.R \name{extract_vars} \alias{extract_vars} \title{Extract Variables from a Formula} \usage{ extract_vars(f) } \arguments{ \item{f}{(\code{formula()}).} } \value{ (\code{list()}) with elements \code{"lhs"} and \code{"rhs"}, both \code{character()}. } \description{ Given a \code{\link[=formula]{formula()}} \code{f}, returns all variables used on the left-hand side and right-hand side of the formula. } \examples{ extract_vars(Species ~ Sepal.Width + Sepal.Length) extract_vars(Species ~ .) } mlr3misc/man/encapsulate.Rd0000644000176200001440000000756515212015277015370 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/encapsulate.R \name{encapsulate} \alias{encapsulate} \title{Encapsulate Function Calls} \usage{ encapsulate( method, .f, .args = list(), .opts = list(), .pkgs = character(), .seed = NA_integer_, .timeout = Inf, .compute = "default" ) } \arguments{ \item{method}{(\code{character(1)})\cr One of \code{"none"}, \code{"try"}, \code{"evaluate"}, \code{"callr"}, or \code{"mirai"}.} \item{.f}{(\verb{function()})\cr Function to call.} \item{.args}{(\code{list()})\cr Named list of arguments passed to \code{.f}.} \item{.opts}{(named \code{list()})\cr Options to set via \code{\link[=options]{options()}} before calling \code{.f}. Restored on exit.} \item{.pkgs}{(\code{character()})\cr Packages to load via \code{\link[=requireNamespace]{requireNamespace()}} before calling \code{.f}.} \item{.seed}{(\code{integer(1)})\cr Random seed set via \code{\link[=set.seed]{set.seed()}} before calling \code{.f}. If \code{NA} (default), the seed is not changed; for \code{"callr"} and \code{"mirai"} modes the current RNG state is forwarded instead.} \item{.timeout}{(\code{numeric(1)})\cr Timeout in seconds (\code{Inf} for no limit). Uses \code{\link[=setTimeLimit]{setTimeLimit()}} for \code{"none"} and \code{"evaluate"}; passed natively to \code{callr::r()} and \code{mirai::mirai()} for the other modes. A value of \code{0} is treated as an already-elapsed deadline: \code{.f} is not evaluated and the result contains an immediate \code{Mlr3ErrorTimeout} in \code{log}.} \item{.compute}{(\code{character(1)})\cr Compute profile for \code{"mirai"} mode. Passed to \code{mirai::mirai()} as \code{.compute}.} } \value{ Named \code{list()} with three elements: \itemize{ \item \code{"result"}: return value of \code{.f}, or \code{NULL} if an error was caught. \item \code{"elapsed"}: elapsed time in seconds, measured via \code{\link[=proc.time]{proc.time()}}. \item \code{"log"}: \code{data.table()} with columns \code{"class"} (ordered factor with levels \code{"output"}, \code{"warning"}, \code{"error"}) and \code{"condition"} (list of condition objects). Messages are classified as \code{"output"} for historical reasons. Empty when no conditions were captured. } } \description{ Evaluates a function, capturing conditions and measuring elapsed time. There are currently five modes: \itemize{ \item \code{"none"}: Runs the call in the current session. Conditions are signaled normally; no log is kept. Works well together with \code{\link[=traceback]{traceback()}}. \item \code{"try"}: Like \code{"none"}, but catches errors and writes them to the log. Warnings and messages are still signaled. \item \code{"evaluate"}: Uses \CRANpkg{evaluate} to capture errors, warnings, and messages into the log. Printed output is lost. \item \code{"callr"}: Uses \CRANpkg{callr} to run the function in a fresh R session. Errors, warnings, and messages are captured into the log; printed output is lost. Protects the calling session from segfaults at the cost of session startup overhead. The RNG state is propagated back to the calling session after evaluation. \item \code{"mirai"}: Uses \CRANpkg{mirai} to run the function on a daemon. Errors, warnings, and messages are captured into the log; printed output is lost. The daemon can be pre-started via \code{daemons(1)}; if none is running, a new session is started per call. Offers similar safety to \code{"callr"} with lower overhead when a daemon is reused across calls. The RNG state is propagated back to the calling session after evaluation. } } \examples{ f = function(n) { message("hi from f") if (n > 5) { stop("n must be <= 5") } runif(n) } encapsulate("none", f, list(n = 1), .seed = 1) if (requireNamespace("evaluate", quietly = TRUE)) { encapsulate("evaluate", f, list(n = 1), .seed = 1) } if (requireNamespace("callr", quietly = TRUE)) { encapsulate("callr", f, list(n = 1), .seed = 1) } } mlr3misc/man/rd_info.Rd0000644000176200001440000000220215211524655014467 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rd_info.R \name{rd_info} \alias{rd_info} \alias{rd_format_range} \alias{rd_format_string} \alias{rd_format_packages} \title{Helpers to Create Manual Pages} \usage{ rd_info(obj, ...) rd_format_range(lower, upper) rd_format_string(str, quote = c("\\\\dQuote{", "}")) rd_format_packages(packages) } \arguments{ \item{obj}{(\code{any})\cr Object of the respective class.} \item{...}{(\verb{any)})\cr Additional arguments.} \item{lower}{(\code{numeric(1)})\cr Lower bound.} \item{upper}{(\code{numeric(1)})\cr Upper bound.} \item{str}{(\code{character()})\cr Vector of strings.} \item{quote}{(\code{character()})\cr Quotes to use around each element of \code{x}. Will be replicated to length 2.} \item{packages}{(\code{character()})\cr Vector of package names.} } \value{ \code{character()}, possibly with markdown code. } \description{ \code{rd_info()} is an internal generic to generate Rd or markdown code to be used in manual pages. \code{rd_format_string()} and \code{rd_format_range()} are string functions to assist generating proper Rd code. } \keyword{Internal} mlr3misc/man/cat_cli.Rd0000644000176200001440000000124315211524655014451 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cat_cli.R \name{cat_cli} \alias{cat_cli} \title{Function to transform message to output} \usage{ cat_cli(expr) } \arguments{ \item{expr}{(\code{any})\cr Expression that calls \verb{cli_*} methods, \code{\link[base:cat]{base::cat()}} or \code{\link[base:print]{base::print()}} to format an object's printout.} } \description{ Wrapper around \code{\link[cli:cli_format_method]{cli::cli_format_method()}}. Uses \code{\link[base:cat]{base::cat()}} to transform the printout from a message to an output with a line break. } \examples{ cat_cli({ cli::cli_h1("Heading") cli::cli_li(c("x", "y")) }) } mlr3misc/man/as_factor.Rd0000644000176200001440000000143215211524655015014 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/as_factor.R \name{as_factor} \alias{as_factor} \title{Convert to Factor} \usage{ as_factor(x, levels, ordered = is.ordered(x)) } \arguments{ \item{x}{(atomic \code{vector()})\cr Vector to convert to factor.} \item{levels}{(\code{character()})\cr Levels of the new factor.} \item{ordered}{(\code{logical(1)})\cr If \code{TRUE}, create an ordered factor.} } \value{ (\code{factor()}). } \description{ Converts a vector to a \code{\link[=factor]{factor()}} and ensures that levels are in the order of the provided levels. } \examples{ x = factor(c("a", "b")) y = factor(c("a", "b"), levels = c("b", "a")) # x with the level order of y as_factor(x, levels(y)) # y with the level order of x as_factor(y, levels(x)) } mlr3misc/man/enframe.Rd0000644000176200001440000000221015211524655014463 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/enframe.R \name{enframe} \alias{enframe} \alias{deframe} \title{Convert a Named Vector into a data.table and Vice Versa} \usage{ enframe(x, name = "name", value = "value") deframe(x) } \arguments{ \item{x}{(\code{vector()} (\code{enframe()}) or \code{data.frame()} (\code{deframe()}))\cr Vector to convert to a \code{\link[data.table:data.table]{data.table::data.table()}}.} \item{name}{(\code{character(1)})\cr Name for the first column with names.} \item{value}{(\code{character(1)})\cr Name for the second column with values.} } \value{ \code{\link[data.table:data.table]{data.table::data.table()}} or named \code{vector}. } \description{ \code{enframe()} returns a \code{\link[data.table:data.table]{data.table::data.table()}} with two columns: The names of \code{x} (or \code{seq_along(x)} if unnamed) and the values of \code{x}. \code{deframe()} converts a two-column data.frame to a named vector. If the data.frame only has a single column, an unnamed vector is returned. } \examples{ x = 1:3 enframe(x) x = set_names(1:3, letters[1:3]) enframe(x, value = "x_values") } mlr3misc/man/mlr_conditions.Rd0000644000176200001440000000533315211524655016102 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/conditions.R \name{mlr_conditions} \alias{mlr_conditions} \alias{error_config} \alias{error_input} \alias{error_timeout} \alias{error_mlr3} \alias{warning_mlr3} \alias{warning_config} \alias{warning_input} \alias{error_learner} \alias{error_learner_train} \alias{error_learner_predict} \title{Error Classes} \usage{ error_config(msg, ..., class = NULL, parent = NULL, signal = TRUE) error_input(msg, ..., class = NULL, parent = NULL, signal = TRUE) error_timeout(signal = TRUE) error_mlr3(msg, ..., class = NULL, parent = NULL, signal = TRUE) warning_mlr3(msg, ..., class = NULL, signal = TRUE) warning_config(msg, ..., class = NULL, signal = TRUE) warning_input(msg, ..., class = NULL, signal = TRUE) error_learner(msg, ..., class = NULL, parent = NULL, signal = TRUE) error_learner_train(msg, ..., class = NULL, parent = NULL, signal = TRUE) error_learner_predict(msg, ..., class = NULL, parent = NULL, signal = TRUE) } \arguments{ \item{msg}{(\code{character(1)})\cr Error message.} \item{...}{(any)\cr Passed to \code{\link[=sprintf]{sprintf()}}.} \item{class}{(\code{character})\cr Additional class(es).} \item{parent}{(\code{condition} or \code{NULL})\cr Parent condition for error chaining. When provided, the parent error is displayed below the current error message.} \item{signal}{(\code{logical(1)})\cr If \code{FALSE}, the condition object is returned instead of being signaled.} } \description{ Condition classes for mlr3. } \section{Formatting}{ It is also possible to use formatting options as defined in \code{\link[cli:cli_bullets]{cli::cli_bullets}}. } \section{Errors}{ \itemize{ \item \code{error_mlr3()} for the base \code{Mlr3Error} class. \item \code{error_config()} for the \code{Mlr3ErrorConfig} class, which signals that a user has misconfigured something (e.g. invalid learner configuration). \item \code{error_input()} for the \code{Mlr3ErrorInput} class, which signals that an invalid input was provided. \item \code{error_timeout()} for the \code{Mlr3ErrorTimeout}, signalling a timeout (encapsulation). \item \code{error_learner()} for the \code{Mlr3ErrorLearner}, signalling a learner error. \item \code{error_learner_train()} for the \code{Mlr3ErrorLearner}, signalling a learner training error. \item \code{error_learner_predict()} for the \code{Mlr3ErrorLearner}, signalling a learner prediction error. } } \section{Warnings}{ \itemize{ \item \code{warning_mlr3()} for the base \code{Mlr3Warning} class. \item \code{warning_config()} for the \code{Mlr3WarningConfig} class, which signals that a user might have misconfigured something. \item \code{warning_input()} for the \code{Mlr3WarningInput} if an invalid input might have been provided. } } mlr3misc/man/dictionary_sugar_inc_get.Rd0000644000176200001440000000363315211524655020116 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/dictionary_sugar.R \name{dictionary_sugar_inc_get} \alias{dictionary_sugar_inc_get} \alias{dictionary_sugar_inc_mget} \title{A Quick Way to Initialize Objects from Dictionaries with Incremented ID} \usage{ dictionary_sugar_inc_get(dict, .key, ..., .dicts_suggest = NULL) dictionary_sugar_inc_mget(dict, .keys, ..., .dicts_suggest = NULL) } \arguments{ \item{dict}{(\link{Dictionary})\cr Dictionary from which to retrieve an element.} \item{.key}{(\code{character(1)})\cr Key of the object to construct - possibly with a suffix of the form \verb{_} which will be appended to the id.} \item{...}{(\code{any})\cr See description of \link{dictionary_sugar}.} \item{.dicts_suggest}{(named \code{list()}) Named list of \link[=Dictionary]{dictionaries} used to look up suggestions for \code{.key} if \code{.key} does not exist in \code{dict}.} \item{.keys}{(\code{character()})\cr Keys of the objects to construct - possibly with suffixes of the form \verb{_} which will be appended to the ids.} } \value{ An element from the dictionary. } \description{ Convenience wrapper around \link{dictionary_sugar_get} and \link{dictionary_sugar_mget} to allow easier avoidance of ID clashes which is useful when the same object is used multiple times and the ids have to be unique. Let \verb{} be the key of the object to retrieve. When passing the \verb{_} to this function, where \verb{} is any natural number, the object with key \verb{} is retrieved and the suffix \verb{_} is appended to the id after the object is constructed. } \examples{ d = Dictionary$new() d$add("a", R6::R6Class("A", public = list(id = "a"))) d$add("b", R6::R6Class("B", public = list(id = "c"))) obj1 = dictionary_sugar_inc_get(d, "a_1") obj1$id obj2 = dictionary_sugar_inc_get(d, "b_1") obj2$id objs = dictionary_sugar_inc_mget(d, c("a_10", "b_2")) map(objs, "id") } mlr3misc/man/crate.Rd0000644000176200001440000000177515211524655014163 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/crate.R \name{crate} \alias{crate} \title{Isolate a Function from its Environment} \usage{ crate(.fn, ..., .parent = topenv(parent.frame()), .compile = TRUE) } \arguments{ \item{.fn}{(\verb{function()})\cr function to crate} \item{...}{(\code{any})\cr The objects, which should be visible inside \code{.fn}.} \item{.parent}{(\code{environment})\cr Parent environment to look up names. Default to \code{\link[=topenv]{topenv()}}.} \item{.compile}{(\code{logical(1)})\cr Whether to jit-compile the function. In case the function is already compiled. If the input function \code{.fn} is compiled, this has no effect, and the output function will always be compiled.} } \description{ Put a function in a "lean" environment that does not carry unnecessary baggage with it (e.g. references to datasets). } \examples{ meta_f = function(z) { x = 1 y = 2 crate(function() { c(x, y, z) }, x) } x = 100 y = 200 z = 300 f = meta_f(1) f() } mlr3misc/man/set_names.Rd0000644000176200001440000000151415211524655015032 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/set_names.R \name{set_names} \alias{set_names} \alias{set_col_names} \title{Set Names} \usage{ set_names(x, nm = x, ...) set_col_names(x, nm, ...) } \arguments{ \item{x}{(\code{any}.)\cr Object to set names for.} \item{nm}{(\code{character()} | \verb{function()})\cr New names, or a function which transforms already existing names.} \item{...}{(\code{any})\cr Passed down to \code{nm} if \code{nm} is a function.} } \value{ \code{x} with updated names. } \description{ Sets the names (or colnames) of \code{x} to \code{nm}. If \code{nm} is a function, it is used to transform the already existing names of \code{x}. } \examples{ x = letters[1:3] # name x with itself: x = set_names(x) print(x) # convert names to uppercase x = set_names(x, toupper) print(x) } mlr3misc/man/Context.Rd0000644000176200001440000000765715211524655014516 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Context.R \name{Context} \alias{Context} \title{Context} \description{ Context objects allow \link{Callback} objects to access and modify data. The following packages implement context subclasses: \itemize{ \item \code{ContextOptimization} in \CRANpkg{bbotk}. \item \code{ContextEval} in \CRANpkg{mlr3tuning}. \item \code{ContextTorch} in \href{https://github.com/mlr-org/mlr3torch}{\code{mlr3torch}} } } \details{ \link{Context} is an abstract base class. A subclass inherits from \link{Context}. Data is stored in public fields. Access to the data can be restricted with active bindings (see example). } \examples{ library(data.table) library(R6) # data table with column x and y data = data.table(x = runif(10), y = sample(c("A", "B"), 10, replace = TRUE)) # context only allows to access column y ContextExample = R6Class("ContextExample", inherit = Context, public = list( data = NULL, initialize = function(data) { self$data = data } ), active = list( y = function(rhs) { if (missing(rhs)) return(self$data$y) self$data$y = rhs } ) ) context = ContextExample$new(data) # retrieve content of column y context$y # change content of column y to "C" context$y = "C" } \section{Public fields}{ \if{html}{\out{
}} \describe{ \item{\code{id}}{(\code{character(1)})\cr Identifier of the object. Used in tables, plot and text output.} \item{\code{label}}{(\code{character(1)})\cr Label for this object. Can be used in tables, plot and text output instead of the ID.} } \if{html}{\out{
}} } \section{Methods}{ \subsection{Public methods}{ \itemize{ \item \href{#method-Context-initialize}{\code{Context$new()}} \item \href{#method-Context-format}{\code{Context$format()}} \item \href{#method-Context-print}{\code{Context$print()}} \item \href{#method-Context-clone}{\code{Context$clone()}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Context-initialize}{}}} \subsection{\code{Context$new()}}{ Creates a new instance of this \link[R6:R6Class]{R6} class. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Context$new(id, label = NA_character_)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{id}}{(\code{character(1)})\cr Identifier for the new instance.} \item{\code{label}}{(\code{character(1)})\cr Label for the new instance.} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Context-format}{}}} \subsection{\code{Context$format()}}{ Format object as simple string. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Context$format(...)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{...}}{(ignored).} } \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Context-print}{}}} \subsection{\code{Context$print()}}{ Print object. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Context$print()} \if{html}{\out{
}} } } \if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Context-clone}{}}} \subsection{\code{Context$clone()}}{ The objects of this class are cloneable with this method. \subsection{Usage}{ \if{html}{\out{
}} \preformatted{Context$clone(deep = FALSE)} \if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ \item{\code{deep}}{Whether to make a deep clone.} } \if{html}{\out{
}} } } } mlr3misc/man/capitalize.Rd0000644000176200001440000000066715211524655015211 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/capitalize.R \name{capitalize} \alias{capitalize} \title{Capitalize the First Letter of Strings} \usage{ capitalize(str) } \arguments{ \item{str}{(\code{character()}).} } \value{ Character vector, same length as \code{str}. } \description{ Takes a character vector and changes the first letter of each element to uppercase. } \examples{ capitalize("foo bar") } mlr3misc/man/str_collapse.Rd0000644000176200001440000000170515211524655015550 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_collapse.R \name{str_collapse} \alias{str_collapse} \title{Collapse Strings} \usage{ str_collapse(str, sep = ", ", quote = character(), n = Inf, ellipsis = "[...]") } \arguments{ \item{str}{(\code{character()})\cr Vector of strings.} \item{sep}{(\code{character(1)})\cr String used to collapse the elements of \code{x}.} \item{quote}{(\code{character()})\cr Quotes to use around each element of \code{x}. Will be replicated to length 2.} \item{n}{(\code{integer(1)})\cr Number of elements to keep from \code{x}. See \code{\link[utils:head]{utils::head()}}.} \item{ellipsis}{(\code{character(1)})\cr If the string has to be shortened, this is signaled by appending \code{ellipsis} to \code{str}. Default is \code{" [...]"}.} } \value{ (\code{character(1)}). } \description{ Collapse multiple strings into a single string. } \examples{ str_collapse(letters, quote = "'", n = 5) } mlr3misc/DESCRIPTION0000644000176200001440000000544315212172057013521 0ustar liggesusersPackage: mlr3misc Title: Helper Functions for 'mlr3' Version: 0.22.0 Authors@R: c( person("Marc", "Becker", , "marcbecker@posteo.de", role = c("cre", "aut"), comment = c(ORCID = "0000-0002-8115-0400")), person("Michel", "Lang", , "michellang@gmail.com", role = "aut", comment = c(ORCID = "0000-0001-9754-0393")), person("Patrick", "Schratz", , "patrick.schratz@gmail.com", role = "aut", comment = c(ORCID = "0000-0003-0748-6624")) ) Description: Frequently used helper functions and assertions used in 'mlr3' and its companion packages. Comes with helper functions for functional programming, for printing, to work with 'data.table', as well as some generally useful 'R6' classes. This package also supersedes the package 'BBmisc'. License: LGPL-3 URL: https://mlr3misc.mlr-org.com, https://github.com/mlr-org/mlr3misc BugReports: https://github.com/mlr-org/mlr3misc/issues Depends: R (>= 3.4.0) Imports: backports (>= 0.1.5), checkmate, cli, data.table, digest, methods, R6 Suggests: callr, evaluate, mirai, paradox, testthat (>= 3.0.0) Config/testthat/edition: 3 Config/testthat/parallel: true Encoding: UTF-8 NeedsCompilation: yes Collate: 'Dictionary.R' 'named_list.R' 'Callback.R' 'Context.R' 'as_factor.R' 'as_short_string.R' 'assert_ro_binding.R' 'calculate_hash.R' 'capitalize.R' 'cat_cli.R' 'catn.R' 'check_operators.R' 'check_packages_installed.R' 'chunk.R' 'compose.R' 'compute_mode.R' 'conditions.R' 'count_missing.R' 'crate.R' 'cross_join.R' 'dictionary_sugar.R' 'did_you_mean.R' 'distinct_values.R' 'encapsulate.R' 'enframe.R' 'extract_vars.R' 'format_bib.R' 'formulate.R' 'get_private.R' 'get_seed.R' 'has_element.R' 'ids.R' 'insert_named.R' 'invoke.R' 'is_scalar_na.R' 'keep_in_bounds.R' 'leanify.R' 'load_dataset.R' 'map_values.R' 'modify.R' 'named_vector.R' 'names2.R' 'nin.R' 'open_help.R' 'printf.R' 'probe.R' 'purrr_map.R' 'rcbind.R' 'rd_info.R' 'recycle_vector.R' 'register_namespace_callback.R' 'remove_named.R' 'reorder_vector.R' 'require_namespaces.R' 'rowwise_table.R' 'seq.R' 'set_class.R' 'set_names.R' 'set_params.R' 'shuffle.R' 'str_collapse.R' 'str_indent.R' 'str_trunc.R' 'strip_srcrefs.R' 'to_decimal.R' 'topo_sort.R' 'transpose.R' 'unnest.R' 'warn_deprecated.R' 'which_max.R' 'with_package.R' 'zzz.R' Config/roxygen2/version: 8.0.0 Packaged: 2026-06-09 18:30:07 UTC; marc Author: Marc Becker [cre, aut] (ORCID: ), Michel Lang [aut] (ORCID: ), Patrick Schratz [aut] (ORCID: ) Maintainer: Marc Becker Repository: CRAN Date/Publication: 2026-06-10 05:20:47 UTC