Skip to contents

Exports a stack_frames() collection to survey::multiframe(), which composites the frames into one estimator. Every component is exported on its own with as_svydesign(), so each keeps its own strata, clusters and variance treatment, and the compositing is applied on top of them.

Usage

# S3 method for class 'frame_stack'
as_svydesign(
  x,
  ...,
  estimator = c("constant", "expected"),
  theta = NULL,
  nest = TRUE,
  systematic_variance = c("warn", "approximate", "error")
)

Arguments

x

A frame_stack from stack_frames().

...

Forwarded to survey::svydesign() for every component. pps is refused, because a joint-probability matrix describes one component and there is no way to say which.

estimator

"constant", the default, is Hartley's: a fixed share of an overlapping unit's weight through each frame. "expected" is the Bankier and Kalton-Anderson single-frame estimator, which weights a unit by one over the sum of its chances across the frames reaching it and so needs the overlaps declared on the stack.

theta

The compositing factor applied to the first frame's overlapping units, a single number in [0, 1]. NULL, the default, is the multiplicity estimator. It belongs to estimator = "constant" and is refused for the other, which would otherwise discard it.

nest, systematic_variance

Passed to as_svydesign() for every component.

Value

A dualframe object from the survey package, which survey::svytotal(), svymean(), svyglm() and their relatives accept.

Details

The compositing factor

theta is Hartley's constant factor: a unit belonging to both frames contributes theta of its weight through the first frame and 1 - theta through the second, so the two contributions sum to one whichever frame selected it. A unit belonging to one frame alone keeps its full weight.

theta belongs to the first frame of the stack. Reversing the components and asking for the same estimator means asking for 1 - theta. Only theta = 0.5 is invariant to the order they were stacked in.

theta = NULL is the multiplicity estimator, which gives every frame reaching a unit an equal share and is theta = 0.5 for two frames. samplyr resolves it and passes the value on. It never forwards NULL, which survey reads as the ratio of the frames' mean sampling weights: a data-dependent heuristic standing in for frame size over sample size, rather than a neutral default.

What is not exported this way

survey::multiframe() takes two frames. A stack of more is refused here rather than at the design layer, the same split as_svydesign() already runs for phases, which chain without a bound while the export stops at two.

A two-phase component is refused as well: as_svydesign() exports one with survey::twophase(), and multiframe() accepts only the objects survey::svydesign() builds.

The expected estimator

estimator = "expected" needs the chance a unit had in every frame, including the frames it was not selected from, which is what stack_frames()'s overlaps argument declares. The composited weight is then one over the sum of those chances, and it owes nothing to the design weight, which cancels.

samplyr hands survey the weight form of those chances, never the probabilities, whichever way they were declared. survey::multiframe() infers the scale from the values, reading a matrix as weights when no non-zero entry in some frame falls below one, and that is reachable whenever a frame is a census or its overlapping units are certainties. Values at or above one are unambiguous under the same rule, so there is nothing left to infer.

It is refused for a component whose weights were shared from another population: the combination is harmonic, and a realized weight-share weight is a random variable rather than an inverse inclusion probability.

References

Hartley, H. O. (1962). Multiple frame surveys. Proceedings of the Social Statistics Section, American Statistical Association, 203-206.

Lohr, S. L. (2021). Multiple-frame surveys for a multiple-data-source world. Survey Methodology, 47(2), 229-263.

Examples

population <- data.frame(
  person_id = 1:200,
  spend = stats::rnorm(200, 100, 10),
  in_landline = rep(c(TRUE, FALSE), times = c(140, 60)),
  in_cell = rep(c(FALSE, TRUE), times = c(60, 140))
)

frames <- stack_frames(
  landline = sampling_design() |>
    draw(n = 40) |>
    execute(population[population$in_landline, ], seed = 1),
  cell = sampling_design() |>
    draw(n = 50) |>
    execute(population[population$in_cell, ], seed = 2),
  membership = c(landline = "in_landline", cell = "in_cell"),
  key = person_id
)

# The multiplicity estimator: an overlap unit counts half in each frame.
svy <- as_svydesign(frames)
survey::svytotal(~spend, svy)
#>       total     SE
#> spend 20169 649.03

# Hartley's estimator with a stated factor on the landline frame.
survey::svytotal(~spend, as_svydesign(frames, theta = 0.74))
#>       total    SE
#> spend 20418 670.2