The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
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[@]dogado.de.
ezrsurvey turns the things consumer-survey analysts do
over and over into single-line helpers. This vignette walks through a
typical analysis of the bundled podracing_survey dataset:
from raw answers to percentages, models, diagnostics and a chart you
could drop on a slide.
podracing_survey is 1,000 simulated respondents with
demographics, a 0–10 NPS question, worded feature ratings, multi-select
motivations, brand questions and open-text comments.
podracing_survey[, c("respondent_id", "demo_gender", "demo_age", "nps_value")]
#> # A tibble: 1,000 × 4
#> respondent_id demo_gender demo_age nps_value
#> <chr> <chr> <int> <int>
#> 1 R00001 Male 35 10
#> 2 R00002 Male 29 6
#> 3 R00003 Male 16 10
#> 4 R00004 Male 16 10
#> 5 R00005 Male 16 9
#> 6 R00006 Male 36 9
#> 7 R00007 Male 30 10
#> 8 R00008 Female 23 9
#> 9 R00009 Female 23 10
#> 10 R00010 Male 39 9
#> # ℹ 990 more rowscount/mutate/pivot_wider
dancecalc_percentage() is the workhorse: counts, percentages
and ordering in one call.
calc_percentage(podracing_survey, demo_gender, sort = "desc")
#> # A tibble: 3 × 3
#> demo_gender n pct
#> <fct> <int> <dbl>
#> 1 Male 525 55
#> 2 Female 399 42
#> 3 Non-binary 27 3Group with by, and pivot to a wide cross-tab with
wide = TRUE:
calc_percentage(podracing_survey, satis_return, by = region, wide = TRUE)
#> # A tibble: 5 × 6
#> region Likely `Not sure` Unlikely `Very likely` `Very unlikely`
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Asia 24 25 12 34 5
#> 2 Europe 28 25 16 25 6
#> 3 Latin America 30 21 11 28 10
#> 4 North America 26 24 17 24 8
#> 5 Oceania 31 12 24 24 10Check-all-that-apply questions live in a block of columns sharing a
prefix; calc_percentage_multi() handles the per-respondent
denominator for you:
calc_percentage_multi(podracing_survey, "motivations_",
id = respondent_id, sort = "desc")
#> # A tibble: 5 × 3
#> option n pct
#> <fct> <int> <dbl>
#> 1 speed 772 79
#> 2 drivers 533 54
#> 3 social 437 45
#> 4 tradition 349 36
#> 5 betting 295 30Spreadsheet exports, Google Forms among them, instead pack every answer a respondent ticked into a single cell. The same function recognises that shape and separates the answers, so you do not have to reshape anything first:
packed <- data.frame(
respondent = 1:4,
motivations = c("Speed; Drivers", "Speed", "", "Betting; Speed")
)
calc_percentage_multi(packed, "motivations", id = respondent, sort = "desc")
#> # A tibble: 3 × 3
#> option n pct
#> <fct> <int> <dbl>
#> 1 Speed 3 100
#> 2 Betting 1 33
#> 3 Drivers 1 33Note the denominator: three respondents ticked something, so “Speed”
is 3 of 3. When you need those answers as columns rather than as a
table, for a crosstab or a filter, split_multi() widens
them:
split_multi(packed, motivations)
#> # A tibble: 4 × 5
#> respondent motivations motivations_Speed motivations_Betting
#> <int> <chr> <chr> <chr>
#> 1 1 "Speed; Drivers" "Speed" ""
#> 2 2 "Speed" "Speed" ""
#> 3 3 "" "" ""
#> 4 4 "Betting; Speed" "Speed" "Betting"
#> # ℹ 1 more variable: motivations_Drivers <chr>Rather than retyping levels = c(...), register an order
once and link it to a variable; calc_percentage() then
applies it automatically.
register_order(
"education",
levels = c("Primary or less", "Lower secondary", "Upper secondary",
"Short-cycle tertiary", "Bachelor or equivalent",
"Master or equivalent", "Doctoral or equivalent"),
vars = "demo_edu"
)
calc_percentage(podracing_survey, demo_edu)
#> # A tibble: 7 × 3
#> demo_edu n pct
#> <ord> <int> <dbl>
#> 1 Primary or less 42 4
#> 2 Lower secondary 111 11
#> 3 Upper secondary 295 30
#> 4 Short-cycle tertiary 123 13
#> 5 Bachelor or equivalent 244 25
#> 6 Master or equivalent 122 13
#> 7 Doctoral or equivalent 35 4calc_nps(podracing_survey, nps_value)
#> # A tibble: 1 × 8
#> n nps pct_detractors pct_passives pct_promoters detractors passives
#> <int> <dbl> <dbl> <dbl> <dbl> <int> <int>
#> 1 1000 7 25 43 32 252 426
#> # ℹ 1 more variable: promoters <int>ipm_model() combines driver importance (by default,
relative weights against the NPS score) with feature performance;
plot_ipm() draws the matrix. Pass
method = "forest" for a random-forest cross-check, which
sees non-linear effects that relative weights cannot.
model <- ipm_model(podracing_survey, nps_value, "ratings_")
model
#> # A tibble: 6 × 4
#> feature importance performance perf_class
#> <chr> <dbl> <dbl> <fct>
#> 1 value 24.9 2.86 2
#> 2 atmosphere 23.8 3.57 3
#> 3 speed 18.0 3.48 3
#> 4 safety 14.1 2.88 2
#> 5 venue 12.2 3.08 3
#> 6 commentary 6.99 2.58 2For event surveys you often compare this wave with the last.
compare_values() computes the differences and
plot_diff() draws the change chart.
previous <- transform(model, performance = performance - c(.3, -.1, .2, 0, .1))
#> Warning in performance - c(0.3, -0.1, 0.2, 0, 0.1): longer object length is not
#> a multiple of shorter object length
compare_values(model, previous) %>%
plot_diff()diagnose() reports the standard error, relative standard
error and margin of error for any column – numeric (point) or
categorical (proportion).
diagnose(podracing_survey, demo_gender, nps_value)
#> # A tibble: 2 × 9
#> variable type unit n estimate se rse moe precision
#> <chr> <chr> <chr> <int> <dbl> <dbl> <dbl> <dbl> <chr>
#> 1 demo_gender prop ppt 951 55.2 1.61 2.92 3.16 high precision
#> 2 nps_value mean points 1000 7.56 0.06 0.74 0.11 high precisionFor a one-shot, plain-language read on the whole study,
precision_summary() picks the point-scale and proportion
variables for you and writes the bullet points you would otherwise
hand-craft for a report appendix:
precision_summary(podracing_survey)
#> Survey precision summary
#> - Based on 1,000 total responses (per-question base of 776 to 1,000).
#> - Point ratings carry a sampling margin of about +/-0.40 points (up to +/-0.69) at 95% confidence.
#> - Percentages carry a sampling margin of about +/-3.0 percentage points (worst case +/-3.1 at a 50/50 split).
#> - Overall relative standard error of about 4.2% -- high precision.A standard error on its own is hard to judge – is ±0.05
good? It depends on the scale. The relative standard
error (RSE) divides the standard error by the estimate, so
precision becomes comparable across a 1–5 rating and a percentage alike.
Rating estimates by their RSE is the approach national statistical
agencies use to decide whether a number is solid enough to publish. The
Australian
Bureau of Statistics, for example, treats an RSE of 25% or more as
not reliable for most purposes, marks estimates between 25% and 50% with
an asterisk as ones to use with caution, and suppresses anything above
50%. ezrsurvey keeps that 25% boundary and adds tighter bands below it,
because in consumer-survey work the question is usually which of several
adequately precise numbers to lead with:
| RSE | Rating |
|---|---|
| under 5% | high precision |
| under 10% | precise |
| under 15% | satisfactory |
| under 25% | use with caution |
| 25% or more | likely reliability issues |
For proportions, the margin of error is widest at a 50/50 split
(sqrt(0.5 * 0.5 / n)), so a single worst-case
± percentage-point figure at your achieved sample size
bounds every percentage in the study – which is why
precision_summary() reports it.
Every table and plot has a one-line, pipe-friendly save that writes
the file you name. A path with a folder in it
("tables/gender.xlsx") creates the folder;
ezrsurvey_options(output_dir = "outputs") collects bare
names in one folder.
calc_percentage(podracing_survey, demo_gender) %>% save_data("gender.xlsx")
plot_nps(podracing_survey, nps_value) %>% save_plot("nps.png")
# several tables, one tab each
export_xlsx(
gender = calc_percentage(podracing_survey, demo_gender),
job = calc_percentage(podracing_survey, demo_job),
path = "summary.xlsx"
)ezrsurvey_options() and a
profile (use_ezrsurvey_profile()).report_deck() or scaffold a Quarto
report with scaffold_report().ezrintelligence package.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.
Health stats visible at Monitor.