library("matrixStats") x_OP_y_R <- function(x, y, OP, na.rm = FALSE) { if (na.rm) { xnok <- is.na(x) ynok <- is.na(y) anok <- xnok & ynok unit <- switch(OP, "+" = 0, "-" = NA_real_, "*" = 1, "/" = NA_real_, stop("Unknown 'OP' operator: ", OP) ) x[xnok] <- unit y[ynok] <- unit } ans <- switch(OP, "+" = x + y, "-" = x - y, "*" = x * y, "/" = x / y, stop("Unknown 'OP' operator: ", OP) ) if (na.rm) { ans[anok] <- NA_real_ } ans } # x_OP_y_R() t_tx_OP_y_R <- function(x, y, OP, na.rm = FALSE) { t(x_OP_y_R(x = t(x), y = y, OP = OP, na.rm = na.rm)) } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # No missing values # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - x <- matrix(1:16, nrow = 4, ncol = 4) y <- 1:nrow(x) storage.mode(y) <- storage.mode(x) for (OP in c("+", "-", "*", "/")) { for (na.rm in c(FALSE, TRUE)) { cat(sprintf("OP = '%s', na.rm = %s\n", OP, na.rm)) a0 <- x_OP_y_R(x, y, OP, na.rm = na.rm) a1 <- x_OP_y(x, y, OP, na.rm = na.rm) str(a1) stopifnot(all.equal(a1, a0)) b0 <- t_tx_OP_y_R(x, y, OP, na.rm = na.rm) b1 <- t_tx_OP_y(x, y, OP, na.rm = na.rm) str(b1) stopifnot(all.equal(b1, b0)) } } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Missing values in x, y, or both. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - for (which in c("x", "y", "both")) { x <- matrix(1:16, nrow = 4, ncol = 4) y <- 1:nrow(x) storage.mode(y) <- storage.mode(x) if (which == "x") { x[3:6] <- NA_real_ } else if (which == "y") { y[c(1, 3)] <- NA_real_ } else if (which == "both") { x[3:6] <- NA_real_ y[c(1, 3)] <- NA_real_ } for (OP in c("+", "-", "*", "/")) { for (na.rm in c(FALSE, TRUE)) { cat(sprintf("OP = '%s', na.rm = %s\n", OP, na.rm)) a0 <- x_OP_y_R(x, y, OP, na.rm = na.rm) a1 <- x_OP_y(x, y, OP, na.rm = na.rm) str(a1) stopifnot(all.equal(a1, a0)) b0 <- t_tx_OP_y_R(x, y, OP, na.rm = na.rm) b1 <- t_tx_OP_y(x, y, OP, na.rm = na.rm) str(b1) stopifnot(all.equal(b1, b0)) } } } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Length differences # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - x <- matrix(1:8, nrow = 2, ncol = 4) y <- 1:ncol(x) storage.mode(y) <- storage.mode(x) for (OP in c("+", "-", "*", "/")) { for (na.rm in c(FALSE, TRUE)) { cat(sprintf("OP = '%s', na.rm = %s\n", OP, na.rm)) a0 <- x_OP_y_R(x, y, OP, na.rm = na.rm) a1 <- x_OP_y(x, y, OP, na.rm = na.rm) str(a1) stopifnot(all.equal(a1, a0)) b0 <- t_tx_OP_y_R(x, y, OP, na.rm = na.rm) b1 <- t_tx_OP_y(x, y, OP, na.rm = na.rm) str(b1) stopifnot(all.equal(b1, b0)) } } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # All missing values # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xs <- list( A = matrix(1:2, nrow = 2, ncol = 2), B = matrix(NA_integer_, nrow = 2, ncol = 2) ) ys <- list( A = 1L, B = NA_integer_ ) for (x in xs) { for (y in ys) { for (mode in c("logical", "integer", "double")) { storage.mode(x) <- mode storage.mode(y) <- mode str(list(x = x, y = y)) for (OP in c("+", "-", "*", "/")) { for (na.rm in c(FALSE, TRUE)) { cat(sprintf("mode = '%s', OP = '%s', na.rm = %s\n", mode, OP, na.rm)) suppressWarnings({ z0 <- x_OP_y_R(x, y, OP, na.rm = na.rm) z <- x_OP_y(x, y, OP, na.rm = na.rm) }) str(z) stopifnot(all.equal(z, z0)) } } } # for (mode ...) } # for (y ...) } # for (x ...)