tidy() returns the estimates of a pool_ipw() result as a tibble using the
column names broom conventions use. There is one row per effect measure, and
one row per effect measure per contrast for a categorical exposure, in the
order the pooled result stores them. Nothing is dropped.
Those columns are the ones the pooled result's own coercion surface reports, so this method is that surface read as a tibble rather than a second assembly of the same table. The covariance of the effects the frame attaches is the one thing that does not travel: it is an attribute rather than a column, and a tidied table is its columns.
The pooling has already happened by the time this method sees the result. Nothing here re-pools and no argument changes an estimate: they say how the table already in the object is reported, which is which of the two readings it is, whether an interval comes with it, the level that interval is reported at, and the scale the ratio rows are put on.
A pooled result reports its effects in one of two readings, and tidy()
returns the one the result records unless effects names the other for the
call. pool_ipw() pools both readings of the results it is given, so naming
one here reports a table the pooling already built rather than pooling again.
The marginal reading is the table of pooled causal contrasts described above.
The conditional reading is the outcome models' coefficient surface, pooled
the same way: one row per coefficient, from the block of the joint estimation
that carries the uncertainty of having estimated the weights from the same
data. The two readings return the same columns in the same order, with one
exception: the contrast column that names the pair of exposure levels a row
compares belongs to the marginal reading of a categorical pool alone, and
that pool's conditional reading returns the same table one column narrower.
Usage
# S3 method for class 'ipw_pooled'
tidy(
x,
conf.int = FALSE,
conf.level = NULL,
exponentiate = FALSE,
...,
effects = NULL
)Arguments
- x
An
ipw_pooledobject, as returned bypool_ipw().- conf.int
Logical. Should the confidence interval bounds be returned in the
conf.lowandconf.highcolumns? Defaults toFALSE.- conf.level
The confidence level of the interval.
NULL, the default, reports the bounds at the level the pooled result stored, which is the level its own intervals were built at. A number between 0 and 1 rebuilds them at that level instead, from the estimate and its standard error referred to t on the pooled degrees of freedom. Not used whenconf.intisFALSE, though it must still be a valid level.- exponentiate
Logical. Should the estimate and its bounds be exponentiated on the rows reported on the log scale? Defaults to
FALSE. This behaves exactly as it does on the pooled result's own coercion surface: in the marginal reading thelog(rr)andlog(or)rows have their estimate and bounds exponentiated and theirtermrelabeled torrandor, and in the conditional reading the outcome model's link settles the scale for every row at once and no term is relabeled. In both readings the standard error, the test statistic, and the p-value describe the log scale and stay there, which is where the inference was done.- ...
These dots are for future extensions and must be empty.
- effects
The reading to report, either
"marginal"or"conditional".NULL, the default, reports the reading the pooled result records; naming a reading reports that one for the one call and leaves the result as it is. The marginal reading reports the pooled causal contrasts; the conditional reading reports the pooled coefficients of the outcome models, which is the readingexponentiateabove puts on the natural scale every row at once.as_marginal()andas_conditional()move a pooled result between the two readings for good rather than for a call.A reading the pooling could not compute is refused rather than reported under the other one's name. The conditional reading needs the covariance the joint estimation of the weights and the outcome implies, and a linearization fit stacks no such system and records no such block, so a set of those fits pools the marginal reading alone. A result pooled before both readings were kept holds only the one it was pooled in, and asking it for the other is refused the same way.
"fixed"is not among the values this method takes, thoughtidy()on a single result accepts it.mice::pool()asks for that reading from the tidier of each imputation's own fit, which is where the name arrives and where the tolerance for it belongs; nothing tidies a pooled result on its behalf.
Value
A tibble with one row per pooled estimate and the columns:
termThe effect measure, such as
"rd","log(rr)","log(or)","diff","slope", or"coef", or the coefficient name in the conditional reading.contrastThe contrast the row reports, such as
"b vs a"for a categorical exposure or the coefficient name on a surface whose rows are named after their coefficients. Present only in the marginal reading, and there only where a row reports one: the conditional reading names each coefficient intermand returns nocontrastcolumn.estimateThe pooled point estimate.
std.errorThe pooled standard error.
statisticThe test statistic, the estimate over its standard error.
dfThe pooled degrees of freedom the statistic is referred to. These carry the Barnard-Rubin small-sample adjustment, so the statistic is referred to t on them rather than to the normal.
p.valueThe two-sided p-value of that statistic.
conf.low,conf.highThe interval bounds. Present only when
conf.intisTRUE.
See also
pool_ipw() for the pooling, glance() for a
one-row summary of the pooled fit, as_marginal() and as_conditional()
for the reading a pooled result records, and the Multiple imputation
section of ipw() for the workflow they belong to.
Examples
set.seed(2024)
n <- 150
x1 <- rnorm(n)
z <- rbinom(n, 1, plogis(0.3 * x1))
y <- rbinom(n, 1, plogis(-0.4 + 0.9 * z + 0.5 * x1))
dat <- data.frame(x1, z, y)
dat$x1[rbinom(n, 1, 0.2) == 1] <- NA
imp <- mice::mice(dat, m = 2, print = FALSE, seed = 1)
fits <- with(imp, {
ps <- glm(z ~ x1, family = binomial())
w <- wt_ate(ps)
om <- glm(y ~ z, family = quasibinomial(), weights = w)
ipw(ps, om)
})
#> ℹ Using exposure variable "z" from GLM model
#> ℹ Treating `.exposure` as binary
#> ℹ Using exposure variable "z" from GLM model
#> ℹ Treating `.exposure` as binary
tidy(pool_ipw(fits))
#> # A tibble: 3 × 6
#> term estimate std.error statistic df p.value
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 rd 0.152 0.0810 1.88 134. 0.0625
#> 2 log(rr) 0.315 0.174 1.80 134. 0.0733
#> 3 log(or) 0.614 0.332 1.85 134. 0.0668
tidy(pool_ipw(fits), conf.int = TRUE, exponentiate = TRUE)
#> # A tibble: 3 × 8
#> term estimate std.error statistic df p.value conf.low conf.high
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 rd 0.152 0.0810 1.88 134. 0.0625 -0.00803 0.312
#> 2 rr 1.37 0.174 1.80 134. 0.0733 0.970 1.93
#> 3 or 1.85 0.332 1.85 134. 0.0668 0.958 3.56
# The outcome models' coefficients, pooled the same way
tidy(pool_ipw(fits), effects = "conditional")
#> # A tibble: 2 × 6
#> term estimate std.error statistic df p.value
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 (Intercept) -0.358 0.246 -1.46 136. 0.148
#> 2 z 0.614 0.332 1.85 134. 0.0668
