Skip to contents

est_pw() estimates pseudo-weights for a nonprobability sample using one reference survey or multiple reference surveys. The function specifies the participation model, handles missing values in the participation model variables, solves the estimating equations, and stores the quantities needed for downstream point and variance estimation.

Users should harmonize variable names and coding before calling est_pw(). Variables used in the participation model must have consistent names and compatible definitions across the nonprobability sample and the reference survey data used for estimation.

With one reference survey, the available methods include the raking ratio calibration method described in Landsman et al. (2026), the adjusted logistic propensity weighting (ALP) method proposed by Wang, Valliant, and Li (2021), and the CLW method proposed by Chen, Li, and Wu (2020). With multiple reference surveys, pseudo-weights are estimated using the multi-reference calibration method proposed by Landsman et al. (2026).

The returned object is designed to be passed to pwmean.

Usage

est_pw(
  data,
  sp_order = c("size", "given"),
  precali = TRUE,
  p_formula = NULL,
  method = NULL,
  na.action = stats::na.omit,
  sc_wname = "pseudo_wts",
  control = pw_solver_control(),
  verbose = FALSE
)

Arguments

data

A list of input data objects of the form list(sc, sp1_design, sp2_design, ...). The first element must be a data frame corresponding to the nonprobability sample. Each remaining element must be a valid survey design object corresponding to a reference probability survey, such as an object created by svydesign or svrepdesign.

sp_order

Character string controlling the order of reference surveys when multiple reference surveys are used. Supported values are "size" and "given". "size" orders reference surveys by sample size, from largest to smallest. "given" uses the user-specified order of the reference surveys in data. Default is "size". With one reference survey, this argument is ignored; a warning is issued if a non-default value is supplied.

precali

Logical. Used only with multiple reference surveys. If TRUE, cumulative precalibration is applied before the main multi-reference estimation step; see the Multi-reference precalibration section for details. Default is TRUE. With one reference survey, this argument is ignored; a warning is issued if FALSE is supplied.

p_formula

Optional participation model formula. Must always be one-sided (no response variable on the left-hand side). A two-sided formula such as y ~ x will raise an error.

With one reference survey, supply a single one-sided formula, for example ~ age + sex + income. With multiple reference surveys, supply a list of one-sided formulas with one formula per reference survey, for example list(~ age + sex, ~ age + income). If NULL, a default formula is constructed automatically from variables shared across the data sources used for estimation. Since shared variables are identified by name, their names should be harmonized across data sources before estimation.

method

Character string specifying the pseudo-weighting method, or NULL (default). If NULL, "calibration" is used when data contains one reference survey, and "multi" is used when data contains more than one reference survey.

To override the default, supply one of the following values. For a one-reference method: "alp", "clw", or "calibration" (or "cali"). For the multi-reference method: "multi".

The argument is case-insensitive, so inputs such as "ALP", "Clw", or "CALI" are also accepted.

na.action

Function specifying how missing values should be handled for variables used in the participation model. Common choices include stats::na.omit, stats::na.exclude, and stats::na.fail. Default is stats::na.omit.

sc_wname

Character string giving the name of the pseudo-weight column added to the returned nonprobability sample. Default is "pseudo_wts". An error is raised at input validation if this name already exists as a column in sc.

control

A solver control object created by pw_solver_control. This object stores numerical settings for solving estimating equations, including the solver, convergence tolerance, maximum number of iterations, tracing behavior, and other options.

verbose

Logical. If TRUE, progress messages and diagnostics are printed during pseudo-weight estimation. Default is FALSE. Must be a single TRUE or FALSE; an error is raised otherwise.

Value

An object of class "pw_fit". This is a list containing user-facing outputs and internal objects required by pwmean.

Important components include:

sc_updated

A data frame containing the nonprobability sample with an added pseudo-weight column named by sc_wname.

pseudo_weights

The estimated pseudo-weight vector. With stats::na.omit, the vector contains only observations retained for pseudo-weight estimation. With stats::na.exclude, excluded observations receive NA and the vector has length nrow(sc).

coefficients

Estimated coefficients for the participation model variables.

solver_diagnostics

A list of solver diagnostics: solver (solver name), termcd (termination code), message (solver message), iter (number of iterations), and fmax (maximum absolute value of the final estimating equations at convergence).

method

The pseudo-weighting method used by the function.

internal

A list of internal objects needed for downstream estimation.

na_summary

An object of class "pw_na_summary" summarizing the number of rows excluded from the nonprobability sample and each reference survey due to missing participation model variables. NULL if no rows were excluded.

call

The matched function call.

Details

est_pw() performs pseudo-weight estimation for the nonprobability sample and stores the method-specific internal objects needed later by pwmean. It does not require an outcome variable.

The input data must be provided as a list, where the first element is the nonprobability sample and the remaining elements are reference survey design objects. Reference survey designs can be created with svydesign for standard complex survey designs or svrepdesign for surveys with replicate weights. These objects preserve the sampling structure needed for design-consistent variance estimation.

Variable harmonization. Variables are matched by name, not by meaning. Before applying est_pw(), shared variables must be harmonized across the nonprobability sample and reference survey data. For example, if a categorical variable is named agecat in the nonprobability sample and age_group in the reference survey, the user should rename one of the variables before estimation.

Categorical variables should be encoded as factors with compatible category definitions and identical levels in the same order. Even when categories are substantively equivalent, mismatched factor levels may cause est_pw() to return an error. Continuous variables included in the participation model should also be measured on comparable scales across datasets.

Internally, est_pw() performs the following steps:

  1. Input validation
    Validates the structure and required components of the input data.

  2. Reference survey detection
    Determines whether the input contains a single reference survey or multiple reference surveys.

  3. Method selection
    Selects the pseudo-weighting method based on the specified argument(s).

  4. Participation model specification
    Constructs a default participation model formula when p_formula = NULL.

  5. Missing data handling
    Applies missing-data handling procedures to variables used in the participation model.

  6. Model matrix construction
    Generates model matrices from the participation model variables.

  7. Pseudo-weight estimation
    Estimates pseudo-weights using the selected method.

  8. Output augmentation
    Appends the estimated pseudo-weights as a new column to the nonprobability sample.

  9. Metadata storage
    Stores information related to missing-data handling and other internal objects for later use or diagnostics.

One-reference method and multi-reference method

If data contains one reference survey design object, est_pw() fits a one-reference method. If data contains more than one reference survey design objects, est_pw() fits the multi-reference calibration method. In both settings, the auxiliary variables used for pseudo-weight estimation should be harmonized across all data sources before calling est_pw().

Multi-reference precalibration

When precali = TRUE, cumulative precalibration is performed before the main multi-reference calibration step. For overlapping auxiliary variables, this procedure calibrates the survey weights of a reference survey so that its weighted totals of the overlapping variables and its sum of weights match the corresponding totals from the preceding reference survey in the cumulative order. If there are no overlapping auxiliary variables, cumulative precalibration is applied only to the sum of weights.

The order of the reference surveys is controlled by sp_order. If sp_order = "size", reference surveys are ordered by sample size, from largest to smallest. If sp_order = "given", the user-specified order of the reference surveys is used.

Cumulative precalibration is based only on overlapping variables that are specified in p_formula, rather than on all overlapping variables in the reference surveys. This choice avoids excluding observations because of missing values in variables that are not used for pseudo-weight estimation.

Missing data handling

Missing values are handled only for variables used in the participation model. The selected na.action is recorded in the returned object, together with the row indices of the nonprobability sample observations retained for pseudo-weight estimation.

With stats::na.omit, rows with missing participation model variables are removed from sc_updated. With stats::na.exclude, the original rows are retained in sc_updated, but excluded rows receive NA in the pseudo-weight column. This can be useful when users want to preserve row alignment with the original nonprobability sample for later imputation or merging.

Numerical control

Numerical settings are supplied through the control argument, which should be created by pw_solver_control. This object controls solver choice, convergence tolerance, maximum iterations, tracing, and optional solver-specific arguments.

The top-level ftol, xtol, and maxit values in pw_solver_control are the package-level convergence controls used by pseudo-weight estimation stages. When the selected solver is "nleqslv", additional arguments can be passed through nleqslv_control. These are forwarded to nleqslv::nleqslv().

References

Chen, Y., Li, P., and Wu, C. (2020). Doubly robust inference with nonprobability survey samples. Journal of the American Statistical Association, 115(532), 2011–2021. doi:10.1080/01621459.2019.1677241

Wang, L., Valliant, R., and Li, Y. (2021). Adjusted logistic propensity weighting methods for population inference using nonprobability volunteer-based epidemiologic cohorts. Statistics in Medicine, 40(24), 5237–5250. doi:10.1002/sim.9122

Landsman, V., Wang, L., Carrillo-Garcia, I., Mitani, A. A., Smith, P. M., Graubard, B. I., Bui, T., and Carnide, N. (2026). Correction for Participation Bias in Nonprobability Samples Using Multiple Reference Surveys. Statistics in Medicine, 45(3–5). doi:10.1002/sim.70403

Examples

# \donttest{
data(sc)
data(sp1)
data(sp2)

## One-reference example

ref1_design <- survey::svydesign(
  ids     = ~psu_sp1,
  strata  = ~strata_sp1,
  weights = ~wts_sp1,
  data    = sp1,
  nest    = TRUE
)

fit1 <- est_pw(
  data      = list(sc, ref1_design),
  p_formula = ~ agecat + race + education + comorbidity + BMI + diabetes,
  method    = "calibration",
  control   = pw_solver_control(ftol = 1e-6)
)

print(fit1)
#> Pseudo-weight fit ("pw_fit")
#> 
#> Call:
#> est_pw(data = list(sc, ref1_design), p_formula = ~agecat + race + 
#>     education + comorbidity + BMI + diabetes, method = "calibration", 
#>     control = pw_solver_control(ftol = 1e-06))
#> 
#> Method:               One reference calibration
#> Participation model:  16 parameters (incl. intercept)
#> Convergence:          converged  (nleqslv, 5 iter, max|EE| = 1.30e-08)
#> 
#> Pseudo-weights (n = 2404):
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>    4099    7244    8819    8651   10139   13958 
#> Sum: 20,797,012
#> 
#> Use summary() for coefficients and diagnostics; pwmean() to estimate means.

summary(fit1)
#> Call:
#> est_pw(data = list(sc, ref1_design), p_formula = ~agecat + race + 
#>     education + comorbidity + BMI + diabetes, method = "calibration", 
#>     control = pw_solver_control(ftol = 1e-06))
#> 
#> Method: One reference calibration 
#> 
#> Participation model involves the following variables:
#> agecat2 agecat3 agecat4 race2 race3 race4 education2 education3 education4 education5 comorbidity1 BMINormal BMIObese BMIOverweight diabetes1 
#> 
#> Solver diagnostics:
#>   Solver: nleqslv 
#>   Method: Newton 
#>   Termination code: 1 
#>   Iterations: 5 
#>   Max |estimating equation|: 1.304e-08 
#>   Message: Function criterion near zero 
#> 
#> Participation model coefficients:
#>  (Intercept)    agecat2    agecat3    agecat4      race2      race3      race4
#>      -9.1480    -0.0344    -0.1093    -0.2328     0.3702     0.6331     0.4028
#>  education2 education3 education4 education5 comorbidity1  BMINormal   BMIObese
#>     -0.1751    -0.1227    -0.0394     0.0951       0.0121     0.0484     0.0858
#>  BMIOverweight  diabetes1
#>         0.0345     0.0546

## Multi-reference example

ref2_design <- survey::svydesign(
  ids     = ~psu_sp2,
  strata  = ~strata_sp2,
  weights = ~wts_sp2,
  data    = sp2,
  nest    = TRUE
)

fit2 <- est_pw(
  data = list(sc, ref1_design, ref2_design),
  p_formula = list(
    ~ agecat + race + education + psa_level + pros_enlarged + comorbidity,
    ~ agecat + race + BMI + diabetes + comorbidity
  ),
  sp_order = "size",
  precali = TRUE,
  control = pw_solver_control(ftol = 1e-6)
)

print(fit2)
#> Pseudo-weight fit ("pw_fit")
#> 
#> Call:
#> est_pw(data = list(sc, ref1_design, ref2_design), sp_order = "size", 
#>     precali = TRUE, p_formula = list(~agecat + race + education + 
#>         psa_level + pros_enlarged + comorbidity, ~agecat + race + 
#>         BMI + diabetes + comorbidity), control = pw_solver_control(ftol = 1e-06))
#> 
#> Method:               Multi-reference calibration
#> Participation model:  18 parameters
#> Convergence:          converged  (nleqslv, 7 iter, max|EE| = 1.79e-07)
#> 
#> Pseudo-weights (n = 2404):
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>   33766   78120  101323  106180  133709 1092320 
#> Sum: 255,256,038
#> 
#> Use summary() for coefficients and diagnostics; pwmean() to estimate means.

summary(fit2)
#> Call:
#> est_pw(data = list(sc, ref1_design, ref2_design), sp_order = "size", 
#>     precali = TRUE, p_formula = list(~agecat + race + education + 
#>         psa_level + pros_enlarged + comorbidity, ~agecat + race + 
#>         BMI + diabetes + comorbidity), control = pw_solver_control(ftol = 1e-06))
#> 
#> Method: Multi-reference calibration
#> 
#> Precalibration summary:
#> Non-calibrated sample (largest): sp[[2]]
#> Calibrated sample: sp[[1]]
#>   Calibration variables: survey weights total, agecat2, agecat3, agecat4, comorbidity1, race2, race3, race4
#> 
#> Reference samples summary:
#> Order of samples by size (largest to smallest):
#>   sp[[2]] (n = 35525)
#>   sp[[1]] (n = 2304)
#> Shared variables in sp[[2]]:
#>   agecat2, agecat3, agecat4, race2, race3, race4, BMINormal, BMIObese, BMIOverweight, diabetes1, comorbidity1
#> Shared variables in sp[[1]]:
#>   agecat2, agecat3, agecat4, race2, race3, race4, education2, education3, education4, education5, psa_level, pros_enlarged1, comorbidity1
#> Variables used for calculation in sp[[2]]:
#>   agecat2, agecat3, agecat4, race2, race3, race4, BMINormal, BMIObese, BMIOverweight, diabetes1, comorbidity1
#> Variables used for calculation in sp[[1]]:
#>   education2, education3, education4, education5, psa_level, pros_enlarged1
#> 
#> Participation model involves the following variables:
#> agecat2 agecat3 agecat4 race2 race3 race4 BMINormal BMIObese BMIOverweight diabetes1 comorbidity1 education2 education3 education4 education5 psa_level pros_enlarged1 
#> 
#> Solver diagnostics:
#>   Solver: nleqslv 
#>   Method: Newton 
#>   Termination code: 1 
#>   Iterations: 7 
#>   Max |estimating equation|: 1.788e-07 
#>   Message: Function criterion near zero 
#> 
#> Participation model coefficients:
#>  (Intercept)    agecat2    agecat3    agecat4      race2      race3      race4
#>     -11.1333     0.0448     0.0463    -0.1072     0.4680     0.7084     0.6349
#>   BMINormal   BMIObese BMIOverweight  diabetes1 comorbidity1 education2
#>     -0.3871    -0.1555       -0.6156    -0.0652       0.0405    -0.0941
#>  education3 education4 education5  psa_level pros_enlarged1
#>     -0.1554    -0.0720    -0.0078    -0.0844         0.0988
#> 
#> (1190 observations deleted due to missingness in sp[[1]])
# }