The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Basic Workflow with svySE

Luis Burgos

2026-07-13

Introduction

svySE provides a structured workflow for producing indicator tables from complex survey data.

The package separates two complementary tasks:

  1. svySE_calc() calculates weighted estimates and sampling errors using sampling weights and, when available, strata and cluster variables.
  2. svySE_simple() calculates unweighted frequencies and percentages from the observed sample without using the survey design.

Results generated by either function can be exported to .xlsx files with svySE_xlsx(). The export function can process one result or consolidate several analyses generated from different datasets, indicators, weights, or function calls.

The package is built on top of survey for design-based estimation and uses openxlsx for workbook generation.

Package workflow

Step Function Purpose
1 svySE_cfg() Configure estimation options
2A svySE_calc() Calculate weighted estimates and sampling errors
2B svySE_simple() Calculate unweighted frequencies and percentages
3 svySE_xlsx() Export one or multiple results to .xlsx files

The two calculation functions are intentionally separated. This avoids performing unnecessary calculations when only sampling errors or only descriptive tables are required.

Example data

The following simulated dataset contains:

library(svySE)

set.seed(123)

df <- data.frame(
  dept = rep(c("A", "B", "C"), each = 50),
  strata = rep(c("S1", "S2", "S3"), each = 50),
  cluster = rep(seq_len(30), each = 5),
  service = rep(c("S1", "S2"), length.out = 150),
  weight = runif(150, 10, 50),
  ind_1 = sample(c(0, 1), 150, replace = TRUE),
  ind_2 = sample(c(0, 1), 150, replace = TRUE),
  stringsAsFactors = FALSE
)

head(df)
#>   dept strata cluster service   weight ind_1 ind_2
#> 1    A     S1       1      S1 21.50310     0     1
#> 2    A     S1       1      S2 41.53221     1     1
#> 3    A     S1       1      S1 26.35908     0     0
#> 4    A     S1       1      S2 45.32070     1     1
#> 5    A     S1       1      S1 47.61869     0     0
#> 6    A     S1       2      S2 11.82226     0     0

Configure sampling error estimation

svySE_cfg() defines the settings used by svySE_calc().

cfg <- svySE_cfg(
  estimator = "prop",
  variance = "taylor",
  lonely_psu = "adjust",
  conf_level = 0.95,
  target = 1,
  valid_values = c(0, 1),
  truncate_lower_ci = TRUE,
  pct_mult = 100,
  deff = TRUE,
  cv = TRUE,
  na_rm = TRUE
)

cfg
#> svySE configuration
#> --------------------------------------------------
#> Estimator          : prop 
#> Variance           : taylor 
#> Lonely PSU         : adjust 
#> Confidence level   : 0.95 
#> Target value       : 1 
#> Valid values       : 0, 1 
#> Truncate lower CI  : TRUE 
#> Percentage mult.   : 100 
#> Include DEFF       : TRUE 
#> Include CV         : TRUE 
#> Remove NA          : TRUE

The principal options are:

Argument Purpose
estimator Selects the estimator used in the analysis
variance Defines the variance estimation method
lonely_psu Specifies how strata containing one PSU are handled
conf_level Defines the confidence level
target Identifies the indicator category of interest
valid_values Defines the valid indicator values
truncate_lower_ci Truncates negative lower confidence limits at zero
pct_mult Converts proportions to the selected percentage scale
deff Enables or disables design-effect calculation
cv Enables or disables coefficient-of-variation calculation
na_rm Controls the treatment of missing values

Calculate sampling errors

svySE_calc() calculates weighted estimates and measures of sampling precision.

res_error <- svySE_calc(
  data = df,
  indicators = c("ind_1", "ind_2"),
  group_vars = "dept",
  group_labels = "Department",
  strata = "strata",
  cluster = "cluster",
  weight = "weight",
  division = NULL,
  div_weight = NULL,
  cfg = cfg,
  verbose = FALSE
)

res_error
#> svySE sampling error result
#> --------------------------------------------------
#> Indicators : ind_1, ind_2 
#> Groups     : dept 
#> Strata     : strata 
#> Cluster    : cluster 
#> Weight     : weight 
#> Division   : NULL 
#> Estimator  : prop 
#> Target     : 1 
#> Strict     : FALSE 
#> Simple tab : No (use svySE_simple())

The returned object has class "svySE_result".

class(res_error)
#> [1] "svySE_result" "list"

Results are organized by indicator and division.

names(res_error$results)
#> [1] "ind_1" "ind_2"
names(res_error$results$ind_1$error)
#> [1] "TOTAL"

The national and grouped results for the first indicator can be inspected with:

res_error$results$ind_1$error$TOTAL
#>       dept   est_abs  est_pct   se_abs   se_pct  ci_l_abs ci_l_pct  ci_u_abs
#> 1 NACIONAL 2274.6821 50.26904 227.0537 4.182067 1829.6650 42.07234 2719.6992
#> 2        A  760.7571 49.39397 134.7782 7.768911  496.5967 34.16719 1024.9174
#> 3        B  933.1969 64.17897 109.2721 5.617541  719.0274 53.16879 1147.3664
#> 4        C  580.7282 37.93676 146.4508 8.122624  293.6899 22.01671  867.7664
#>   ci_u_pct        cv      deff n_unw
#> 1 58.46574  8.319368 1.0781551    72
#> 2 64.62076 15.728459 1.2665513    23
#> 3 75.18915  8.752931 0.6797495    30
#> 4 53.85680 21.410960 1.4608894    19

The sampling error table contains:

Column Description
est_abs Weighted absolute estimate
est_pct Weighted percentage estimate
se_abs Standard error of the absolute estimate
se_pct Standard error of the percentage
ci_l_abs Lower confidence limit for the absolute estimate
ci_l_pct Lower confidence limit for the percentage
ci_u_abs Upper confidence limit for the absolute estimate
ci_u_pct Upper confidence limit for the percentage
cv Coefficient of variation
deff Design effect
n_unw Unweighted number of target cases

Supported survey designs

svySE_calc() can be used with different combinations of design variables.

Design strata cluster
Weight only NULL NULL
Stratified Variable name NULL
Clustered NULL Variable name
Stratified and clustered Variable name Variable name

Weight-only design

res_weight <- svySE_calc(
  data = df,
  indicators = "ind_1",
  group_vars = "dept",
  group_labels = "Department",
  strata = NULL,
  cluster = NULL,
  weight = "weight",
  cfg = cfg,
  verbose = FALSE
)

res_weight
#> svySE sampling error result
#> --------------------------------------------------
#> Indicators : ind_1 
#> Groups     : dept 
#> Strata     : NULL 
#> Cluster    : NULL 
#> Weight     : weight 
#> Division   : NULL 
#> Estimator  : prop 
#> Target     : 1 
#> Strict     : FALSE 
#> Simple tab : No (use svySE_simple())

Stratified design

res_strata <- svySE_calc(
  data = df,
  indicators = "ind_1",
  group_vars = "dept",
  group_labels = "Department",
  strata = "strata",
  cluster = NULL,
  weight = "weight",
  cfg = cfg,
  verbose = FALSE
)

res_strata
#> svySE sampling error result
#> --------------------------------------------------
#> Indicators : ind_1 
#> Groups     : dept 
#> Strata     : strata 
#> Cluster    : NULL 
#> Weight     : weight 
#> Division   : NULL 
#> Estimator  : prop 
#> Target     : 1 
#> Strict     : FALSE 
#> Simple tab : No (use svySE_simple())

Clustered design

res_cluster <- svySE_calc(
  data = df,
  indicators = "ind_1",
  group_vars = "dept",
  group_labels = "Department",
  strata = NULL,
  cluster = "cluster",
  weight = "weight",
  cfg = cfg,
  verbose = FALSE
)

res_cluster
#> svySE sampling error result
#> --------------------------------------------------
#> Indicators : ind_1 
#> Groups     : dept 
#> Strata     : NULL 
#> Cluster    : cluster 
#> Weight     : weight 
#> Division   : NULL 
#> Estimator  : prop 
#> Target     : 1 
#> Strict     : FALSE 
#> Simple tab : No (use svySE_simple())

Stratified and clustered design

res_complex <- svySE_calc(
  data = df,
  indicators = "ind_1",
  group_vars = "dept",
  group_labels = "Department",
  strata = "strata",
  cluster = "cluster",
  weight = "weight",
  cfg = cfg,
  verbose = FALSE
)

res_complex
#> svySE sampling error result
#> --------------------------------------------------
#> Indicators : ind_1 
#> Groups     : dept 
#> Strata     : strata 
#> Cluster    : cluster 
#> Weight     : weight 
#> Division   : NULL 
#> Estimator  : prop 
#> Target     : 1 
#> Strict     : FALSE 
#> Simple tab : No (use svySE_simple())

Domain estimation

The division argument generates separate results for each observed category of a division variable.

res_domain <- svySE_calc(
  data = df,
  indicators = "ind_1",
  group_vars = "dept",
  group_labels = "Department",
  strata = "strata",
  cluster = "cluster",
  weight = "weight",
  division = "service",
  div_weight = NULL,
  cfg = cfg,
  verbose = FALSE
)

names(res_domain$results$ind_1$error)
#> [1] "TOTAL" "S1"    "S2"

The TOTAL element contains the complete estimate, while the remaining elements contain the corresponding division results.

res_domain$results$ind_1$error$S1
#>       dept   est_abs  est_pct    se_abs    se_pct ci_l_abs ci_l_pct  ci_u_abs
#> 1 NACIONAL 1135.5816 50.12187 158.81289  5.725684 824.3141 38.89974 1446.8492
#> 2        A  283.6570 38.83620  81.08334  9.105621 124.7366 20.98951  442.5775
#> 3        B  568.1100 72.84501 100.44052  9.339124 371.2502 54.54066  764.9698
#> 4        C  283.8146 37.57349  92.51339 10.743894 102.4917 16.51584  465.1376
#>   ci_u_pct       cv      deff n_unw
#> 1 61.34401 11.42352 1.0036189    35
#> 2 56.68288 23.44622 0.8612027     9
#> 3 91.14935 12.82054 1.1615982    17
#> 4 58.63113 28.59435 1.2557022     9

When a division requires a different expansion factor, it can be provided through div_weight.

Calculate simple indicator tables

svySE_simple() calculates unweighted frequencies and percentages without requiring sampling weights, strata, or clusters.

res_simple <- svySE_simple(
  data = df,
  indicators = c("ind_1", "ind_2"),
  group_vars = "dept",
  group_labels = "Department",
  division = NULL,
  target = 1,
  valid_values = c(0, 1),
  pct_mult = 100,
  verbose = FALSE
)

res_simple
#> svySE simple result
#> --------------------------------------------------
#> Indicators : ind_1, ind_2 
#> Groups     : dept 
#> Division   : NULL 
#> Target     : 1 
#> Weighted   : No
#> Warning    : Results describe the observed sample only.

The returned object has class "svySE_simple_result".

class(res_simple)
#> [1] "svySE_simple_result" "list"

A simple table can be inspected with:

res_simple$results$ind_1$simple$TOTAL
#>       dept freq_0 pct_0 freq_1 pct_1 freq_total pct_total
#> 1 NACIONAL     78    52     72    48        150       100
#> 2        A     27    54     23    46         50       100
#> 3        B     20    40     30    60         50       100
#> 4        C     31    62     19    38         50       100

The table contains:

Column Description
freq_0 Frequency of non-target cases
pct_0 Percentage of non-target cases
freq_1 Frequency of target cases
pct_1 Percentage of target cases
freq_total Total number of valid observations
pct_total Total percentage

The results generated by svySE_simple() describe the observed sample only. Because no sampling weights or design variables are used, these percentages should not be interpreted as population estimates.

Simple tables by division

A division variable can also be used with svySE_simple().

res_simple_domain <- svySE_simple(
  data = df,
  indicators = "ind_1",
  group_vars = "dept",
  group_labels = "Department",
  division = "service",
  target = 1,
  valid_values = c(0, 1),
  pct_mult = 100,
  verbose = FALSE
)

names(res_simple_domain$results$ind_1$simple)
#> [1] "TOTAL" "S1"    "S2"

Export sampling errors to XLSX

The following example writes a sampling error workbook to a temporary file.

file_err <- tempfile(fileext = ".xlsx")

export_error <- svySE_xlsx(
  x = res_error,
  file_err = file_err,
  file_tab = NULL,
  cols_err = svySE_cols_err("full"),
  overwrite = TRUE
)

file.exists(file_err)
#> [1] TRUE

Export simple tables to XLSX

file_tab <- tempfile(fileext = ".xlsx")

export_simple <- svySE_xlsx(
  x = res_simple,
  file_err = NULL,
  file_tab = file_tab,
  cols_tab = svySE_cols_tab("full"),
  overwrite = TRUE
)

file.exists(file_tab)
#> [1] TRUE

Export multiple analyses

svySE_xlsx() can receive a named list containing several result objects.

results <- list(
  Main_errors = res_error,
  Domain_errors = res_domain,
  Main_simple = res_simple,
  Domain_simple = res_simple_domain
)

The function automatically identifies the class of each object:

multiple_err <- tempfile(fileext = ".xlsx")
multiple_tab <- tempfile(fileext = ".xlsx")

export_multiple <- svySE_xlsx(
  x = results,
  file_err = multiple_err,
  file_tab = multiple_tab,
  cols_err = svySE_cols_err("full"),
  cols_tab = svySE_cols_tab("full"),
  overwrite = TRUE
)

file.exists(multiple_err)
#> [1] TRUE
file.exists(multiple_tab)
#> [1] TRUE

This is useful when several indicators are calculated from different datasets, survey weights, domains, or analytical processes.

Export selected results

The select argument restricts the export to chosen elements of a named list.

Select sampling error results

selected_err <- tempfile(fileext = ".xlsx")

svySE_xlsx(
  x = results,
  select = c("Main_errors", "Domain_errors"),
  file_err = selected_err,
  file_tab = NULL,
  overwrite = TRUE
)

file.exists(selected_err)
#> [1] TRUE

Select simple results

selected_tab <- tempfile(fileext = ".xlsx")

svySE_xlsx(
  x = results,
  select = c("Main_simple", "Domain_simple"),
  file_err = NULL,
  file_tab = selected_tab,
  overwrite = TRUE
)

file.exists(selected_tab)
#> [1] TRUE

Customize exported columns

Sampling error columns

The complete set of sampling error columns can be requested with:

svySE_cols_err("full")
#>  [1] "est_abs"  "est_pct"  "se_abs"   "se_pct"   "ci_l_abs" "ci_l_pct"
#>  [7] "ci_u_abs" "ci_u_pct" "cv"       "deff"     "n_unw"

A custom selection can be defined with:

error_columns <- svySE_cols_err(
  type = "custom",
  cols = c(
    "est_pct",
    "se_pct",
    "ci_l_pct",
    "ci_u_pct",
    "cv",
    "deff",
    "n_unw"
  )
)

error_columns
#> [1] "est_pct"  "se_pct"   "ci_l_pct" "ci_u_pct" "cv"       "deff"     "n_unw"

Use the custom selection during export:

custom_err <- tempfile(fileext = ".xlsx")

svySE_xlsx(
  x = res_error,
  file_err = custom_err,
  file_tab = NULL,
  cols_err = error_columns,
  overwrite = TRUE
)

file.exists(custom_err)
#> [1] TRUE

Simple table columns

svySE_cols_tab("full")
#> [1] "freq_0"     "pct_0"      "freq_1"     "pct_1"      "freq_total"
#> [6] "pct_total"

A custom selection can be defined with:

simple_columns <- svySE_cols_tab(
  type = "custom",
  cols = c(
    "freq_1",
    "pct_1",
    "freq_total"
  )
)

simple_columns
#> [1] "freq_1"     "pct_1"      "freq_total"

Use the custom selection during export:

custom_tab <- tempfile(fileext = ".xlsx")

svySE_xlsx(
  x = res_simple,
  file_err = NULL,
  file_tab = custom_tab,
  cols_tab = simple_columns,
  overwrite = TRUE
)

file.exists(custom_tab)
#> [1] TRUE

Main functions

Function Description
svySE_cfg() Configure sampling error estimation
svySE_calc() Calculate weighted estimates and sampling errors
svySE_simple() Calculate unweighted frequencies and percentages
svySE_xlsx() Export one or multiple results to .xlsx files
svySE_cols_err() Select sampling error columns
svySE_cols_tab() Select simple table columns

Technical foundation

svySE uses established R packages for its internal workflow.

Package Role
survey Design-based estimation and variance calculation
openxlsx Creation and formatting of .xlsx workbooks
stats Statistical formulas, coefficients, and confidence intervals
svySE High-level workflow for indicators, sampling errors, tables, and export

svySE does not replace survey. It provides a structured interface for repeated indicator production, quality measurement, and export.

Summary

This vignette demonstrated how to:

  1. configure sampling error estimation with svySE_cfg();
  2. calculate weighted estimates and sampling errors with svySE_calc();
  3. work with weight-only, stratified, clustered, and combined designs;
  4. calculate domain estimates;
  5. generate unweighted descriptive tables with svySE_simple();
  6. export sampling errors and simple tables separately;
  7. consolidate several analyses in one export process;
  8. select specific results before exporting;
  9. customize the columns included in .xlsx files.

The same workflow can be applied to official survey datasets by specifying the corresponding indicators, grouping variables, weights, strata, and clusters.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.