#' Sliced Inverse Regression #' #' @export SIR <- function(X, y, d, nr.slices = 10L, slice.method = c("cut", "ecdf")) { if (!(is.factor(y) || is.integer(y))) { slice.method <- match.arg(slice.method) if (slice.method == "ecdf") { y <- cut(ecdf(y)(y), nr.slices) } else { y <- cut(y, nr.slices) # ensure there are no empty slices if (any(table(y) == 0)) { y <- as.factor(as.integer(y)) } } } # Center `X` Z <- scale(X, scale = FALSE) # Split `Z` into slices determined by `y` slices <- Map(function(i) Z[i, , drop = FALSE], split(seq_along(y), y)) # Sizes and Means for each slice slice.sizes <- mapply(nrow, slices) slice.means <- Map(colMeans, slices) # Inbetween slice covariances sCov <- Reduce(`+`, Map(function(mean_s, n_s) { n_s * tcrossprod(mean_s) }, slice.means, slice.sizes)) / nrow(X) # Compute EDR directions La.svd(sCov, d, 0L)$u }