Summarise and test numeric variables, in the style of SAS PROC UNIVARIATE
Source:R/proc_univariate.R
proc_univariate.RdProduces the statistics data set SAS PROC UNIVARIATE writes with
OUTPUT OUT=: one row per analysis variable (per class level), one
column per requested statistic in the order requested, then one column per
PCTLPTS= percentile. Beyond proc_means it adds weighted
and decimal percentiles, VARDEF=, and the tests for location and
normality.
Arguments
- data
A data frame, tibble, or similar tabular object.
- vars
Character vector of columns to analyse.
NULL(default) selects every numeric column not named inclassorweights.- class
Character vector of grouping columns, prepended to the result as leading columns. Rows with a missing value in any class variable are dropped, and levels follow
ORDER=INTERNAL, as inproc_means. Unlikeproc_means(), a level whose every weight is missing has no row, as in SAS.- stats
Character vector of SAS statistic keywords: every keyword
proc_meansaccepts, plus"stdmean","t","probt","msign","probm","signrank","probs","normal"and"probn".- weights
Character or
NULL. Name of a single numeric column ofdatato use as an observation weight, SASWEIGHT. Observations whose weight is missing are excluded from every statistic exceptnobs, which counts them.- pctlpts
Numeric vector of percentile points in
[0, 100], decimals allowed, orNULL. SASPCTLPTS=.- pctlpre
Single string prefixed to the
pctlptscolumn names. SASPCTLPRE=. The point follows with.replaced by_, so2.5givesp2_5.- mu0
Single finite number, the null value for
t,msignandsignrank. SASMU0=.- vardef
The variance divisor:
"df"(default),"n","wdf"or"weight". SASVARDEF=.
Value
A data frame with one row per analysis variable per class
combination. Columns are the class variables (when supplied), then
variable, label, then one column per stats keyword in
the order given, then one column per pctlpts point in the order
given. n, nmiss and nobs are integer; all others are
numeric.
Details
Weighting. Weights apply as in proc_means, except
that the quantiles are weighted: median, q1, q3,
qrange, pNN and the pctlpts columns. The weighted
percentile sorts the values with their cumulative weights \(S_i\); the
0th percentile is the minimum and the 100th the maximum; otherwise, when
\(S_i = pW\) the result is the mean of \(x_i\) and \(x_{i+1}\),
else the first \(x_i\) with \(S_i > pW\). Unweighted quantiles use
stats::quantile(type = 2), SAS's default PCTLDEF=5.
mode stays unweighted, as in SAS. stderr and stdmean
divide the standard deviation by the square root of the sum of the weights.
A zero or negative weight is an error; SAS instead treats a negative weight
as zero and still counts the observation.
VARDEF. The variance divisor is \(n - 1\) ("df"),
\(n\) ("n"), \(W - 1\) ("wdf") or \(W\)
("weight"), where \(W\) is the sum of the weights (\(n\)
without weights). It changes var, std and cv. Under
"n", skewness and kurtosis are the moment forms rather
than the adjusted ones.
Statistics SAS does not compute are NA, as SAS writes missing:
msign,probm,signrank,probs,normal,probnwhenweightsis given;t,probt,stderrandstdmeanwhenvardefis not"df";skewnessandkurtosiswhenvardefis"wdf"or"weight";normalandprobnabove 2000 observations, with one warning per call: SAS switches to a Kolmogorov D test there, which is not ported;std,var,cv,stderr,stdmean,t,probtat one observation,skewnessbelow three andkurtosisbelow four;t,probt,skewness,kurtosis,normal,probnwhen every value is equal (cvis then0unless the mean is zero, where it isNA);msign,probm,signrank,probswhen no value differs frommu0;modewhen no value repeats among two or more values.
Tests. t is Student's t for the mean against mu0;
msign the sign statistic; signrank the Wilcoxon signed rank
statistic, with an exact p-value for 20 or fewer non-zero differences and
SAS's t approximation above that. normal is the Shapiro-Wilk
\(W\), from stats::shapiro.test(), which implements Royston's 1995
algorithm; SAS implements Royston's 1992 one, so normal and
probn agree with SAS to about \(10^{-8}\), not to machine
precision. At two observations both are 1, as SAS reports.
See also
proc_means for the descriptive statistics alone.
Examples
dta <- generate_survival_data(n = 200, seed = 42)
# SAS unistats default statistics over every numeric variable
head(proc_univariate(dta))
#> variable label n median
#> 1 origin_year Calendar year for iv_opyrs = 0 200 2008.00
#> 2 iv_opyrs Observation interval (years) since origin_year 200 7.87
#> 3 iv_dead Follow-up time to death (years) 200 4.10
#> 4 dead Death indicator (1=dead, 0=censored) 200 1.00
#> 5 reop Reoperation (1=yes, 0=no) 200 0.00
#> 6 iv_reop Follow-up time to reoperation (years) 33 1.29
#> mean std cv min max
#> 1 2008.110000 5.8299090 0.2903182 1998.00 2018.00
#> 2 7.947450 4.0759650 51.2864500 1.06 14.99
#> 3 4.887950 3.1987862 65.4422866 0.25 13.98
#> 4 0.540000 0.4996481 92.5274291 0.00 1.00
#> 5 0.165000 0.3721120 225.5224211 0.00 1.00
#> 6 1.732727 1.9354171 111.6977318 0.04 9.92
# Decimal percentiles, as for a bootstrap interval
proc_univariate(dta, vars = "age", stats = "n",
pctlpts = c(2.5, 50, 97.5))
#> variable label n p2_5 p50 p97_5
#> 1 age Age at surgery (years) 200 16.45 44.75 72.45
# Tests for location and normality
proc_univariate(dta, vars = "bmi",
stats = c("mean", "t", "probt", "normal", "probn"),
mu0 = 25)
#> variable label mean t probt normal
#> 1 bmi Body mass index (kg/m2) 26.7885 5.324349 2.722644e-07 0.9954021
#> probn
#> 1 0.8071198