简体   繁体   中英

scale() R function equivalent in Octave/Matlab

Avoiding loops, is there a way to center a matrix of data around the mean of the columns (or rows), scaling each entry by the standard deviation (also column-wise or row-wise)?

In R this is easy: scale(data, center = T, scale = T)) .

But I don't know how to achieve the same basic pre-processing in Ocatave or Matlab.

In Octave, you have two functions for this center() and zscore(). center just subtracts the mean, whereas zscore also divides by sd (an operation sometimes known as known as standarization)

center (x)

Center data by subtracting its mean.

If x is a vector, subtract its mean. If x is a matrix, do the above for each column. If the optional argument dim is given, operate along this dimension.

and

zscore (x, opt, dim) Computes the Z score of x

if x is a vector, subtract its mean and divide by its standard deviation. If the standard deviation is zero, divide by 1 instead.

The optional parameter opt determines the normalization to use when computing the standard deviation and has the same definition as the corresponding parameter for std.

If x is a matrix, calculate along the first non-singleton dimension. If the third optional argument dim is given, operate along this dimension.

There isn't a single function that does this but you can use the dim parameter for std and mean to accomplish this. We can also use bsxfun to wrap it all into one line.

A = rand(5, 4);

% Column-wise
bsxfun(@rdivide, bsxfun(@minus, A, mean(A, 1)), std(A, [], 1))

% Row-wise  
bsxfun(@rdivide, bsxfun(@minus, A, mean(A, 2)), std(A, [], 2))

Explanation

Using the dim parameter to mean we can compute the mean value for each column of A .

M = mean(A, 1)

Then we can use bsxfun to subtract the mean from each value in each column ( @minus ). We need to use bsxfun because M is 1 x nCols and A is nRows x nCols . bsxfun will automatically broadcast the operation for us.

B = bsxfun(@minus, A, M);

Then we want to compute the standard deviation of each column, again using the dim parameter (third input).

S = std(A, [], 1)

And divide each column by this standard deviation

bsxfun(@rdivide, B, S);

So bringing this all together we get

bsxfun(@rdivide, bsxfun(@minus, A, mean(A, 1)), std(A, [], 1))

To perform the row-wise operation, all we need to do is switch the dim parameter from 1 (columns) to 2 (rows).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM