################################################################################ ### Tests for objects implementing the distance specification protocol ################################################################################ context("Distance Specification Protocol") test_that("Matrix => nodes and arcs", { # tests: expect_true(isGeneric("prepareMatching")) # matrix and matrix.csr implement prepareMatching # each returns the proper number of nodes and arcs # test data: 4 arcs (2 pairs unmatchable) m <- matrix(c(1, Inf, 1, 2, 2, Inf), nrow = 2, ncol = 3) colnames(m) <- c("A", "B", "C") rownames(m) <- c("D", "E") m.result <- prepareMatching(m) expect_equal(dim(m.result), c(4, 3)) expect_equal(unique(m.result$treated), as.factor(c("D", "E"))) expect_equal(unique(m.result$control), as.factor(c("A", "B", "C"))) # NA's and NaN's the same as Inf's mm <- m mm[is.infinite(m)] <- c(NA_real_, NaN) expect_equal(prepareMatching(mm), m.result) }) test_that("ISM => nodes and arcs", { m <- matrix(c(1, Inf, 1, 2, 2, Inf), nrow = 2, ncol = 3) A.nonames <- as.InfinitySparseMatrix(m) expect_error(prepareMatching(A.nonames)) colnames(m) <- c("A", "B", "C") rownames(m) <- c("D", "E") A <- as.InfinitySparseMatrix(m) res.ISM <- prepareMatching(A) expect_equal(dim(res.ISM), c(4, 3)) expect_equal(unique(res.ISM$treated), as.factor(c("D", "E"))) expect_equal(unique(res.ISM$control), as.factor(c("A", "B", "C"))) # NA's and NaN's the same as Inf's mm <- m mm[is.infinite(m)] <- c(NA_real_, NaN) expect_equal(prepareMatching(as.InfinitySparseMatrix(mm)), res.ISM) }) test_that("Subproblems", { m <- matrix(1, nrow = 2, ncol = 2) expect_false(subproblems(m)) expect_false(subproblems(as.InfinitySparseMatrix(m))) B <- rep(c(0,1), each = 5) names(B) <- letters[1:10] em <- exactMatch(B, rep(c(0,1), 5)) res.em <- subproblems(em) expect_equal(length(res.em), 2) expect_true(all(vapply(res.em, validDistanceSpecification, logical(1)))) m1 <- matrix(0, nrow = 2, ncol = 3, dimnames = list(treated = c("b", "d"), control = c("a", "c", "e"))) m2 <- matrix(0, nrow = 3, ncol = 2, dimnames = list(treated = c("f", "h", "j"), control = c("g", "i"))) expect_equal(as.matrix(res.em[[1]]), m1) expect_equal(as.matrix(res.em[[2]]), m2) # findSubproblems should always return a list, of length # of probs expect_equal(length(findSubproblems(m)), 1) expect_equal(length(findSubproblems(as.InfinitySparseMatrix(m))), 1) B2 <- rep(1:5, each = 2) names(B2) <- letters[1:10] em2 <- exactMatch(B2, rep(c(0,1), 5)) em.subps <- findSubproblems(em2) expect_equal(length(em.subps), 5) expect_is(em.subps, "list") lapply(em.subps, function(i) { expect_true(validDistanceSpecification(i)) }) # a dense problem that looks likes a sparse problem position <- rep(1:4, each = 4) z <- rep(0:1, 8) names(z) <- letters[1:16] dist <- match_on(z ~ position, inv.scale.matrix = diag(1)) allin <- exactMatch(rep(1, 16), z) res.allin <- findSubproblems(dist + allin) expect_equal(length(res.allin), 1) expect_equal(dim(res.allin[[1]]), c(8,8)) expect_equal(res.allin[[1]]@.Data, as.vector(dist)) # factors that create unworkable subproblems (e.g. only control units) # use z from above bad.factor <- c(rep(1:4, each = 2), rep(c(4,5), 4)) bad.match <- exactMatch(bad.factor, z) expect_equal(dim(bad.match), c(8,8)) # don't return invalid subproblems, in this case, only return 1 subprob res.sp <- findSubproblems(bad.match) expect_equal(length(res.sp), 4) # there are 5 levels in the factor, but only 4 valid subprobs }) test_that("Validating DistSpecs", { # nameless matrices are not valid: m <- matrix(1:4, nrow = 2) expect_error(validDistanceSpecification(m)) expect_error(validDistanceSpecification(as.InfinitySparseMatrix(m))) dimnames(m) <- list(1:2, 3:4) expect_true(validDistanceSpecification(m)) expect_true(validDistanceSpecification(as.InfinitySparseMatrix(m))) # matrices/isms must be numeric m2 <- matrix(letters[1:4], nrow = 2) dimnames(m2) <- list(1:2, 3:4) expect_equal(mode(m2), "character") # while character based ISMs are ok, they are not valid distance specifications expect_error(validDistanceSpecification(m2)) expect_error(validDistanceSpecification(as.InfinitySparseMatrix(m2))) # all Inf is valid m3 <- matrix(Inf, nrow = 3, ncol = 4) rownames(m3) <- LETTERS[1:3] colnames(m3) <- letters[23:26] expect_true(validDistanceSpecification(m3)) expect_true(validDistanceSpecification(as.InfinitySparseMatrix(m3))) # negative distances not OK m4 <- matrix(1:4 -2, nrow = 2) dimnames(m4) <- list(1:2, 3:4) expect_error(validDistanceSpecification(m4), "can't be negative") expect_error(validDistanceSpecification(as.InfinitySparseMatrix(m4)), "can't be negative") m5 <- matrix(1:4 -1, nrow = 2) dimnames(m5) <- list(1:2, 3:4) expect_true(validDistanceSpecification(m5)) expect_true(validDistanceSpecification(as.InfinitySparseMatrix(m5))) })