From 050769c957711f3e194d68c8aeb8814059e6cad5 Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Mon, 27 Mar 2023 21:12:43 +0200 Subject: [PATCH 1/9] PCV functionality is moved to a separate package --- R/pcv.R | 176 -------------------------------------- man/eye.Rd | 17 ---- man/getR.Rd | 19 ---- man/mdatools.Rd | 1 - man/pcv.Rd | 37 -------- man/rotationMatrixToX1.Rd | 17 ---- tests/testthat/test-pcv.R | 42 --------- 7 files changed, 309 deletions(-) delete mode 100644 R/pcv.R delete mode 100644 man/eye.Rd delete mode 100644 man/getR.Rd delete mode 100644 man/pcv.Rd delete mode 100644 man/rotationMatrixToX1.Rd delete mode 100644 tests/testthat/test-pcv.R diff --git a/R/pcv.R b/R/pcv.R deleted file mode 100644 index b064be1..0000000 --- a/R/pcv.R +++ /dev/null @@ -1,176 +0,0 @@ -#' Compute matrix with pseudo-validation set -#' -#' @param x -#' matrix with calibration set (IxJ) -#' @param ncomp -#' number of components for PCA decomposition -#' @param nseg -#' number of segments in cross-validation -#' @param scale -#' logical, standardize columns of X prior to decompositon or not -#' -#' @description -#' The method computes pseudo-validation matrix Xpv, based on PCA decomposition of calibration set X -#' and systematic (venetian blinds) cross-validation. It is assumed that data rows are ordered -#' correctly, so systematic cross-validation can be applied. -#' -#' All details can be found in [1] -#' -#' @references -#' 1. Kucheryavskiy, S., Zhilin, S., Rodionova, O., & Pomerantsev, A. -#' Procrustes Cross-Validation—A Bridge between Cross-Validation and Independent Validation Sets. -#' Analytical Chemistry, 92 (17), 2020. pp.11842–11850. DOI: 10.1021/acs.analchem.0c02175 -#' -#' @return -#' Pseudo-validation matrix (IxJ) -#' -#' @export -pcv <- function(x, ncomp = min(round(nrow(x) / nseg) - 1, col(x), 20), nseg = 4, scale = FALSE) { - - # keep names if any - attrs <- attributes(x) - - # convert to matrix if necessary - x <- mda.df2mat(x) - - mx <- apply(x, 2, mean) - sx <- if (scale) apply(x, 2, sd) else rep(1, ncol(x)) - - # autoscale the calibration set - x <- scale(x, center = mx, scale = sx) - - # create a global model - P <- svd(x)$v[, seq_len(ncomp), drop = FALSE] - - # create matrix with indices for cross-validation, so - # each column is number of rows to be taken as local validation set - # in corresponding segment - ind <- matrix(seq_len(nrow(x)), ncol = nseg, byrow = TRUE) - - # prepare empty matrix for pseudo-validation set - x.pv <- matrix(0, nrow(x), ncol(x)) - a <- NULL - - # cv-loop - for (k in seq_len(nseg)) { - - # split data to calibration and validation - x.c <- x[-ind[, k], , drop = FALSE] - x.k <- x[ind[, k], , drop = FALSE] - - # get loadings for local model and rotation matrix between global and local models - P.k <- svd(x.c, nv = ncomp)$v[, seq_len(ncomp), drop = FALSE] - - # correct direction of loadings for local model - a <- acos(colSums(P * P.k)) < pi / 2 - P.k <- P.k %*% diag(a * 2 - 1, ncol(P), ncol(P)) - - # get rotation matrix between the PC spaces - R <- getR(P.k, P) - - # rotate the local validation set and save as a part of Xpv - x.pv[ind[, k], ] <- tcrossprod(x.k, R) - } - - # uscenter and unscale the data - x.pv <- sweep(x.pv, 2, sx, "*") - x.pv <- sweep(x.pv, 2, mx, "+") - - attributes(x.pv) <- attrs - return(x.pv) -} - -#' Creates rotation matrix to map a set vectors \code{base1} to a set of vectors \code{base2}. -#' -#' @param base1 -#' Matrix (JxA) with A orthonormal vectors as columns to be rotated (A <= J) -#' @param base2 -#' Matrix (JxA) with A orthonormal vectors as columns, \code{base1} should be aligned with -#' -#' @description -#' In both sets vectors should be orthonormal. -#' -#' @return -#' Rotation matrix (JxJ) -getR <- function(base1, base2) { - base1 <- as.matrix(base1) - base2 <- as.matrix(base2) - - R1 <- rotationMatrixToX1(base1[, 1]) - R2 <- rotationMatrixToX1(base2[, 1]) - - if (ncol(base1) == 1) { - R <- t(R2) %*% R1 - } else { - # Compute bases rotated to match their first vectors to [1 0 0 ... 0]' - base1_r <- as.matrix(R1 %*% base1) - base2_r <- as.matrix(R2 %*% base2) - - # Get bases of subspaces of dimension n-1 (forget x1) - nr <- nrow(base1_r) # equal to nrow(base2_r) - nc <- ncol(base1_r) # equal to ncol(base2_r) - base1_rs <- base1_r[2:nr, 2:nc] - base2_rs <- base2_r[2:nr, 2:nc] - - # Recursevely compute rotation matrix to map subspaces - Rs <- getR(base1_rs, base2_rs) - - # Construct rotation matrix of the whole space (recall x1) - M <- eye(nr) - M[2:nr, 2:nr] <- Rs - - R <- crossprod(R2, (M %*% R1)) - } - - return(R) -} - -#' Creates a rotation matrix to map a vector x to [1 0 0 ... 0] -#' -#' @param x -#' Vector (sequence with J coordinates) -#' -#' @return -#' Rotation matrix (JxJ) -rotationMatrixToX1 <- function(x) { - N <- length(x) - R <- eye(N) - step <- 1 - while (step < N) { - A <- eye(N) - n <- 1 - while (n <= N - step) { - r2 <- x[n]^2 + x[n + step]^2 - if (r2 > 0) { - r <- sqrt(r2) - pcos <- x[n] / r - psin <- -x[n + step] / r - A[n, n] <- pcos - A[n, n + step] <- -psin - A[n + step, n] <- psin - A[n + step, n + step] <- pcos - } - n <- n + 2 * step - } - step <- 2 * step - x <- A %*% x - R <- A %*% R - } - return(R) -} - - -#' Create the identity matrix -#' -#' @param n -#' Size of the matrix -#' -#' @return -#' The identity matrix (n x n) -#' -#' @export -eye <- function(n) { - X <- matrix(0, n, n) - diag(X) <- 1 - return(X) -} diff --git a/man/eye.Rd b/man/eye.Rd deleted file mode 100644 index 1d257c9..0000000 --- a/man/eye.Rd +++ /dev/null @@ -1,17 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pcv.R -\name{eye} -\alias{eye} -\title{Create the identity matrix} -\usage{ -eye(n) -} -\arguments{ -\item{n}{Size of the matrix} -} -\value{ -The identity matrix (n x n) -} -\description{ -Create the identity matrix -} diff --git a/man/getR.Rd b/man/getR.Rd deleted file mode 100644 index 045b7e7..0000000 --- a/man/getR.Rd +++ /dev/null @@ -1,19 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pcv.R -\name{getR} -\alias{getR} -\title{Creates rotation matrix to map a set vectors \code{base1} to a set of vectors \code{base2}.} -\usage{ -getR(base1, base2) -} -\arguments{ -\item{base1}{Matrix (JxA) with A orthonormal vectors as columns to be rotated (A <= J)} - -\item{base2}{Matrix (JxA) with A orthonormal vectors as columns, \code{base1} should be aligned with} -} -\value{ -Rotation matrix (JxJ) -} -\description{ -In both sets vectors should be orthonormal. -} diff --git a/man/mdatools.Rd b/man/mdatools.Rd index e715882..c16dafe 100644 --- a/man/mdatools.Rd +++ b/man/mdatools.Rd @@ -27,7 +27,6 @@ So far the following modelling and validation methods are implemented: \code{\link{ipls}} \tab Interval PLS variable.\cr \code{\link{mcrals}} \tab Multivariate Curve Resolution with Alternating Least Squares.\cr \code{\link{mcrpure}} \tab Multivariate Curve Resolution with Purity approach.\cr - \code{\link{pcv}} \tab Procrustes Cross Validation.\cr } Methods for data preprocessing: diff --git a/man/pcv.Rd b/man/pcv.Rd deleted file mode 100644 index f5ae4b6..0000000 --- a/man/pcv.Rd +++ /dev/null @@ -1,37 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pcv.R -\name{pcv} -\alias{pcv} -\title{Compute matrix with pseudo-validation set} -\usage{ -pcv( - x, - ncomp = min(round(nrow(x)/nseg) - 1, col(x), 20), - nseg = 4, - scale = FALSE -) -} -\arguments{ -\item{x}{matrix with calibration set (IxJ)} - -\item{ncomp}{number of components for PCA decomposition} - -\item{nseg}{number of segments in cross-validation} - -\item{scale}{logical, standardize columns of X prior to decompositon or not} -} -\value{ -Pseudo-validation matrix (IxJ) -} -\description{ -The method computes pseudo-validation matrix Xpv, based on PCA decomposition of calibration set X -and systematic (venetian blinds) cross-validation. It is assumed that data rows are ordered -correctly, so systematic cross-validation can be applied. - -All details can be found in [1] -} -\references{ -1. Kucheryavskiy, S., Zhilin, S., Rodionova, O., & Pomerantsev, A. -Procrustes Cross-Validation—A Bridge between Cross-Validation and Independent Validation Sets. -Analytical Chemistry, 92 (17), 2020. pp.11842–11850. DOI: 10.1021/acs.analchem.0c02175 -} diff --git a/man/rotationMatrixToX1.Rd b/man/rotationMatrixToX1.Rd deleted file mode 100644 index 8b3b2bf..0000000 --- a/man/rotationMatrixToX1.Rd +++ /dev/null @@ -1,17 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pcv.R -\name{rotationMatrixToX1} -\alias{rotationMatrixToX1} -\title{Creates a rotation matrix to map a vector x to [1 0 0 ... 0]} -\usage{ -rotationMatrixToX1(x) -} -\arguments{ -\item{x}{Vector (sequence with J coordinates)} -} -\value{ -Rotation matrix (JxJ) -} -\description{ -Creates a rotation matrix to map a vector x to [1 0 0 ... 0] -} diff --git a/tests/testthat/test-pcv.R b/tests/testthat/test-pcv.R deleted file mode 100644 index e22e140..0000000 --- a/tests/testthat/test-pcv.R +++ /dev/null @@ -1,42 +0,0 @@ -##################################################### -# Tests for Procrustes Cross-Validation methods # -##################################################### - -setup({ - pdf(file = tempfile("mdatools-test-pcv-", fileext = ".pdf")) - sink(tempfile("mdatools-test-pcv-", fileext = ".txt"), append = FALSE, split = FALSE) -}) - -teardown({ - dev.off() - sink() -}) - -# Simple tests for the PCV R implementation -I <- 100 -J <- 50 -A <- 10 -K <- 4 -set.seed(42) -x <- matrix(rnorm(I * J), I, J) - -params <- list() -params[[1]] <- list(x = x) -params[[2]] <- list(x = x, ncomp = 1) -params[[3]] <- list(x = x, ncomp = A) -params[[4]] <- list(x = x, ncomp = A, nseg = 4) -params[[5]] <- list(x = x, ncomp = A, nseg = 10) -params[[6]] <- list(x = x, ncomp = A, nseg = nrow(x)) -params[[7]] <- list(x = x, ncomp = A, nseg = 4, scale = TRUE) -params[[8]] <- list(x = x, ncomp = A, nseg = 10, scale = TRUE) -params[[9]] <- list(x = x, ncomp = A, nseg = nrow(x), scale = TRUE) - -context("pcv: for PCA") -for (i in seq_along(params)) { - test_that(paste0("pcv() for PCA works well with parameters set #", i), { - x.pv <- do.call(pcv, params[[i]]) - expect_equal(nrow(x.pv), nrow(x)) - expect_equal(ncol(x.pv), ncol(x)) - expect_gt(ks.test(x, x.pv)$p.value, 0.01) - }) -} From fdb73caf7c80bd9575a0afa4249492370ea606c3 Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Mon, 27 Mar 2023 21:13:11 +0200 Subject: [PATCH 2/9] fixed issue with venetian blinds generation of CV segments --- R/crossval.R | 3 ++- tests/testthat/test-crossval.R | 28 +++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/R/crossval.R b/R/crossval.R index 6debe23..cd0f50a 100755 --- a/R/crossval.R +++ b/R/crossval.R @@ -107,7 +107,8 @@ crossval <- function(cv = 1, nobj = NULL, resp = NULL) { } if (p$type == "ven") { - ind <- if (is.null(resp)) seq_len(nobj) else order(resp) + + ind <- if (is.null(resp)) seq_len(nobj) else order(order(resp)) return(matrix(rep(seq_len(p$nseg), length.out = nobj)[ind], ncol = 1)) } diff --git a/tests/testthat/test-crossval.R b/tests/testthat/test-crossval.R index e797a4f..356e462 100644 --- a/tests/testthat/test-crossval.R +++ b/tests/testthat/test-crossval.R @@ -70,19 +70,37 @@ test_that("systematic cross-validation works correctly", { nseg <- 4 set.seed(42) resp <- rnorm(nobj) - cv.ind <- matrix(rep(seq_len(nseg), length.out = nobj)[order(resp)], ncol = 1) - set.seed(42) - expect_equivalent(cv.ind, crossval(cv = list("ven", 4), resp = resp)) + cv.ind <- matrix(rep(seq_len(nseg), length.out = nobj)[order(order(resp))], ncol = 1) + cv.computed <- crossval(cv = list("ven", 4), resp = resp); + expect_equivalent(cv.ind, cv.computed) + + # check segment wise + # sort resp values and split sorted values into segments using systematic indices: 1, 2, 3, 4, 1, 2, 3, 4, 1, 2... + resp.sorted = sort(resp) + cv.ind.sorted = rep(seq_len(nseg), length.out = nobj) + + # check that both splits are identicall + for (i in 1:4) { + expect_equivalent(sort(resp[cv.computed == i]), resp.sorted[cv.ind.sorted == i]) + } # number of objets is not a multuply of number segments nseg <- 5 set.seed(42) resp <- rnorm(nobj) - cv.ind <- matrix(rep(seq_len(nseg), length.out = nobj)[order(resp)], ncol = 1) - set.seed(42) + cv.ind <- matrix(rep(seq_len(nseg), length.out = nobj)[order(order(resp))], ncol = 1) expect_equivalent(cv.ind, crossval(cv = list("ven", 5), resp = resp)) # it also works well without any response expect_equivalent(crossval(list("ven", 4), 10), matrix(c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2), ncol = 1)) + + # to catch a possible bug + # 1 2 3 4 5 6 7 8 9 10 11 12 - normal order + # 2 4 8 7 11 3 10 9 1 6 12 5 - order of indices for sorted y-vales + # 1 2 3 4 1 2 3 4 1 2 3 4 - normal order of segments + # 1 1 2 2 4 2 4 3 4 3 1 3 + y = c(9, 1, 6, 2, 12, 10, 4, 3, 8, 7, 5, 11) + expect_equivalent(crossval(list("ven", 4), 12, y), matrix(c(1, 1, 2, 2, 4, 2, 4, 3, 4, 3, 1, 3), ncol = 1)) + }) From 8af48d978c0f8010aaeb1fec7a55e34ad5ed2bcb Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Tue, 28 Mar 2023 18:29:03 +0200 Subject: [PATCH 3/9] fixed bug Error in `summary.simcares` when no reference class labels are used #109 --- R/simcares.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/simcares.R b/R/simcares.R index fc0b311..e89ecce 100755 --- a/R/simcares.R +++ b/R/simcares.R @@ -117,7 +117,7 @@ as.matrix.simcares <- function(x, ncomp = NULL, ...) { out[, 1:2] <- round(out[, 1:2], 2) colnames(out) <- c("Expvar", "Cumexpvar", "TP", "FP", "TN", "FN", - "Spec.", "Sens.", "Accuracy") + "Spec.", "Sens.", "Accuracy")[seq_len(ncol(out))] return(out) } From 5170deca901c283ee2be59b23204dc6fa24b92da Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Tue, 28 Mar 2023 18:29:24 +0200 Subject: [PATCH 4/9] changes in prep.alsbasecorr() to meet new Matrix requirements --- R/prep.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/prep.R b/R/prep.R index 2d31fff..33b8da5 100755 --- a/R/prep.R +++ b/R/prep.R @@ -413,15 +413,17 @@ prep.alsbasecorr <- function(data, plambda = 5, p = 0.1, max.niter = 10) { m <- ncol(data) baseline <- matrix(0, nrow(data), ncol(data)) + LDD <- Matrix::Matrix((10^plambda) * crossprod(diff(diag(m), difference = 2)), sparse = TRUE) w.ini <- matrix(rep(1, m)) for (i in seq_len(nrow(data))) { y <- data[i, ] w <- w.ini + for (j in seq_len(max.niter)) { W <- Matrix::Diagonal(x = as.numeric(w)) - z <- Matrix::solve(as(W + LDD, "dgCMatrix"), w * y, sparse = TRUE) + z <- Matrix::solve(as(W + LDD, "generalMatrix"), w * y, sparse = TRUE) w.old <- w w <- p * (y > z) + (1 - p) * (y < z) From eceda7f40fdc67fd2af9e4f5b71df44ab4b490ba Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Tue, 28 Mar 2023 18:29:34 +0200 Subject: [PATCH 5/9] small changes in tests --- tests/testthat/test-ipls.R | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/testthat/test-ipls.R b/tests/testthat/test-ipls.R index 9312a5d..6819b09 100644 --- a/tests/testthat/test-ipls.R +++ b/tests/testthat/test-ipls.R @@ -194,47 +194,47 @@ y = simdata$conc.c[, 2, drop = FALSE] ## - default settings (full = FALSE) m1 = ipls(X, y, glob.ncomp = 4, int.num = 15) -expect_equal(nrow(m1$int.stat), 6) -expect_equal(length(m1$int.selected), 5) -expect_equivalent(m1$int.selected, c(6, 1, 11, 3, 12)) +expect_equal(nrow(m1$int.stat), 7) +expect_equal(length(m1$int.selected), 6) +expect_equivalent(m1$int.selected, c(6, 11, 1, 2, 13, 12)) ## - with full = TRUE m2 = ipls(X, y, glob.ncomp = 4, int.num = 15, full = TRUE) expect_equal(nrow(m2$int.stat), 16) -expect_equal(length(m2$int.selected), 8) -expect_equivalent(m2$int.selected, c(6, 1, 11, 3, 12, 4, 9, 13)) +expect_equal(length(m2$int.selected), 6) +expect_equivalent(m2$int.selected, c(6, 11, 1, 2, 13, 12)) ## - default settings (full = FALSE) + different int.num m3 = ipls(X, y, glob.ncomp = 4, int.num = 50) -expect_equal(nrow(m3$int.stat), 21) -expect_equal(length(m3$int.selected), 20) +expect_equal(nrow(m3$int.stat), 15) +expect_equal(length(m3$int.selected), 14) ## - with full = TRUE and different int.num m4 = ipls(X, y, glob.ncomp = 4, int.num = 50, full = TRUE) expect_equal(nrow(m4$int.stat), 31) -expect_equal(length(m4$int.selected), 20) +expect_equal(length(m4$int.selected), 27) ## - with full = TRUE and different int.num + larger max.niter m5 = ipls(X, y, glob.ncomp = 4, int.num = 50, full = TRUE, int.niter = 40) expect_equal(nrow(m5$int.stat), 41) -expect_equal(length(m5$int.selected), 20) +expect_equal(length(m5$int.selected), 27) ## - with full = TRUE and different int.num + very large max.niter m6 = ipls(X, y, glob.ncomp = 4, int.num = 50, full = TRUE, int.niter = 100) expect_equal(nrow(m6$int.stat), 51) -expect_equal(length(m6$int.selected), 20) +expect_equal(length(m6$int.selected), 27) # check backward method - in this case number of iterations is less than number of intervals - 1 ## - default settings (full = FALSE) m1 = ipls(X, y, glob.ncomp = 4, int.num = 15, method = "backward") -expect_equal(nrow(m1$int.stat), 11) -expect_equivalent(m1$int.selected, c(1, 3, 5, 9, 11)) +expect_equal(nrow(m1$int.stat), 10) +expect_equivalent(m1$int.selected, c(1, 3, 5, 9, 11, 13)) ## - with full = TRUE m2 = ipls(X, y, glob.ncomp = 4, int.num = 15, full = TRUE, method = "backward") expect_equal(nrow(m2$int.stat), 15) -expect_equivalent(m2$int.selected, c(1, 3, 5, 9, 11)) +expect_equivalent(m2$int.selected, c(1, 3, 5, 9, 11, 13)) ## - default settings (full = FALSE) + different int.num m3 = ipls(X, y, glob.ncomp = 4, int.num = 50, method = "backward") @@ -244,12 +244,12 @@ expect_equal(length(m3$int.selected), 20) # 50 in total minus 30 excluded ## - with full = TRUE and different int.num + large max.niter m4 = ipls(X, y, glob.ncomp = 4, int.num = 50, full = TRUE, int.niter = 40, method = "backward") expect_equal(nrow(m4$int.stat), 41) -expect_equal(length(m4$int.selected), 16) # 50 in total minus 34 excluded +expect_equal(length(m4$int.selected), 13) # 50 in total minus 37 excluded ## - with full = TRUE and different int.num + very large max.niter m5 = ipls(X, y, glob.ncomp = 4, int.num = 50, full = TRUE, int.niter = 100, method = "backward") expect_equal(nrow(m5$int.stat), 50) # not 51 because last interval can not be excluded, so general model + 49 iterations -expect_equal(length(m5$int.selected), 16) # 50 in total minus 34 excluded +expect_equal(length(m5$int.selected), 13) # 50 in total minus 37 excluded ############################### From 51d72e7f5f6ac3c365438863bc7872caabe3c5cf Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Tue, 28 Mar 2023 18:29:53 +0200 Subject: [PATCH 6/9] Description is updated to match the new version --- DESCRIPTION | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3ff1bfc..d8be2bb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,17 +1,17 @@ Package: mdatools +Version: 0.14.0 Title: Multivariate Data Analysis for Chemometrics -Version: 0.13.1 -Date: 2022-11-09 -Author: Sergey Kucheryavskiy () +Date: 2023-03-28 +Authors@R: c(person("Sergey", "Kucheryavskiy", role = c("aut", "cre"), email="svkucheryavski@gmail.com", comment = c(ORCID = "0000-0002-3145-7244"))) Maintainer: Sergey Kucheryavskiy -Description: Projection based methods for preprocessing, - exploring and analysis of multivariate data used in chemometrics. - S. Kucheryavskiy (2020) . +Description: Projection based methods for preprocessing, exploring and analysis of multivariate data used in chemometrics. S. Kucheryavskiy (2020) . Encoding: UTF-8 License: MIT + file LICENSE Imports: methods, graphics, grDevices, stats, Matrix -RoxygenNote: 7.2.1 +RoxygenNote: 7.2.3 Suggests: testthat NeedsCompilation: no Packaged: 2019-05-24 11:03:33 UTC; svkucheryavski Depends: R (>= 3.5.0) +URL: https://github.com/svkucheryavski/mdatools +BugReports: https://github.com/svkucheryavski/mdatools/issues From cdaaef768bc8ec03a39fc1ede9c76605a0538202 Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Tue, 28 Mar 2023 18:30:07 +0200 Subject: [PATCH 7/9] Namespace is updated after removal of pcv() --- NAMESPACE | 2 -- 1 file changed, 2 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 0905b0f..95797da 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -173,7 +173,6 @@ export(ddrobust.param) export(ellipse) export(employ.constraint) export(employ.prep) -export(eye) export(fprintf) export(getCalibrationData) export(getConfusionMatrix) @@ -236,7 +235,6 @@ export(pca) export(pca.mvreplace) export(pca.run) export(pcares) -export(pcv) export(pinv) export(plotBars) export(plotBiplot) From 4e755201ebcae534919e125cf7828316fb4153cf Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Tue, 28 Mar 2023 18:30:46 +0200 Subject: [PATCH 8/9] added release information for 0.14.0 --- NEWS.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/NEWS.md b/NEWS.md index 011343f..fa3c1d6 100755 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,19 @@ +v. 0.14.0 +========== + +The changes are relatively small, but some of them can be potentially breaking, hence the version is bumped up to 0.14.0. + +* Procrustes cross-validation method, `pcv()`, has been recently improved and extended. It was decided to move it to a separate dedicated R package, `pcv`. Check [GitHub repo](https://github.com/svkucheryavski/pcv) for details. The documentation chapter has been updated accordingly. + +* Fixed a bug related to generating segment indices for Venetian blinds cross-validation for regression. In case of regression, the indices are generating by taking into account the order of the response values. There was a small bug in this implementation, now it is fixed. Remember, that you can always provide manually generated vector og segment indices as value of `cv` argument. + +* Made small changes in `prep.alsbasecorr()` to meet new requirements of the `Matrix` package. So if you saw warning message from this package last couple of month, this update will fix this. + +* fixed bug [#109](https://github.com/svkucheryavski/mdatools/issues/109) + +* small improvements in documentation. + + v. 0.13.1 ========== From b8ab96dbeb9082622d57f04574b430bdde2e7e7e Mon Sep 17 00:00:00 2001 From: Sergey Kucheryavskiy Date: Tue, 28 Mar 2023 18:58:30 +0200 Subject: [PATCH 9/9] updated README to match new version --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fc1c528..ee2aaab 100755 --- a/README.md +++ b/README.md @@ -18,16 +18,16 @@ If you want to cite the package, please use the following: Sergey Kucheryavskiy, What is new ----------- -Latest release (0.13.1) is available both from GitHub and CRAN. You can see the full list of changes [here](NEWS.md). The Bookdown tutorial has been also updated and contains the description of new methods added in the last release. +Latest release (0.14.0) is available both from GitHub and CRAN. You can see the full list of changes [here](NEWS.md). The Bookdown tutorial has been also updated and contains the description of new methods added in the last release. How to install -------------- -The package is available from CRAN by usual installing procedure. However, due to restrictions in CRAN politics regarding number of submissions (one in 3-4 month), mostly major releases will be published there (with 2-3 weeks delay after GitHub release as more thorough testing is needed). You can [download](https://github.com/svkucheryavski/mdatools/releases) a zip-file with source package and install it using the `install.packages` command, e.g. if the downloaded file is `mdatools_0.13.1.tar.gz` and it is located in a current working directory, just run the following: +The package is available from CRAN by usual installing procedure. However, due to restrictions in CRAN politics regarding number of submissions (one in 3-4 month), mostly major releases will be published there (with 2-3 weeks delay after GitHub release as more thorough testing is needed). You can [download](https://github.com/svkucheryavski/mdatools/releases) a zip-file with source package and install it using the `install.packages` command, e.g. if the downloaded file is `mdatools_0.14.0.tar.gz` and it is located in a current working directory, just run the following: ``` -install.packages("mdatools_0.13.1.tar.gz") +install.packages("mdatools_0.14.0.tar.gz") ``` If you have `devtools` package installed, the following command will install the current developer version from the master branch of GitHub repository (do not forget to load the `devtools` package first):