library("matrixStats") weightedVar_R <- function(x, w) { mu <- weighted.mean(x, w = w) sum(w * (x - mu) ^ 2) / (sum(w) - 1) } n <- 10 x <- as.double(1:n) message("*** weightedVar() ...") message("- Zero elements") m0 <- var(integer(0)) m1 <- weightedVar(integer(0), w = integer(0)) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("- One elements") m0 <- var(1) m1 <- weightedVar(1) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("- Uniform weights (all w = 1)") m0 <- var(x) w <- rep(1, times = n) m1 <- weightedVar(x, w = w) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("- Uniform weights (all w = 3)") m0 <- var(rep(x, each = 3)) w <- rep(3, times = n) m1 <- weightedVar(x, w = w) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("- Uniform weights on the first five elements") idxs <- 1:5 m0 <- var(x[1:5]) w <- rep(0, times = n) w[idxs] <- 1 m1 <- weightedVar(x, w = w) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("- Uniform weights on every second elements") idxs <- seq(from = 1, to = n, by = 2) m0 <- var(x[idxs]) w <- rep(0, times = n) w[idxs] <- 1 m1 <- weightedVar(x, w = w) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("- All weights are zero") idxs <- integer(0L) m0 <- var(x[idxs]) w <- rep(0, times = n) w[idxs] <- 1 m1 <- weightedVar(x, w = w) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("- Infinite weight on first element") idxs <- 1L m0 <- var(x[idxs]) w <- rep(0, times = n) w[idxs] <- Inf m1 <- weightedVar(x, w = w) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("- Missing-value weight on first element") idxs <- 1L w <- rep(1, times = n) w[idxs] <- NA_real_ m1 <- weightedVar(x, w = w) str(list(m1 = m1)) stopifnot(identical(m1, NA_real_)) message("- Frequency weights") ## From https://en.wikipedia.org/wiki/Weighted_arithmetic_mean y <- c(2, 2, 4, 5, 5, 5) x <- unique(y) w <- table(y) stopifnot(names(w) == x) m0 <- weightedVar(x, w = w) m1 <- var(y) stopifnot(all.equal(m1, m0)) m2 <- weightedVar(x, w = w) str(list(m0 = m0, m1 = m1, m2 = m2)) stopifnot(all.equal(m2, m0)) ## From https://github.com/HenrikBengtsson/matrixStats/issues/72 large <- c(21, 8, 26, 1, 15, 33, 12, 25, 0, 84) years <- c(41706, 9301, 33678, 3082, 27040, 44188, 10049, 30591, 2275, 109831) m0 <- weightedVar(large, w = years) m1 <- weightedVar(large, w = years) str(list(m0 = m0, m1 = m1)) stopifnot(all.equal(m1, m0)) message("*** weightedVar() ... DONE")