diff --git a/.Rbuildignore b/.Rbuildignore index 948c293..5cec232 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -6,6 +6,7 @@ ^Meta$ ^README\.Rmd$ ^README\.html$ +^[\.]?air\.toml$ ^\.Renviron$ ^\.Rproj\.user$ ^\.ccache$ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 41a7962..c804849 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,10 +4,6 @@ repos: - repo: https://github.com/lorenzwalthert/precommit rev: v0.4.3.9008 hooks: - - id: style-files - args: [--style_pkg=styler.mlr, --style_fun=mlr_style] - additional_dependencies: - - mlr-org/styler.mlr - id: roxygenize additional_dependencies: - R6 diff --git a/R/PipeOpFDACor.R b/R/PipeOpFDACor.R index c41319a..218150d 100644 --- a/R/PipeOpFDACor.R +++ b/R/PipeOpFDACor.R @@ -23,7 +23,8 @@ #' po_cor = po("fda.cor") #' task_cor = po_cor$train(list(task))[[1L]] #' task_cor -PipeOpFDACor = R6Class("PipeOpFDACor", +PipeOpFDACor = R6Class( + "PipeOpFDACor", inherit = PipeOpTaskPreprocSimple, public = list( #' @description Initializes a new instance of this Class. diff --git a/R/PipeOpFDAExtract.R b/R/PipeOpFDAExtract.R index e7a965c..157f07b 100644 --- a/R/PipeOpFDAExtract.R +++ b/R/PipeOpFDAExtract.R @@ -49,7 +49,8 @@ #' ) #' task_custom = po_custom$train(list(task))[[1L]] #' task_custom -PipeOpFDAExtract = R6Class("PipeOpFDAExtract", +PipeOpFDAExtract = R6Class( + "PipeOpFDAExtract", inherit = PipeOpTaskPreprocSimple, public = list( #' @description Initializes a new instance of this Class. @@ -63,41 +64,44 @@ PipeOpFDAExtract = R6Class("PipeOpFDAExtract", drop = p_lgl(tags = c("train", "predict", "required")), left = p_dbl(tags = c("train", "predict", "required")), right = p_dbl(tags = c("train", "predict", "required")), - features = p_uty(tags = c("train", "predict", "required"), custom_check = crate(function(x) { - if (test_character(x)) { - return(check_subset(x, choices = c("mean", "median", "min", "max", "slope", "var"))) - } - if (test_list(x)) { - res = check_list(x, types = c("character", "function"), any.missing = FALSE, unique = TRUE) - if (!isTRUE(res)) { - return(res) + features = p_uty( + tags = c("train", "predict", "required"), + custom_check = crate(function(x) { + if (test_character(x)) { + return(check_subset(x, choices = c("mean", "median", "min", "max", "slope", "var"))) } - nms = names2(x) - res = check_names(nms[!is.na(nms)], "unique") - if (!isTRUE(res)) { - return(res) - } - for (i in seq_along(x)) { - if (is.function(x[[i]])) { - res = check_function(x[[i]], args = c("arg", "value")) - if (!isTRUE(res)) { - return(res) - } - res = check_names(nms[i]) - if (!isTRUE(res)) { - return(res) - } - } else { - res = check_choice(x[[i]], choices = c("mean", "median", "min", "max", "slope", "var")) - if (!isTRUE(res)) { - return(res) + if (test_list(x)) { + res = check_list(x, types = c("character", "function"), any.missing = FALSE, unique = TRUE) + if (!isTRUE(res)) { + return(res) + } + nms = names2(x) + res = check_names(nms[!is.na(nms)], "unique") + if (!isTRUE(res)) { + return(res) + } + for (i in seq_along(x)) { + if (is.function(x[[i]])) { + res = check_function(x[[i]], args = c("arg", "value")) + if (!isTRUE(res)) { + return(res) + } + res = check_names(nms[i]) + if (!isTRUE(res)) { + return(res) + } + } else { + res = check_choice(x[[i]], choices = c("mean", "median", "min", "max", "slope", "var")) + if (!isTRUE(res)) { + return(res) + } } } + return(TRUE) } - return(TRUE) - } - "Features must be a character or list" - })) + "Features must be a character or list" + }) + ) ) param_set$set_values( drop = TRUE, @@ -144,7 +148,8 @@ PipeOpFDAExtract = R6Class("PipeOpFDAExtract", if (is.function(feature)) { return(feature) } - switch(feature, + switch( + feature, mean = fmean, median = fmedian, min = fmin, diff --git a/R/PipeOpFDAFlatten.R b/R/PipeOpFDAFlatten.R index 5bb2978..6752ccd 100644 --- a/R/PipeOpFDAFlatten.R +++ b/R/PipeOpFDAFlatten.R @@ -21,7 +21,8 @@ #' task = tsk("fuel") #' pop = po("fda.flatten") #' task_flat = pop$train(list(task)) -PipeOpFDAFlatten = R6Class("PipeOpFDAFlatten", +PipeOpFDAFlatten = R6Class( + "PipeOpFDAFlatten", inherit = PipeOpTaskPreprocSimple, public = list( #' @description Initializes a new instance of this Class. diff --git a/R/PipeOpFDAInterpol.R b/R/PipeOpFDAInterpol.R index 6a9528a..bf89d87 100644 --- a/R/PipeOpFDAInterpol.R +++ b/R/PipeOpFDAInterpol.R @@ -45,7 +45,8 @@ #' pop = po("fda.interpol") #' task_interpol = pop$train(list(task))[[1L]] #' task_interpol$data() -PipeOpFDAInterpol = R6Class("PipeOpFDAInterpol", +PipeOpFDAInterpol = R6Class( + "PipeOpFDAInterpol", inherit = PipeOpTaskPreprocSimple, public = list( #' @description Initializes a new instance of this Class. @@ -56,17 +57,22 @@ PipeOpFDAInterpol = R6Class("PipeOpFDAInterpol", #' otherwise be set during construction. Default `list()`. initialize = function(id = "fda.interpol", param_vals = list()) { param_set = ps( - grid = p_uty(tags = c("train", "predict", "required"), custom_check = crate(function(x) { - if (test_string(x)) { - return(check_choice(x, choices = c("union", "intersect", "minmax"))) - } - if (test_numeric(x, any.missing = FALSE, min.len = 1L)) { - return(TRUE) - } - "Must be either a string or numeric vector" - })), + grid = p_uty( + tags = c("train", "predict", "required"), + custom_check = crate(function(x) { + if (test_string(x)) { + return(check_choice(x, choices = c("union", "intersect", "minmax"))) + } + if (test_numeric(x, any.missing = FALSE, min.len = 1L)) { + return(TRUE) + } + "Must be either a string or numeric vector" + }) + ), method = p_fct( - c("linear", "spline", "fill_extend", "locf", "nocb"), default = "linear", tags = c("train", "predict") + c("linear", "spline", "fill_extend", "locf", "nocb"), + default = "linear", + tags = c("train", "predict") ), left = p_dbl(tags = c("train", "predict")), right = p_dbl(tags = c("train", "predict")) diff --git a/R/PipeOpFDAScaleRange.R b/R/PipeOpFDAScaleRange.R index 5af7bdf..b87d5c9 100644 --- a/R/PipeOpFDAScaleRange.R +++ b/R/PipeOpFDAScaleRange.R @@ -21,7 +21,8 @@ #' po_scale = po("fda.scalerange", lower = -1, upper = 1) #' task_scale = po_scale$train(list(task))[[1L]] #' task_scale$data() -PipeOpFDAScaleRange = R6Class("PipeOpFDAScaleRange", +PipeOpFDAScaleRange = R6Class( + "PipeOpFDAScaleRange", inherit = PipeOpTaskPreproc, public = list( #' @description Initializes a new instance of this Class. diff --git a/R/PipeOpFDASmooth.R b/R/PipeOpFDASmooth.R index 5159e16..8e3a4fc 100644 --- a/R/PipeOpFDASmooth.R +++ b/R/PipeOpFDASmooth.R @@ -31,7 +31,8 @@ #' task_smooth = po_smooth$train(list(task))[[1L]] #' task_smooth #' task_smooth$data(cols = c("NIR", "UVVIS")) -PipeOpFDASmooth = R6Class("PipeOpFDASmooth", +PipeOpFDASmooth = R6Class( + "PipeOpFDASmooth", inherit = PipeOpTaskPreprocSimple, public = list( #' @description Initializes a new instance of this Class. @@ -42,9 +43,14 @@ PipeOpFDASmooth = R6Class("PipeOpFDASmooth", #' otherwise be set during construction. Default `list()`. initialize = function(id = "fda.smooth", param_vals = list()) { param_set = ps( - method = p_fct(default = "lowess", c("lowess", "rollmean", "rollmedian", "savgol"), tags = c("train", "predict")), # nolint + method = p_fct( + default = "lowess", + c("lowess", "rollmean", "rollmedian", "savgol"), + tags = c("train", "predict") + ), args = p_uty( - tags = c("train", "predict", "required"), custom_check = crate(function(x) check_list(x, names = "unique")) + tags = c("train", "predict", "required"), + custom_check = crate(function(x) check_list(x, names = "unique")) ), verbose = p_lgl(tags = c("train", "predict", "required")) ) @@ -72,7 +78,8 @@ PipeOpFDASmooth = R6Class("PipeOpFDASmooth", return(dt) } for (j in seq_along(dt)) { - set(dt, + set( + dt, j = j, value = suppressMessages(invoke(tf::tf_smooth, x = dt[[j]], method = pars$method, .args = pars$args)) ) diff --git a/R/PipeOpFDATsfeatures.R b/R/PipeOpFDATsfeatures.R index db2a818..6250a58 100644 --- a/R/PipeOpFDATsfeatures.R +++ b/R/PipeOpFDATsfeatures.R @@ -38,7 +38,8 @@ #' po_tsfeats = po("fda.tsfeats") #' task_tsfeats = po_tsfeats$train(list(task))[[1L]] #' task_tsfeats$data() -PipeOpFDATsfeatures = R6Class("PipeOpFDATsfeatures", +PipeOpFDATsfeatures = R6Class( + "PipeOpFDATsfeatures", inherit = PipeOpTaskPreprocSimple, public = list( #' @description Initializes a new instance of this Class. diff --git a/R/PipeOpFPCA.R b/R/PipeOpFPCA.R index 79ae9a6..fae708b 100644 --- a/R/PipeOpFPCA.R +++ b/R/PipeOpFPCA.R @@ -28,7 +28,8 @@ #' po_fpca = po("fda.fpca", n_components = 3L) #' task_fpca = po_fpca$train(list(task))[[1L]] #' task_fpca$data() -PipeOpFPCA = R6Class("PipeOpFPCA", +PipeOpFPCA = R6Class( + "PipeOpFPCA", inherit = PipeOpTaskPreproc, public = list( #' @description Initializes a new instance of this Class. diff --git a/R/bibentries.R b/R/bibentries.R index 8a1ce3a..02f8bbd 100644 --- a/R/bibentries.R +++ b/R/bibentries.R @@ -1,7 +1,8 @@ #' @importFrom utils bibentry # nolint start bibentries = c( - ferraty2003curves = bibentry("article", + ferraty2003curves = bibentry( + "article", title = "Curves discrimination: a nonparametric functional approach", author = "Ferraty, Fr\xc3\xa9dric and Vieu, Philippe", journal = "Computational Statistics & Data Analysis", @@ -11,7 +12,8 @@ bibentries = c( year = "2003", publisher = "Elsevier" ), - brockhaus2015functional = bibentry("article", + brockhaus2015functional = bibentry( + "article", title = "The functional linear array model", author = "Brockhaus, Sarah and Scheipl, Fabian and Hothorn, Torsten and Greven, Sonja", journal = "Statistical Modelling", @@ -21,7 +23,8 @@ bibentries = c( year = "2015", publisher = "SAGE Publications Sage India: New Delhi, India" ), - goldsmith2011penalized = bibentry("article", + goldsmith2011penalized = bibentry( + "article", title = "Penalized functional regression", author = "Goldsmith, Jeff and Bobb, Jennifer and Crainiceanu, Ciprian M and Caffo, Brian and Reich, Daniel", journal = "Journal of Computational and Graphical Statistics", diff --git a/R/zzz.R b/R/zzz.R index c5f7e40..1680074 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -64,7 +64,7 @@ register_mlr3pipelines = function() { register_namespace_callback(pkgname, "mlr3pipelines", register_mlr3pipelines) } -.onUnload = function(libPaths) { # nolint +.onUnload = function(libPaths) { walk(names(mlr3fda_tasks), function(nm) mlr_tasks$remove(nm)) walk(names(mlr3fda_pipeops), function(nm) mlr_pipeops$remove(nm)) mlr_reflections$task_feature_types = diff --git a/air.toml b/air.toml new file mode 100644 index 0000000..6cb579d --- /dev/null +++ b/air.toml @@ -0,0 +1,2 @@ +[format] +line-width = 120 diff --git a/inst/bench/bench.R b/inst/bench/bench.R index 9a1d17b..e0a3f36 100644 --- a/inst/bench/bench.R +++ b/inst/bench/bench.R @@ -5,9 +5,7 @@ library(mlr3pipelines) set.seed(1234) setDTthreads(threads = 1) -generate_data = function(n_patients = 100, - n_weeks = 10, - type = c("reg", "irreg")) { +generate_data = function(n_patients = 100, n_weeks = 10, type = c("reg", "irreg")) { type = match.arg(type) if (type == "reg") { week = 1:n_weeks @@ -52,27 +50,29 @@ analyse_dplyr = function(patients, window_start, window_end, choice) { analyse_dt = function(patients, window_start, window_end, choice) { if (choice == "one") { - patients[between(week, window_start, window_end), .( - mean = mean(measurement_value) - ), keyby = .(patient_id, measurement_type)] + patients[ + between(week, window_start, window_end), + .( + mean = mean(measurement_value) + ), + keyby = .(patient_id, measurement_type) + ] } else { - patients[between(week, window_start, window_end), .( - mean = mean(measurement_value), - var = var(measurement_value), - slope = coef(lm(measurement_value ~ week))[[2]] - ), keyby = .(patient_id, measurement_type)] + patients[ + between(week, window_start, window_end), + .( + mean = mean(measurement_value), + var = var(measurement_value), + slope = coef(lm(measurement_value ~ week))[[2]] + ), + keyby = .(patient_id, measurement_type) + ] } } build_graph = function(left, right, choice) { features = switch(choice, one = "mean", three = c("mean", "var", "slope")) - po("ffs", - features = features, - id = "features", - drop = FALSE, - left = left, - right = right - ) + po("ffs", features = features, id = "features", drop = FALSE, left = left, right = right) } analyse_fda = function(graph, task) { @@ -88,7 +88,9 @@ results_one = bench::press( window_end = floor(n_weeks * 0.8) patients = generate_data( - n_patients = n_patients, n_weeks = n_weeks, type = type + n_patients = n_patients, + n_weeks = n_weeks, + type = type ) patients_long = patients |> tidyr::pivot_longer( @@ -129,7 +131,9 @@ results_three = bench::press( window_end = floor(n_weeks * 0.8) patients = generate_data( - n_patients = n_patients, n_weeks = n_weeks, type = type + n_patients = n_patients, + n_weeks = n_weeks, + type = type ) patients_long = patients |> tidyr::pivot_longer( diff --git a/tests/testthat/test_PipeOpFDAExtract.R b/tests/testthat/test_PipeOpFDAExtract.R index db1b4d5..23e40c5 100644 --- a/tests/testthat/test_PipeOpFDAExtract.R +++ b/tests/testthat/test_PipeOpFDAExtract.R @@ -50,7 +50,10 @@ test_that("PipeOpFDAExtract works", { pop = po("fda.extract", features = c("mean", "median", "min"), drop = TRUE, left = 100, right = 200) task_pop = train_pipeop(pop, list(task))[[1L]] expected = data.table( - y = 1:2, f_mean = rep(NA_real_, 2L), f_median = rep(NA_real_, 2L), f_min = rep(NA_real_, 2L) + y = 1:2, + f_mean = rep(NA_real_, 2L), + f_median = rep(NA_real_, 2L), + f_min = rep(NA_real_, 2L) ) expect_identical(task_pop$data(), expected) @@ -184,9 +187,7 @@ test_that("ffind works", { expect_identical(ffind(1:10, 5, 15), c(5L, 10L)) expect_identical( - ffind(c(-3876, -3798, -3453, -3363, -2974, -2953, -2871, -1917, -1335, -1304, -725, 10), - left = -200, right = 0 - ), + ffind(c(-3876, -3798, -3453, -3363, -2974, -2953, -2871, -1917, -1335, -1304, -725, 10), left = -200, right = 0), rep(NA_integer_, 2L) ) }) diff --git a/tests/testthat/test_PipeOpFDAFlatten.R b/tests/testthat/test_PipeOpFDAFlatten.R index 8c5140c..1817d00 100644 --- a/tests/testthat/test_PipeOpFDAFlatten.R +++ b/tests/testthat/test_PipeOpFDAFlatten.R @@ -54,7 +54,12 @@ test_that("PipeOpFDAFlatten works with tfr and tfi", { pop = po("fda.flatten") task_flat = train_pipeop(pop, list(task))[[1L]] expected = data.table( - y = 1:2, f_1 = c(1, 3), f_2 = c(2, 5), f_3 = c(5, 10), f_4 = c(5, 2), f_5 = c(7, 12) + y = 1:2, + f_1 = c(1, 3), + f_2 = c(2, 5), + f_3 = c(5, 10), + f_4 = c(5, 2), + f_5 = c(7, 12) ) expect_set_equal(c("f_1", "f_2", "f_3", "f_4", "f_5"), task_flat$feature_names) expect_equal(task_flat$data(), expected) @@ -71,7 +76,13 @@ test_that("PipeOpFDAFlatten works with tfr and tfi", { pop = po("fda.flatten") task_flat = train_pipeop(pop, list(task))[[1L]] expected = data.table( - y = 1:2, f_1 = c(NA, 1), f_2 = c(NA, 3), f_3 = c(2, 4), f_4 = c(5, 5), f_5 = c(6, 6), f_6 = c(NA, 7) + y = 1:2, + f_1 = c(NA, 1), + f_2 = c(NA, 3), + f_3 = c(2, 4), + f_4 = c(5, 5), + f_5 = c(6, 6), + f_6 = c(NA, 7) ) expect_set_equal(c("f_1", "f_2", "f_3", "f_4", "f_5", "f_6"), task_flat$feature_names) expect_equal(task_flat$data(), expected) diff --git a/tests/testthat/test_PipeOpFPCA.R b/tests/testthat/test_PipeOpFPCA.R index b688c17..122a73d 100644 --- a/tests/testthat/test_PipeOpFPCA.R +++ b/tests/testthat/test_PipeOpFPCA.R @@ -50,9 +50,16 @@ test_that("PipeOpPCA works", { expect_task(task_fpc) expect_identical(dim(new_data), c(10L, 10L)) nms = c( - "y", "f_pc_1", "f_pc_2", "f_pc_3", - "g_pc_1", "g_pc_2", "g_pc_3", - "h_pc_1", "h_pc_2", "h_pc_3" + "y", + "f_pc_1", + "f_pc_2", + "f_pc_3", + "g_pc_1", + "g_pc_2", + "g_pc_3", + "h_pc_1", + "h_pc_2", + "h_pc_3" ) expect_named(new_data, nms) expect_identical(new_data, predict_pipeop(pop, list(task))[[1L]]$data()) @@ -62,9 +69,13 @@ test_that("PipeOpPCA works", { new_data = train_pipeop(pop, list(task))[[1L]]$data() expect_identical(dim(new_data), c(10L, 7L)) nms = c( - "y", "f_pc_1", "f_pc_2", - "g_pc_1", "g_pc_2", - "h_pc_1", "h_pc_2" + "y", + "f_pc_1", + "f_pc_2", + "g_pc_1", + "g_pc_2", + "h_pc_1", + "h_pc_2" ) expect_named(new_data, nms)