What's the range of values of scale()?

Viewed 176

I'm trying to figure out the range of values that any value of scale would be between?

I have a 47*2 data frame with values such as:

43109 43026 
43857 42904 
43753 43714

and I am running scale() on that function. I am trying to figure out a bound for what the range of values will be between. Is this fixed, or does it vary with input?

I am thinking that the values would be standardised between the nearest one, is this correct?

Sorry for the noob question. The documentation of scale() has got me confused.

3 Answers

By default, scale subtracts the mean and divides by the standard deviation of x. So there is no fixed minimum/maximum value. Chebyshev's inequality says that (as long as the distribution of the data has finite mean and finite non-zero variance) a proportion 1-1/k^2 of the values are expected to be within k standard deviations of the mean, so for the scaled data, 1-1/k^2 of the values would typically have absolute value less than k.

Since you have about 100 values, all but 1 (99%) are likely to have absolute value <10, provided the distribution's not really crazy. If your data were normally distributed, 99% of the data would have scaled value < 2.58 (qnorm((1+0.99)/2)).

With default parameters

If scale is TRUE then scaling is done by dividing the (centered) columns of x by their standard deviations if center is TRUE

So that means if Y is the vector of one column of your matrix, after scale() this column will be replaced by (Y - mean(Y))/sd(Y). You can verify this:

mat_scaled1 <- scale(mat)

colmeans <- colMeans(mat)
colsds <- matrixStats::colSds(mat)

mat_scaled2 <- matrix(NA_real_, nrow=20, ncol=20)
for(i in seq_len(ncol(mat))){
  mat_scaled2[,i] <- (mat[,i] - colmeans[i])/colsds[i]
}

all.equal(mat_scaled1, mat_scaled2,check.attributes = FALSE)
#> [1] TRUE

So the matrix can have values much higher than the standard deviation (you could call them "outliers" depending on the context). If you really want to know the full range of the values, you need to divide by the maximum.

mat_scaled_max <- scale(mat, center = FALSE, scale = matrixStats::colMaxs(mat))

max(mat_scaled_max)
#> [1] 1

You mean with the default settings? These would be:

scale(x, center = TRUE, scale = TRUE)

Here from the documentation the relevant information for the default settings, (important parts marked for you, irrelevant parts removed):

If center is TRUE then centering is done by subtracting the column means (omitting NAs) of x from their corresponding columns, and if center is FALSE, no centering is done.

The value of scale determines how column scaling is performed (after centering). If scale is TRUE then scaling is done by dividing the (centered) columns of x by their standard deviations.

You can have a better look at this this way

# read in example data for you
aaa <- c(43109,43026, 43857,42904,43753, 43714)

# Get the results for scale
scale(aaa)

As I said the default scale call means you call scale(x, center = T, scale = T).

From the description you know, what this does is first centering and then scaling on these centered data.

You can have an insight into these steps by calling:

scale(aaa, center = T, scale = F)

This would basically give you just the first step.

[,1]
[1,] -284.8333
[2,] -367.8333
[3,]  463.1667
[4,] -489.8333
[5,]  359.1667
[6,]  320.1667
attr(,"scaled:center")
[1] 43393.83    

These are the results for the first step (centering) for the data I choose (43109,43026, 43857,42904,43753, 43714). You can see, 43393.83 is the column mean. The rows are the respective values minus the column mean. E.g. for the first value 43109 - 43393.83 = -284.8333, and so on for the other rows.

Related