coef_tol <- 1e-06 loglik_tol <- 1e-07 ## Extractor for the log-likelihood of poisson gnm's adjusting for the -mu part ## which is fixed due to the parameter space restriction to match row totals logLik_poisson.gnm <- function(x) { ll <- logLik(x) + sum(x$weights) attr(ll, "df") <- attr(ll, "df") - nlevels(x$eliminate) ll } ## pudding data (Example 2, Davidson 1970) is in tests/pudding.rda load("../pudding.rda") ## expand to one ranking per row R <- with(pudding, { R <- list() n <- max(i, j) for (r in seq_len(nrow(pudding))){ R[[r]] <- matrix(0, nrow = r_ij[r], ncol = n) a <- rep(c(1, 2, 1), c(w_ij[r], w_ji[r], t_ij[r])) b <- rep(c(2, 1, 1), c(w_ij[r], w_ji[r], t_ij[r])) R[[r]][, c(i[r], j[r])] <- c(a, b) } do.call("rbind", R) }) ## aggregate to unique rankings rankings <- split(R, row(R)) uniq <- unique(rankings) g <- match(rankings, uniq) R2 <- R[!duplicated(g),] w <- tabulate(g) if (require(gnm)){ ## fit PlackettLuce model ## - one ranking per row mod0 <- PlackettLuce(R, npseudo = 0) ## - aggregated to unique rankings mod1 <- PlackettLuce(R2, weights = w, npseudo = 0) ## fit log-linear model to aggregated rankings ## (do not aggregate different choices from same set of alternatives) dat <- PlackettLuce:::poisson_rankings(R2, weights = w, aggregate = FALSE, as.data.frame = TRUE) mod2 <- gnm(y ~ -1 + X, family = poisson, eliminate = z, data = dat, constrain = 1, weights = w) test_that("fit is the same for aggregated data [pudding]", { expect_equal(coef(mod0), coef(mod1), tolerance = coef_tol) expect_equal(logLik(mod0), logLik(mod1), tolerance = loglik_tol) expect_equal(vcov(mod0), vcov(mod1)) }) test_that("fit matches gnm for aggregated data [pudding]", { expect_equal(as.vector(coef(mod1)), as.vector(parameters(mod2)), tolerance = coef_tol) expect_equal(logLik(mod1), logLik_poisson.gnm(mod2), ignore_attr = TRUE, tolerance = loglik_tol) expect_equal(as.vector(vcov(mod1)), as.vector(vcov(mod2)), tolerance = loglik_tol) }) } ## netflix data (as in vignett) is in tests/netflix.rda load("../netflix.rda") r <- rep(seq_len(nrow(netflix)), netflix$n) R <- as.rankings(netflix[r,-1], "ordering") R2 <- as.rankings(netflix[,-1], "ordering") w <- netflix$n ## fit PlackettLuce model ## - one ranking per row mod0 <- PlackettLuce(R, npseudo = 0) ## - aggregated to unique rankings mod1 <- PlackettLuce(R2, weights = w, npseudo = 0) test_that("fit is the same for aggregated data [netflix]", { expect_equal(coef(mod0), coef(mod1), tolerance = coef_tol) expect_equal(logLik(mod0), logLik(mod1), tolerance = loglik_tol) expect_equal(vcov(mod0), vcov(mod1)) }) if (require(psychotree)){ ## Germany's Next Topmodel 2007 data data("Topmodel2007", package = "psychotree") ## give some judges higher weight w <- rep.int(1, nrow(Topmodel2007)) w[1:5] <- 2 ## btmodel mod1 <- btmodel(Topmodel2007$preference) mod2 <- btmodel(Topmodel2007$preference, weights = w) ## PlackettLuce (should be grouped rankings as weight is per judge) R <- as.grouped_rankings(Topmodel2007$preference) mod3 <- PlackettLuce(R, npseudo = 0) mod4 <- PlackettLuce(R, weights = w, npseudo = 0) ## bttree can't take weights, so compare to tree with no split (alpha = 0) tm_tree <- pltree(R ~ ., data = Topmodel2007[, -1], minsize = 5, weights = w, alpha = 0, npseudo = 0) test_that("fit correct for grouped rankings object [Topmodel2007]", { expect_equal(as.vector(itempar(mod1, log = TRUE, ref = "Barbara")), as.vector(coef(mod3)), tolerance = coef_tol) expect_equal(logLik(mod1), logLik(mod3), tolerance = loglik_tol) }) test_that("weights work for plfit [Topmodel2007]", { expect_equal(as.vector(itempar(mod2, log = TRUE, ref = "Barbara")), as.vector(coef(mod4)), tolerance = coef_tol) expect_equal(logLik(mod2), logLik(mod4), tolerance = loglik_tol) }) test_that("weights work for pltree [Topmodel2007]", { expect_equal(as.vector(coef(tm_tree)), as.vector(coef(mod4)), ignore_attr = TRUE, tolerance = coef_tol) expect_equal(logLik(tm_tree), logLik(mod4), ignore_attr = TRUE, tolerance = loglik_tol) }) }