18
$\begingroup$

I understand the concept of scaling the data matrix to use in a linear regression model. For example, in R you could use:

scaled.data <- scale(data, scale=TRUE)

My only question is, for new observations for which I want to predict the output values, how are they correctly scaled? Would it be, scaled.new <- (new - mean(data)) / std(data)?

$\endgroup$
2
  • 1
    $\begingroup$ To get the values back just do y = y_esc * sd(y) + mean(y), but that would mess with the model properties i guess, so i'm also waiting a more technical answer too! $\endgroup$
    – Fernando
    Commented Mar 7, 2014 at 15:29
  • $\begingroup$ I don't want the values back, I want to know how new instances can be correctly scaled in the same way. I've edited my question based on your comment. $\endgroup$
    – SamuelNLP
    Commented Mar 7, 2014 at 15:31

2 Answers 2

17
$\begingroup$

The short answer to your question is, yes - that expression for scaled.new is correct (except you wanted sd instead of std).

It may be worth noting that scale has optional arguments which you could use:

scaled.new <- scale(new, center = mean(data), scale = sd(data))

Also, the object returned by scale (scaled.data) has attributes holding the numeric centering and scalings used (if any), which you could use:

scaled.new <- scale(new, attr(scaled.data, "scaled:center"), attr(scaled.data, "scaled:scale"))

The advantage of that appears when the original data has more than one column, so there are multiple means and/or standard deviations to consider.

$\endgroup$
3
  • 3
    $\begingroup$ I wish there was a slightly simpler way to do this, like scaled.new <- scale(new, use.attrs = scaled.data) $\endgroup$ Commented Mar 25, 2019 at 6:32
  • $\begingroup$ @wordsforthewise It wouldn't be hard to write a wrapper for scale.default to achieve that. I doubt that R-core would give it high priority. $\endgroup$
    – user20637
    Commented Mar 25, 2019 at 19:09
  • $\begingroup$ Yeah. If I can figure out how to contribute to R-core and find time to do it, I might do that. $\endgroup$ Commented Mar 26, 2019 at 0:33
4
$\begingroup$

There are now simpler ways to do this. For example, the preprocess function of the caret package

library(caret)
preproc <- preProcess(data, method = c("center", "scale")
scaled.new <- predict(preproc, newdata = new)

or scale_by in the standardize package

or using the receipes package

library(recipes); library(dplyr)
rec <- recipe(~ ., data) %>% step_normalize(all_numeric()) %>% prep()
scaled.new <- rec %>% bake(new)
$\endgroup$
3
  • $\begingroup$ Upvoted. You might want to correct case in "the preprocess function of the caret package" and spelling in "using the receipes package" $\endgroup$
    – user20637
    Commented Jan 19, 2021 at 20:43
  • $\begingroup$ Not sure if the function changed compared to nigelhenry's first comment, but it seems that "preProcess" will give you only the preprocessing values but won't change your data. Using his example, you should follow up with predict(preproc, data) and predict(preproc, new). Original example here: Caret $\endgroup$ Commented Aug 3, 2023 at 22:55
  • $\begingroup$ Yes, the OP only asked about new data, so I only provided code for that. $\endgroup$
    – nigelhenry
    Commented Aug 24, 2023 at 22:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.