Centers and scales the columns of a numeric matrix. The conventional version uses mean and standard deviation, the robust one median and MAD (see Details).
Arguments
- x
a numeric matrix-like object
- center
logical scalar or numeric vector. If
TRUE, the column means (or medians, forrobust = TRUE) are subtracted; ifFALSE, no centering is performed. Alternatively, a numeric vector of lengthncol(x)supplies the values to subtract directly.- scale
logical scalar or numeric vector. If
TRUE, the columns are divided by their standard deviation (or MAD, forrobust = TRUE); ifFALSE, no scaling is performed. Alternatively, a numeric vector of lengthncol(x)supplies the divisors directly.- robust
logical; whether to standardize by median and MAD rather than by mean and standard deviation
- na.rm
logical; if
TRUE(default), missing values are omitted when the column centers and scales are computed. Ignored for whichever ofcenterandscaleis given as a numeric vector. Missing entries ofxitself always remain missing in the result.
Value
the centered and scaled matrix. The numeric centerings and
scalings used (if any) are returned as attributes
"scaled:center" and "scaled:scale".
Details
The R base function base::scale() centers each column by its
mean and divides by the root mean square of the centered column, which
for centered data is the standard deviation. Both are sensitive to
outliers: a single extreme value moves the mean and inflates the standard
deviation, so the remaining observations are compressed towards zero.
If robust is set to TRUE the column median takes the place
of the mean and the median absolute deviation
(stats::mad()) that of the standard deviation. Both have a
breakdown point of 50 percent, so the standardization reflects the bulk
of the data rather than its extremes, and genuine outliers keep large
scores instead of being pulled in.
Whichever is chosen, center and scale accept either a
logical flag or a numeric vector of values to use directly, in which case
that vector must have one entry per column of x, as in
base::scale().
The two versions differ in one further respect. The MAD is invariant to
location shifts, so for robust = TRUE the returned
"scaled:scale" is the same whether or not the columns were
centered first, and does not depend on center. The root mean
square is not invariant; for robust = FALSE it is computed after
centering, matching base::scale(), which is what makes it
equal the standard deviation when center is TRUE and not
otherwise.
A zero or non-finite scaling factor can produce undefined or non-finite
results. scaleX emits a warning naming the affected columns rather
than failing, since the result may still be usable when those columns are
subsequently dropped.
See also
base::scale(), base::sweep(),
stats::mad(), rangeX(), bedrock::linScale()
Other transform:
boxCox(),
boxCoxLambda(),
logSt(),
yeoJohnson()
Examples
x <- bedrock::Pizza$temperature
# robust standardization is far less affected by the extreme values
plot(scaleX(x, robust = TRUE), col = "black", pch = 16, cex = 0.4,
ylab = "standardized temperature")
points(scaleX(x), col = "red", pch = 16, cex = 0.4)
legend("topright", legend = c("robust (median/MAD)", "conventional"),
col = c("black", "red"), pch = 16, bty = "n")
# the centerings and scalings used are recoverable
z <- scaleX(cbind(a = c(1, 2, 3, 4, 100), b = c(10, 20, 30, 40, 50)))
attr(z, "scaled:center")
#> a b
#> 22 30
attr(z, "scaled:scale")
#> a b
#> 43.61766 15.81139
# compared to the robust version, which the extreme value barely moves
attr(scaleX(cbind(a = c(1, 2, 3, 4, 100)), robust = TRUE), "scaled:scale")
#> a
#> 1.4826
# supplying the values directly, as base::scale allows
scaleX(matrix(1:6, ncol = 2), center = c(0, 0), scale = c(1, 2))
#> [,1] [,2]
#> [1,] 1 2.0
#> [2,] 2 2.5
#> [3,] 3 3.0
#> attr(,"scaled:center")
#> [1] 0 0
#> attr(,"scaled:scale")
#> [1] 1 2
