Skip to content

Commit b83c8a8

Browse files
survey matching intercept names for ord
1 parent 8516a91 commit b83c8a8

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Bugs:
99
* Error when merging the original data back into `comparisons()` when the data includes some list columns. The problem is that `data.table` does not support that column type. We now return the original data.table error as a warning, and do not merge the data back. Thanks to @raffaem for report #1638.
1010
* Improve warning message for hypothesis string order. Thanks to @zakarydraper for report #1640.
1111
* `comparisons()` with survey-weighted ordinal regressions failed because `stats::na.omit()` discarded every row when auxiliary columns were all `NA`, and the remaining objects fell out of alignment. We now filter using a shared index so hi/lo predictions, weights, and posterior draws stay synchronized.
12+
* `set_coef.svyolr()` did not recognize thresholds named like `"Intercept: 1|2"`, so delta-method perturbations replaced all cutpoints with `NA` and SEs vanished for `comparisons()`/`avg_*()` on survey ordinal models. Threshold names are now matched with or without the `"Intercept:"` prefix.
1213

1314
## 0.31.0
1415

R/methods_survey.R

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,15 @@ set_coef.svyolr <- function(model, coefs, ...) {
1616
# in basic model classes coefficients are named vector
1717
idx <- match(names(model$coefficients), names(coefs))
1818
model[["coefficients"]] <- coefs[idx]
19-
idx <- match(names(model$zeta), names(coefs))
19+
20+
# thresholds can be named either "1|2" or "Intercept: 1|2"
21+
zeta_names <- names(model$zeta)
22+
idx <- match(zeta_names, names(coefs))
23+
if (anyNA(idx)) {
24+
zeta_alt <- paste("Intercept:", zeta_names)
25+
idx_alt <- match(zeta_alt, names(coefs))
26+
idx <- ifelse(is.na(idx), idx_alt, idx)
27+
}
2028
model[["zeta"]] <- coefs[idx]
2129
model
2230
}

R/sanitize_newdata.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ add_wts_column <- function(wts, newdata, model) {
184184
flag2 <- isTRUE(checkmate::check_numeric(wts, len = nrow(newdata)))
185185
if (!flag1 && !flag2) {
186186
msg <- sprintf(
187-
"The `wts` argument must be a numeric vector of length %s, or a string which matches a column name in `newdata`. If you did not supply a `newdata` explicitly, `marginaleffects` extracted it automatically from the model object, and the `wts` variable may not have been available. The easiest strategy is often to supply a data frame such as the original data to `newdata` explicitly, and to make sure that it includes an appropriate column of weights, identified by the `wts` argument.",
187+
"The `wts` argument must be a numeric vector of length %s, or a string which matches one of the `colnames()` in the data frame that you supplied to the `newdata`, or in the `marginaleffects` objects.",
188188
nrow(newdata)
189189
)
190190
stop(msg, call. = FALSE)

inst/tinytest/test-pkg-survey.R

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,23 @@ m <- suppressWarnings(svyglm(
5858
))
5959
cmp <- avg_comparisons(m, variables = "education", by = c("ban", "gender"), wts = "weights", hypothesis = ~reference)
6060
expect_false(anyNA(cmp$estimate))
61+
62+
# svyolr delta-method standard errors
63+
set.seed(1234)
64+
n <- 400
65+
z <- rbinom(n, 1, 0.5)
66+
x <- factor(sample(c("1", "2", "3"), n, replace = TRUE))
67+
beta_x <- c("1" = 0, "2" = 0.4, "3" = -0.3)
68+
beta_z <- 0.6
69+
eta <- beta_x[x] + beta_z * z + rlogis(n)
70+
cuts <- c(-1.5, -0.5, 0.5, 1.5)
71+
y <- cut(eta, breaks = c(-Inf, cuts, Inf), labels = 1:5, ordered_result = TRUE)
72+
weights <- rlnorm(n, meanlog = log(50000), sdlog = 1)
73+
design <- svydesign(ids = ~1, weights = ~weights, data = data.frame(y, x, z, weights))
74+
ord_svy <- svyolr(y ~ x + z, method = "logistic", design = design)
75+
cmp <- comparisons(ord_svy, wts = "(weights)")
76+
expect_true(any(!is.na(cmp$std.error)))
77+
avg_cmp <- avg_comparisons(ord_svy, wts = "(weights)")
78+
expect_true(any(!is.na(avg_cmp$std.error)))
79+
avg_pred <- avg_predictions(ord_svy, wts = "(weights)")
80+
expect_true(any(!is.na(avg_pred$std.error)))

0 commit comments

Comments
 (0)