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 bysvydesignorsvrepdesign.- 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 indata. 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 isTRUE. With one reference survey, this argument is ignored; a warning is issued ifFALSEis 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 ~ xwill 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 examplelist(~ age + sex, ~ age + income). IfNULL, 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). IfNULL,"calibration"is used whendatacontains one reference survey, and"multi"is used whendatacontains 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, andstats::na.fail. Default isstats::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 insc.- 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 isFALSE. Must be a singleTRUEorFALSE; 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_updatedA data frame containing the nonprobability sample with an added pseudo-weight column named by
sc_wname.pseudo_weightsThe estimated pseudo-weight vector. With
stats::na.omit, the vector contains only observations retained for pseudo-weight estimation. Withstats::na.exclude, excluded observations receiveNAand the vector has lengthnrow(sc).coefficientsEstimated coefficients for the participation model variables.
solver_diagnosticsA list of solver diagnostics:
solver(solver name),termcd(termination code),message(solver message),iter(number of iterations), andfmax(maximum absolute value of the final estimating equations at convergence).methodThe pseudo-weighting method used by the function.
internalA list of internal objects needed for downstream estimation.
na_summaryAn 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.NULLif no rows were excluded.callThe 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:
Input validation
Validates the structure and required components of the input data.Reference survey detection
Determines whether the input contains a single reference survey or multiple reference surveys.Method selection
Selects the pseudo-weighting method based on the specified argument(s).Participation model specification
Constructs a default participation model formula whenp_formula = NULL.Missing data handling
Applies missing-data handling procedures to variables used in the participation model.Model matrix construction
Generates model matrices from the participation model variables.Pseudo-weight estimation
Estimates pseudo-weights using the selected method.Output augmentation
Appends the estimated pseudo-weights as a new column to the nonprobability sample.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]])
# }